Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.