Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkToFImageRecorder.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 #include "mitkToFImageRecorder.h"
17 #include <mitkRealTimeClock.h>
18 #include <itkMultiThreader.h>
19 #include <itksys/SystemTools.hxx>
20 #pragma GCC visibility push(default)
21 #include <itkEventObject.h>
22 #pragma GCC visibility pop
23 
24 namespace mitk
25 {
27 {
28  this->m_ToFCameraDevice = NULL;
31  this->m_ThreadID = 0;
32  this->m_NumOfFrames = 1; //lets record one frame per default
33  this->m_ToFImageWriter = NULL;
34  this->m_DistanceImageSelected = true; //lets assume a device only has depth data by default
35  this->m_AmplitudeImageSelected = false;
36  this->m_IntensityImageSelected = false;
37  this->m_RGBImageSelected = false;
38  this->m_Abort = false;
39  this->m_ToFCaptureWidth = 0;
40  this->m_ToFCaptureHeight = 0;
41  this->m_RGBCaptureWidth = 0;
42  this->m_RGBCaptureHeight = 0;
43  this->m_FileFormat = ".nrrd"; //lets make nrrd the default
44  this->m_ToFPixelNumber = 0;
45  this->m_RGBPixelNumber = 0;
46  this->m_SourceDataSize = 0;
49  this->m_DistanceImageFileName = "";
50  this->m_AmplitudeImageFileName = "";
51  this->m_IntensityImageFileName = "";
52  this->m_RGBImageFileName = "";
53  this->m_ImageSequence = 0;
54  this->m_DistanceArray = NULL;
55  this->m_AmplitudeArray = NULL;
56  this->m_IntensityArray = NULL;
57  this->m_RGBArray = NULL;
58  this->m_SourceDataArray = NULL;
59 }
60 
62 {
63  delete[] m_DistanceArray;
64  delete[] m_AmplitudeArray;
65  delete[] m_IntensityArray;
66  delete[] m_RGBArray;
67  delete[] m_SourceDataArray;
68 }
69 
71 {
72 
73  this->m_AbortMutex->Lock();
74  this->m_Abort = true;
75  this->m_AbortMutex->Unlock();
76 
77 }
78 
80 {
81  if (this->m_ToFCameraDevice.IsNull())
82  {
83  throw std::invalid_argument("ToFCameraDevice is NULL.");
84  return;
85  }
86  if (this->m_FileFormat.compare(".csv") == 0)
87  {
89  }
90  else if(this->m_FileFormat.compare(".nrrd") == 0)
91  {
93  this->m_ToFImageWriter->SetExtension(m_FileFormat);
94  }
95  else
96  {
97  throw std::logic_error("No file format specified!");
98  }
99 
100  this->m_RGBCaptureWidth = this->m_ToFCameraDevice->GetRGBCaptureWidth();
101  this->m_RGBCaptureHeight = this->m_ToFCameraDevice->GetRGBCaptureHeight();
103 
104  this->m_ToFCaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth();
105  this->m_ToFCaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight();
107 
108  this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize();
109 
110  // allocate buffer
111  if(m_IntensityArray == NULL)
112  {
113  this->m_IntensityArray = new float[m_ToFPixelNumber];
114  }
115  if(this->m_DistanceArray == NULL)
116  {
117  this->m_DistanceArray = new float[m_ToFPixelNumber];
118  }
119  if(this->m_AmplitudeArray == NULL)
120  {
121  this->m_AmplitudeArray = new float[m_ToFPixelNumber];
122  }
123  if(this->m_RGBArray == NULL)
124  {
125  this->m_RGBArray = new unsigned char[m_RGBPixelNumber*3];
126  }
127  if(this->m_SourceDataArray == NULL)
128  {
129  this->m_SourceDataArray = new char[m_SourceDataSize];
130  }
131 
132  this->m_ToFImageWriter->SetDistanceImageFileName(this->m_DistanceImageFileName);
133  this->m_ToFImageWriter->SetAmplitudeImageFileName(this->m_AmplitudeImageFileName);
134  this->m_ToFImageWriter->SetIntensityImageFileName(this->m_IntensityImageFileName);
135  this->m_ToFImageWriter->SetRGBImageFileName(this->m_RGBImageFileName);
136  this->m_ToFImageWriter->SetRGBCaptureWidth(this->m_RGBCaptureWidth);
137  this->m_ToFImageWriter->SetRGBCaptureHeight(this->m_RGBCaptureHeight);
138  this->m_ToFImageWriter->SetToFCaptureWidth(this->m_ToFCaptureWidth);
139  this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight);
140  this->m_ToFImageWriter->SetToFImageType(this->m_ToFImageType);
141  this->m_ToFImageWriter->SetDistanceImageSelected(this->m_DistanceImageSelected);
142  this->m_ToFImageWriter->SetAmplitudeImageSelected(this->m_AmplitudeImageSelected);
143  this->m_ToFImageWriter->SetIntensityImageSelected(this->m_IntensityImageSelected);
144  this->m_ToFImageWriter->SetRGBImageSelected(this->m_RGBImageSelected);
145  this->m_ToFImageWriter->Open();
146 
147  this->m_AbortMutex->Lock();
148  this->m_Abort = false;
149  this->m_AbortMutex->Unlock();
150  this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this);
151 }
152 
154 {
155  this->m_MultiThreader->TerminateThread(this->m_ThreadID);
156 }
157 
158 ITK_THREAD_RETURN_TYPE ToFImageRecorder::RecordData(void* pInfoStruct)
159 {
160  struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
161  if (pInfo == NULL)
162  {
163  return ITK_THREAD_RETURN_VALUE;
164  }
165  if (pInfo->UserData == NULL)
166  {
167  return ITK_THREAD_RETURN_VALUE;
168  }
169  ToFImageRecorder* toFImageRecorder = (ToFImageRecorder*)pInfo->UserData;
170  if (toFImageRecorder!=NULL)
171  {
172 
173  ToFCameraDevice::Pointer toFCameraDevice = toFImageRecorder->GetCameraDevice();
174 
175  mitk::RealTimeClock::Pointer realTimeClock;
176  realTimeClock = mitk::RealTimeClock::New();
177  int n = 100;
178  double t1 = 0;
179  double t2 = 0;
180  t1 = realTimeClock->GetCurrentStamp();
181  bool overflow = false;
182  bool printStatus = false;
183  int requiredImageSequence = 0;
184  int numOfFramesRecorded = 0;
185 
186  bool abort = false;
187  toFImageRecorder->m_AbortMutex->Lock();
188  abort = toFImageRecorder->m_Abort;
189  toFImageRecorder->m_AbortMutex->Unlock();
190  while ( !abort )
191  {
192  if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) ||
193  (toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) )
194  {
195 
196  toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray,
197  toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray );
198 
199  if (toFImageRecorder->m_ImageSequence >= requiredImageSequence)
200  {
201  if (toFImageRecorder->m_ImageSequence > requiredImageSequence)
202  {
203  MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence;
204  }
205  requiredImageSequence = toFImageRecorder->m_ImageSequence + 1;
206  toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray,
207  toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_RGBArray );
208  numOfFramesRecorded++;
209  if (numOfFramesRecorded % n == 0)
210  {
211  printStatus = true;
212  }
213  if (printStatus)
214  {
215  t2 = realTimeClock->GetCurrentStamp() - t1;
216  MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFImageRecorder->m_ImageSequence;
217  t1 = realTimeClock->GetCurrentStamp();
218  printStatus = false;
219  }
220  }
221  toFImageRecorder->m_AbortMutex->Lock();
222  abort = toFImageRecorder->m_Abort;
223  toFImageRecorder->m_AbortMutex->Unlock();
224  }
225  else
226  {
227  abort = true;
228  }
229  } // end of while loop
230 
231  toFImageRecorder->InvokeEvent(itk::AbortEvent());
232 
233  toFImageRecorder->m_ToFImageWriter->Close();
234  }
235  return ITK_THREAD_RETURN_VALUE;
236 }
237 
239 {
240  this->m_ToFCameraDevice = aToFCameraDevice;
241 }
242 
244 {
245  return this->m_ToFCameraDevice;
246 }
247 
249 {
250  return this->m_ToFImageType;
251 }
252 
254 {
255  this->m_ToFImageType = toFImageType;
256 }
257 
259 {
260  return this->m_RecordMode;
261 }
262 
264 {
265  this->m_RecordMode = recordMode;
266 }
267 }
void StartRecording()
Starts the recording by spawning a Thread which streams the data to a file. Aborting of the record pr...
itk::SmartPointer< Self > Pointer
ToFImageRecorder::RecordMode m_RecordMode
mode of recording the images: specified number of frames (PerFrames) or infinite (Infinite) ...
int m_ImageSequence
number of images currently acquired
std::string m_AmplitudeImageFileName
file name for saving the amplitude image
itk::FastMutexLock::Pointer m_AbortMutex
mutex for thread-safe data access of abort flag
#define MITK_INFO
Definition: mitkLogMacros.h:22
ToFImageWriter::ToFImageType m_ToFImageType
type of image to be recorded: ToFImageType3D (0) or ToFImageType2DPlusT (1)
bool m_Abort
flag controlling the abort mechanism of the recording procedure. For thread-safety only use in combin...
int m_ToFCaptureHeight
height (y-dimension) of the images to record.
void SetToFImageType(ToFImageWriter::ToFImageType toFImageType)
Set the type of image to be recorded.
ToFCameraDevice::Pointer m_ToFCameraDevice
ToFCameraDevice used for acquiring the images.
Virtual interface and base class for all Time-of-Flight devices.
static Pointer New()
void StopRecording()
Stops the recording by setting the m_Abort flag to false.
DataCollection - Class to facilitate loading/accessing structured data.
std::string m_FileFormat
file format for saving images. If .csv is chosen, ToFImageCsvWriter is used
int m_ToFCaptureWidth
width (x-dimension) of the images to record.
int m_RGBCaptureHeight
height (y-dimension) of the images to record.
int m_NumOfFrames
number of frames to be recorded by this recorder
int m_RGBPixelNumber
number of pixels (widht*height) of the images to record
static Pointer New()
std::string m_DistanceImageFileName
file name for saving the distance image
int m_ToFPixelNumber
number of pixels (widht*height) of the images to record
ToFCameraDevice * GetCameraDevice()
Get the device used for acquiring ToF images.
ToFImageWriter::ToFImageType GetToFImageType()
Get the type of image to be recorded.
Recorder class for ToF images.
void WaitForThreadBeingTerminated()
Wait until thread is terinated.
int m_SourceDataSize
size of the source data provided by the device
void SetCameraDevice(ToFCameraDevice *aToFCameraDevice)
Set the device used for acquiring ToF images.
bool m_AmplitudeImageSelected
flag indicating if amplitude image should be recorded
float * m_DistanceArray
array holding the distance data
static ITK_THREAD_RETURN_TYPE RecordData(void *pInfoStruct)
Thread method acquiring data via the ToFCameraDevice and recording it to file via the ToFImageWriter...
std::string m_RGBImageFileName
file name for saving the rgb image
ToFImageRecorder::RecordMode GetRecordMode()
Returns the currently set RecordMode.
int m_RGBCaptureWidth
width (x-dimension) of the images to record.
float * m_IntensityArray
array holding the intensity data
itk::MultiThreader::Pointer m_MultiThreader
member for thread-handling (ITK-based)
ToFImageWriter::Pointer m_ToFImageWriter
image writer writing the acquired images to a file
bool m_DistanceImageSelected
flag indicating if distance image should be recorded
bool m_RGBImageSelected
flag indicating if rgb image should be recorded
void SetRecordMode(ToFImageRecorder::RecordMode recordMode)
Set the RecordMode.
unsigned char * m_RGBArray
array holding the RGB data if available (e.g. for Kinect)
static Pointer New(void)
instanciates a new, operating-system dependant, instance of mitk::RealTimeClock.
std::string m_IntensityImageFileName
file name for saving the intensity image
bool m_IntensityImageSelected
flag indicating if intensity image should be recorded
char * m_SourceDataArray
array holding the source data
int m_ThreadID
ID of the thread recording the data.
float * m_AmplitudeArray
array holding the amplitude data
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.