Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkToFCameraMITKPlayerDevice.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 ===================================================================*/
18 #include "mitkRealTimeClock.h"
19 
20 #include <iostream>
21 #include <fstream>
22 #include <itkMultiThreader.h>
23 #include <itksys/SystemTools.hxx>
24 
25 namespace mitk
26 {
28  m_DistanceDataBuffer(NULL), m_AmplitudeDataBuffer(NULL), m_IntensityDataBuffer(NULL), m_RGBDataBuffer(NULL)
29 {
31 }
32 
34 {
37 }
38 
40 {
41  bool ok = m_Controller->OpenCameraConnection();
42  if (ok)
43  {
44  this->m_CaptureWidth = m_Controller->GetCaptureWidth();
45  this->m_CaptureHeight = m_Controller->GetCaptureHeight();
46  this->m_RGBImageWidth = m_Controller->GetRGBCaptureWidth();
47  this->m_RGBImageHeight = m_Controller->GetRGBCaptureHeight();
48  this->m_PixelNumber = m_Controller->GetPixelNumber();
49  this->m_RGBPixelNumber = m_Controller->GetRGBPixelNumber();
50 
52  this->SetBoolProperty("RGBImageHasDifferentResolution", true);
53 
54 
57 
58  m_CameraConnected = true;
59  }
60  return ok;
61 }
62 
64 {
65  bool ok = m_Controller->CloseCameraConnection();
66  if (ok)
67  {
68  m_CameraConnected = false;
69  m_PropertyList->Clear();
70  }
71  return ok;
72 }
73 
75 {
77  {
78  // get the first image
79  this->m_Controller->UpdateCamera();
80  this->m_ImageMutex->Lock();
81  this->m_Controller->GetDistances(this->m_DistanceDataBuffer[this->m_FreePos]);
82  this->m_Controller->GetAmplitudes(this->m_AmplitudeDataBuffer[this->m_FreePos]);
83  this->m_Controller->GetIntensities(this->m_IntensityDataBuffer[this->m_FreePos]);
84  this->m_Controller->GetRgb(this->m_RGBDataBuffer[this->m_FreePos]);
85  this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize;
86  this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize;
87  this->m_ImageSequence++;
88  this->m_ImageMutex->Unlock();
89 
90  this->m_CameraActiveMutex->Lock();
91  this->m_CameraActive = true;
92  this->m_CameraActiveMutex->Unlock();
93  this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this);
94  // wait a little to make sure that the thread is started
95  itksys::SystemTools::Delay(10);
96  }
97  else
98  {
99  MITK_INFO<<"Camera not connected";
100  }
101 }
102 
104 {
105  m_Controller->UpdateCamera();
106 }
107 
108 ITK_THREAD_RETURN_TYPE ToFCameraMITKPlayerDevice::Acquire(void* pInfoStruct)
109 {
110  /* extract this pointer from Thread Info structure */
111  struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
112  if (pInfo == NULL)
113  {
114  return ITK_THREAD_RETURN_VALUE;
115  }
116  if (pInfo->UserData == NULL)
117  {
118  return ITK_THREAD_RETURN_VALUE;
119  }
120  ToFCameraMITKPlayerDevice* toFCameraDevice = (ToFCameraMITKPlayerDevice*)pInfo->UserData;
121  if (toFCameraDevice!=NULL)
122  {
123  mitk::RealTimeClock::Pointer realTimeClock;
124  realTimeClock = mitk::RealTimeClock::New();
125  int n = 100;
126  double t1, t2;
127  t1 = realTimeClock->GetCurrentStamp();
128  bool overflow = false;
129  bool printStatus = false;
130  while (toFCameraDevice->IsCameraActive())
131  {
132  // update the ToF camera
133  toFCameraDevice->UpdateCamera();
134  // get image data from controller and write it to the according buffer
135  toFCameraDevice->m_Controller->GetDistances(toFCameraDevice->m_DistanceDataBuffer[toFCameraDevice->m_FreePos]);
136  toFCameraDevice->m_Controller->GetAmplitudes(toFCameraDevice->m_AmplitudeDataBuffer[toFCameraDevice->m_FreePos]);
137  toFCameraDevice->m_Controller->GetIntensities(toFCameraDevice->m_IntensityDataBuffer[toFCameraDevice->m_FreePos]);
138  toFCameraDevice->m_Controller->GetRgb(toFCameraDevice->m_RGBDataBuffer[toFCameraDevice->m_FreePos]);
139  toFCameraDevice->Modified();
140  toFCameraDevice->m_ImageMutex->Lock();
141  toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize;
142  toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize;
143  toFCameraDevice->m_ImageSequence++;
144  if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos)
145  {
146  overflow = true;
147  }
148  if (toFCameraDevice->m_ImageSequence % n == 0)
149  {
150  printStatus = true;
151  }
152  toFCameraDevice->m_ImageMutex->Unlock();
153  if (overflow)
154  {
155  overflow = false;
156  }
157  // print current framerate
158  if (printStatus)
159  {
160  t2 = realTimeClock->GetCurrentStamp() - t1;
161  MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence;
162  t1 = realTimeClock->GetCurrentStamp();
163  printStatus = false;
164  }
165  } // end of while loop
166  }
167  return ITK_THREAD_RETURN_VALUE;
168 }
169 
170 void ToFCameraMITKPlayerDevice::GetAmplitudes(float* amplitudeArray, int& imageSequence)
171 {
172  m_ImageMutex->Lock();
173  // write amplitude image data to float array
174  for (int i=0; i<this->m_PixelNumber; i++)
175  {
176  amplitudeArray[i] = this->m_AmplitudeDataBuffer[this->m_CurrentPos][i];
177  }
178  imageSequence = this->m_ImageSequence;
179  m_ImageMutex->Unlock();
180 }
181 
182 void ToFCameraMITKPlayerDevice::GetIntensities(float* intensityArray, int& imageSequence)
183 {
184  m_ImageMutex->Lock();
185  // write intensity image data to float array
186  for (int i=0; i<this->m_PixelNumber; i++)
187  {
188  intensityArray[i] = this->m_IntensityDataBuffer[this->m_CurrentPos][i];
189  }
190  imageSequence = this->m_ImageSequence;
191  m_ImageMutex->Unlock();
192 }
193 
194 void ToFCameraMITKPlayerDevice::GetDistances(float* distanceArray, int& imageSequence)
195 {
196  m_ImageMutex->Lock();
197  // write distance image data to float array
198  for (int i=0; i<this->m_PixelNumber; i++)
199  {
200  distanceArray[i] = this->m_DistanceDataBuffer[this->m_CurrentPos][i];
201  }
202  imageSequence = this->m_ImageSequence;
203  m_ImageMutex->Unlock();
204 }
205 
206 void ToFCameraMITKPlayerDevice::GetRgb(unsigned char* rgbArray, int& imageSequence)
207 {
208  m_ImageMutex->Lock();
209  // write intensity image data to unsigned char array
210  for (int i=0; i<this->m_RGBPixelNumber*3; i++)
211  {
212  rgbArray[i] = this->m_RGBDataBuffer[this->m_CurrentPos][i];
213  }
214  imageSequence = this->m_ImageSequence;
215  m_ImageMutex->Unlock();
216 }
217 
218 void ToFCameraMITKPlayerDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* /*sourceDataArray*/,
219  int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray)
220 {
221  m_ImageMutex->Lock();
222 
223  //check for empty buffer
224  if (this->m_ImageSequence < 0)
225  {
226  // buffer empty
227  MITK_INFO << "Buffer empty!! ";
228  capturedImageSequence = this->m_ImageSequence;
229  m_ImageMutex->Unlock();
230  return;
231  }
232  // determine position of image in buffer
233  int pos = 0;
234  if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence))
235  {
236  capturedImageSequence = this->m_ImageSequence;
237  pos = this->m_CurrentPos;
238  }
239  else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize)
240  {
241  capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1;
242  pos = (this->m_CurrentPos + 1) % this->m_BufferSize;
243  }
244  else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence)
245  {
246  capturedImageSequence = requiredImageSequence;
247  pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize;
248  }
249 
250  if(this->m_DistanceDataBuffer&&this->m_AmplitudeDataBuffer&&this->m_IntensityDataBuffer&&this->m_RGBDataBuffer)
251  {
252  // write image data to float arrays
253  memcpy(distanceArray, this->m_DistanceDataBuffer[pos], this->m_PixelNumber * sizeof(float));
254  memcpy(amplitudeArray, this->m_AmplitudeDataBuffer[pos], this->m_PixelNumber * sizeof(float));
255  memcpy(intensityArray, this->m_IntensityDataBuffer[pos], this->m_PixelNumber * sizeof(float));
256  memcpy(rgbDataArray, this->m_RGBDataBuffer[pos], this->m_RGBPixelNumber * 3 * sizeof(unsigned char));
257  }
258  m_ImageMutex->Unlock();
259 }
260 
261 void ToFCameraMITKPlayerDevice::SetInputFileName(std::string inputFileName)
262 {
263  this->m_InputFileName = inputFileName;
264  this->m_Controller->SetInputFileName(inputFileName);
265 }
266 
267 void ToFCameraMITKPlayerDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue )
268 {
269  this->m_PropertyList->SetProperty(propertyKey, propertyValue);
270 
271  ToFCameraMITKPlayerController::Pointer myController = dynamic_cast<mitk::ToFCameraMITKPlayerController*>(this->m_Controller.GetPointer());
272 
273  std::string strValue;
274  GetStringProperty(propertyKey, strValue);
275  if (strcmp(propertyKey, "DistanceImageFileName") == 0)
276  {
277  myController->SetDistanceImageFileName(strValue);
278  }
279  else if (strcmp(propertyKey, "AmplitudeImageFileName") == 0)
280  {
281  std::ifstream amplitudeImage(strValue.c_str());
282  if(amplitudeImage)
283  {
284  this->m_PropertyList->SetBoolProperty("HasAmplitudeImage", true);
285  myController->SetAmplitudeImageFileName(strValue);
286  }
287  else
288  {
289  MITK_WARN << "File " << strValue << " does not exist!";
290  }
291  }
292  else if (strcmp(propertyKey, "IntensityImageFileName") == 0)
293  {
294  std::ifstream intensityImage(strValue.c_str());
295  if(intensityImage)
296  {
297  this->m_PropertyList->SetBoolProperty("HasIntensityImage", true);
298  myController->SetIntensityImageFileName(strValue);
299  }
300  else
301  {
302  MITK_WARN << "File " << strValue << " does not exist!";
303  }
304  }
305  else if (strcmp(propertyKey, "RGBImageFileName") == 0)
306  {
307  std::ifstream intensityImage(strValue.c_str());
308  if(intensityImage)
309  {
310  this->m_PropertyList->SetBoolProperty("HasRGBImage", true);
311  myController->SetRGBImageFileName(strValue);
312  }
313  else
314  {
315  MITK_WARN << "File " << strValue << " does not exist!";
316  }
317  }
318 }
319 
321 {
322  if (m_DistanceDataBuffer)
323  {
324  for(int i=0; i<this->m_MaxBufferSize; i++)
325  {
326  delete[] this->m_DistanceDataBuffer[i];
327  }
328  delete[] this->m_DistanceDataBuffer;
329  }
330  if (m_AmplitudeDataBuffer)
331  {
332  for(int i=0; i<this->m_MaxBufferSize; i++)
333  {
334  delete[] this->m_AmplitudeDataBuffer[i];
335  }
336  delete[] this->m_AmplitudeDataBuffer;
337  }
338  if (m_IntensityDataBuffer)
339  {
340  for(int i=0; i<this->m_MaxBufferSize; i++)
341  {
342  delete[] this->m_IntensityDataBuffer[i];
343  }
344  delete[] this->m_IntensityDataBuffer;
345  }
346  if (m_RGBDataBuffer)
347  {
348  for(int i=0; i<this->m_MaxBufferSize; i++)
349  {
350  delete[] this->m_RGBDataBuffer[i];
351  }
352  delete[] this->m_RGBDataBuffer;
353  }
354 }
355 
357 {
358  // free memory if it was already allocated
359  this->CleanUpDataBuffers();
360  // allocate buffers
361  this->m_DistanceDataBuffer = new float*[this->m_MaxBufferSize];
362  for(int i=0; i<this->m_MaxBufferSize; i++)
363  {
364  this->m_DistanceDataBuffer[i] = new float[this->m_PixelNumber];
365  }
366  this->m_AmplitudeDataBuffer = new float*[this->m_MaxBufferSize];
367  for(int i=0; i<this->m_MaxBufferSize; i++)
368  {
369  this->m_AmplitudeDataBuffer[i] = new float[this->m_PixelNumber];
370  }
371  this->m_IntensityDataBuffer = new float*[this->m_MaxBufferSize];
372  for(int i=0; i<this->m_MaxBufferSize; i++)
373  {
374  this->m_IntensityDataBuffer[i] = new float[this->m_PixelNumber];
375  }
376  this->m_RGBDataBuffer = new unsigned char*[this->m_MaxBufferSize];
377  for(int i=0; i<this->m_MaxBufferSize; i++)
378  {
379  this->m_RGBDataBuffer[i] = new unsigned char[this->m_RGBPixelNumber*3];
380  }
381 }
382 }
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
std::string m_InputFileName
member holding the file name of the current input file
int m_RGBPixelNumber
number of pixels in the range image (m_RGBImageWidth*m_RGBImageHeight)
bool GetStringProperty(const char *propertyKey, std::string &string)
get a string from the property list
virtual void SetInputFileName(std::string inputFileName)
Set file name where the data is recorded.
int m_PixelNumber
number of pixels in the range image (m_CaptureWidth*m_CaptureHeight)
DataCollection - Class to facilitate loading/accessing structured data.
PropertyList::Pointer m_PropertyList
a list of the corresponding properties
int m_ThreadID
ID of the started thread.
void CleanUpDataBuffers()
Clean up memory (pixel buffers)
virtual bool DisconnectCamera() override
closes the connection to the camera
itk::FastMutexLock::Pointer m_CameraActiveMutex
mutex for the cameraActive flag
virtual void GetRgb(unsigned char *rgbArray, int &imageSequence)
gets the rgb data from the ToF camera. Caution! The user is responsible for allocating and deleting t...
itk::MultiThreader::Pointer m_MultiThreader
itk::MultiThreader used for thread handling
int m_FreePos
current position in the buffer which will be filled with data acquired from the hardware ...
Abstract base class for properties.
int m_RGBImageHeight
height of the RGB image (y dimension)
#define MITK_WARN
Definition: mitkLogMacros.h:23
bool m_CameraActive
flag indicating if the camera is currently active or not. Caution: thread safe access only! ...
int m_CurrentPos
current position in the buffer which will be retrieved by the Get methods
bool m_CameraConnected
flag indicating if the camera is successfully connected or not. Caution: thread safe access only! ...
Device class representing a player for MITK-ToF images.
int m_CaptureWidth
width of the range image (x dimension)
itk::FastMutexLock::Pointer m_ImageMutex
mutex for images provided by the range camera
ToFCameraMITKPlayerController::Pointer m_Controller
member holding the corresponding controller
virtual void AllocatePixelArrays()
method for allocating memory for pixel arrays m_IntensityArray, m_DistanceArray and m_AmplitudeArray ...
virtual void UpdateCamera() override
updates the camera for image acquisition
int m_BufferSize
buffer size of the image buffer needed for loss-less acquisition of range data
int m_MaxBufferSize
maximal buffer size needed for initialization of data arrays. Default value is 100.
virtual bool OnConnectCamera() override
opens a connection to the ToF camera
virtual void GetAllImages(float *distanceArray, float *amplitudeArray, float *intensityArray, char *sourceDataArray, int requiredImageSequence, int &capturedImageSequence, unsigned char *rgbDataArray=NULL) override
gets the 3 images (distance, amplitude, intensity) from the ToF camera. Caution! The user is responsi...
int m_CaptureHeight
height of the range image (y dimension)
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue) override
set a BaseProperty
virtual void GetAmplitudes(float *amplitudeArray, int &imageSequence) override
gets the amplitude data from the ToF camera as the strength of the active illumination of every pixel...
virtual void GetDistances(float *distanceArray, int &imageSequence) override
gets the distance data from the ToF camera measuring the distance between the camera and the differen...
void AllocateDataBuffers()
Allocate pixel buffers.
Controller for playing ToF images saved in MITK (.pic) format.
static Pointer New(void)
instanciates a new, operating-system dependant, instance of mitk::RealTimeClock.
void SetBoolProperty(const char *propertyKey, bool boolValue)
set a bool property in the property list
int m_RGBImageWidth
width of the RGB image (x dimension)
static ITK_THREAD_RETURN_TYPE Acquire(void *pInfoStruct)
Thread method continuously acquiring images from the specified input file.
int m_ImageSequence
counter for acquired images
virtual bool IsCameraActive()
returns true if the camera is connected and started
virtual void GetIntensities(float *intensityArray, int &imageSequence) override
gets the intensity data from the ToF camera as a greyscale image. Caution! The user is responsible fo...
virtual void StartCamera() override
starts the continuous updating of the camera. A separate thread updates the source data...