Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
mitkKinectDevice.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 #include "mitkKinectDevice.h"
13 #include <mitkRealTimeClock.h>
14 
15 #include <itkMultiThreader.h>
16 #include <itksys/SystemTools.hxx>
17 
18 
19 namespace mitk
20 {
21 
23 {
25 }
26 
28 {
29 }
30 
32 {
33  bool ok = false;
34  if (m_Controller)
35  {
36  ok = m_Controller->OpenCameraConnection();
37  if (ok)
38  {
39  this->m_CaptureWidth = m_Controller->GetCaptureWidth();
40  this->m_CaptureHeight = m_Controller->GetCaptureHeight();
41  this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight;
42 
46 
47  this->SetBoolProperty("HasAmplitudeImage", m_Controller->GetUseIR());
48  this->SetBoolProperty("HasRGBImage", !m_Controller->GetUseIR());
49 
50  // allocate buffer
51  this->m_DistanceArray = new float[this->m_PixelNumber];
52  for(int i=0; i<this->m_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;}
53  this->m_AmplitudeArray = new float[this->m_PixelNumber];
54  for(int i=0; i<this->m_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;}
55 
56  this->m_DistanceDataBuffer = new float*[this->m_MaxBufferSize];
57  for(int i=0; i<this->m_MaxBufferSize; i++)
58  {
59  this->m_DistanceDataBuffer[i] = new float[this->m_PixelNumber];
60  }
61  this->m_AmplitudeDataBuffer = new float*[this->m_MaxBufferSize];
62  for(int i=0; i<this->m_MaxBufferSize; i++)
63  {
64  this->m_AmplitudeDataBuffer[i] = new float[this->m_PixelNumber];
65  }
66  this->m_RGBDataBuffer = new unsigned char*[this->m_MaxBufferSize];
67  for (int i=0; i<this->m_MaxBufferSize; i++)
68  {
69  this->m_RGBDataBuffer[i] = new unsigned char[this->m_PixelNumber*3];
70  }
71 
72  m_CameraConnected = true;
73  }
74  }
75  return ok;
76 }
77 
79 {
80  bool ok = false;
81  if (m_Controller)
82  {
83  ok = m_Controller->CloseCameraConnection();
84 
85  // clean-up only if camera was connected
87  {
88  delete [] m_DistanceArray;
89  delete [] m_AmplitudeArray;
90 
91  for(int i=0; i<this->m_MaxBufferSize; i++)
92  {
93  delete[] this->m_DistanceDataBuffer[i];
94  delete[] this->m_AmplitudeDataBuffer[i];
95  delete[] this->m_RGBDataBuffer[i];
96  }
97  delete[] this->m_DistanceDataBuffer;
98  delete[] this->m_AmplitudeDataBuffer;
99  delete[] this->m_RGBDataBuffer;
100 
101  m_CameraConnected = false;
102  }
103 
104  }
105  return ok;
106 }
107 
109 {
110  if (m_CameraConnected)
111  {
112  // get the first image
113  this->m_Controller->UpdateCamera();
114  this->m_ImageMutex->Lock();
115  this->m_Controller->GetAllData(this->m_DistanceDataBuffer[this->m_FreePos],this->m_AmplitudeDataBuffer[this->m_FreePos],this->m_RGBDataBuffer[this->m_FreePos]);
116  this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize;
117  this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize;
118  this->m_ImageSequence++;
119  this->m_ImageMutex->Unlock();
120 
121  this->m_CameraActiveMutex->Lock();
122  this->m_CameraActive = true;
123  this->m_CameraActiveMutex->Unlock();
124  this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this);
125  // wait a little to make sure that the thread is started
126  itksys::SystemTools::Delay(10);
127  }
128  else
129  {
130  MITK_INFO<<"Camera not connected";
131  }
132 }
133 
135 {
136  m_CameraActiveMutex->Lock();
137  m_CameraActive = false;
138  m_CameraActiveMutex->Unlock();
139  itksys::SystemTools::Delay(100);
140  if (m_MultiThreader.IsNotNull())
141  {
142  m_MultiThreader->TerminateThread(m_ThreadID);
143  }
144  // wait a little to make sure that the thread is terminated
145  itksys::SystemTools::Delay(10);
146 }
147 
149 {
150  m_CameraActiveMutex->Lock();
151  bool ok = m_CameraActive;
152  m_CameraActiveMutex->Unlock();
153  return ok;
154 }
155 
157 {
158  if (m_Controller)
159  {
160  m_Controller->UpdateCamera();
161  }
162 }
163 
164 ITK_THREAD_RETURN_TYPE KinectDevice::Acquire(void* pInfoStruct)
165 {
166  /* extract this pointer from Thread Info structure */
167  struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
168  if (pInfo == nullptr)
169  {
170  return ITK_THREAD_RETURN_VALUE;
171  }
172  if (pInfo->UserData == nullptr)
173  {
174  return ITK_THREAD_RETURN_VALUE;
175  }
176  KinectDevice* toFCameraDevice = (KinectDevice*)pInfo->UserData;
177  if (toFCameraDevice!=nullptr)
178  {
179  mitk::RealTimeClock::Pointer realTimeClock;
180  realTimeClock = mitk::RealTimeClock::New();
181  double t1, t2;
182  t1 = realTimeClock->GetCurrentStamp();
183  int n = 100;
184  bool overflow = false;
185  bool printStatus = false;
186  while (toFCameraDevice->IsCameraActive())
187  {
188  // update the ToF camera
189  toFCameraDevice->UpdateCamera();
190  // get the image data from the camera and write it at the next free position in the buffer
191  toFCameraDevice->m_ImageMutex->Lock();
192  toFCameraDevice->m_Controller->GetAllData(toFCameraDevice->m_DistanceDataBuffer[toFCameraDevice->m_FreePos],toFCameraDevice->m_AmplitudeDataBuffer[toFCameraDevice->m_FreePos],toFCameraDevice->m_RGBDataBuffer[toFCameraDevice->m_FreePos]);
193  toFCameraDevice->m_ImageMutex->Unlock();
194 
195  // call modified to indicate that cameraDevice was modified
196  toFCameraDevice->Modified();
197  toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize;
198  toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize;
199  toFCameraDevice->m_ImageSequence++;
200  if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos)
201  {
202  overflow = true;
203  }
204  if (toFCameraDevice->m_ImageSequence % n == 0)
205  {
206  printStatus = true;
207  }
208  if (overflow)
209  {
210  overflow = false;
211  }
212 
213  // print current framerate
214  if (printStatus)
215  {
216  t2 = realTimeClock->GetCurrentStamp() - t1;
217  MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence;
218  t1 = realTimeClock->GetCurrentStamp();
219  printStatus = false;
220  }
221  } // end of while loop
222  }
223  return ITK_THREAD_RETURN_VALUE;
224 }
225 
226 void KinectDevice::GetAmplitudes(float*, int& imageSequence)
227 {
228  m_ImageMutex->Lock();
229  if (m_CameraActive)
230  {
231  // copy the image buffer
232  imageSequence = this->m_ImageSequence;
233  }
234  else
235  {
236  MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
237  }
238  m_ImageMutex->Unlock();
239 }
240 
241 void KinectDevice::GetIntensities(float *, int &)
242 {
243 }
244 
245 void KinectDevice::GetDistances(float*, int& imageSequence)
246 {
247  m_ImageMutex->Lock();
248  if (m_CameraActive)
249  {
250  imageSequence = this->m_ImageSequence;
251  }
252  else
253  {
254  MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
255  }
256  m_ImageMutex->Unlock();
257 }
258 
259 void KinectDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float*, char*,
260  int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray)
261 {
262  if (m_CameraActive)
263  {
264  // check for empty buffer
265  if (this->m_ImageSequence < 0)
266  {
267  // buffer empty
268  MITK_INFO << "Buffer empty!! ";
269  capturedImageSequence = this->m_ImageSequence;
270  return;
271  }
272 
273  // determine position of image in buffer
274  int pos = 0;
275  if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence))
276  {
277  capturedImageSequence = this->m_ImageSequence;
278  pos = this->m_CurrentPos;
279  }
280  else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize)
281  {
282  capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1;
283  pos = (this->m_CurrentPos + 1) % this->m_BufferSize;
284  }
285  else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence)
286  {
287  capturedImageSequence = requiredImageSequence;
288  pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize;
289  }
290 
291  memcpy( distanceArray, this->m_DistanceDataBuffer[pos], m_PixelNumber*sizeof(float));
292  if(m_Controller->GetUseIR())
293  {
294  memcpy( amplitudeArray, this->m_AmplitudeDataBuffer[pos], m_PixelNumber*sizeof(float));
295  }
296  else
297  {
298  memcpy( rgbDataArray, this->m_RGBDataBuffer[pos], m_RGBPixelNumber*3*sizeof(unsigned char));
299  }
300  }
301  else
302  {
303  MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
304  }
305 }
306 
307 KinectController::Pointer KinectDevice::GetController()
308 {
309  return this->m_Controller;
310 }
311 
312 void KinectDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue )
313 {
314  ToFCameraDevice::SetProperty(propertyKey,propertyValue);
315  this->m_PropertyList->SetProperty(propertyKey, propertyValue);
316  if (strcmp(propertyKey, "RGB") == 0)
317  {
318  bool rgb = false;
319  GetBoolProperty(propertyKey, rgb);
320  m_Controller->SetUseIR(!rgb);
321  }
322  else if (strcmp(propertyKey, "IR") == 0)
323  {
324  bool ir = false;
325  GetBoolProperty(propertyKey, ir);
326  m_Controller->SetUseIR(ir);
327  }
328 }
329 
331 {
332  return this->GetCaptureWidth();
333 }
334 
336 {
337  return this->GetCaptureHeight();
338 }
339 }
virtual int GetCaptureHeight()
get the currently set capture height
#define MITK_INFO
Definition: mitkLogMacros.h:18
static ITK_THREAD_RETURN_TYPE Acquire(void *pInfoStruct)
Thread method continuously acquiring images from the ToF hardware.
float ** m_DistanceDataBuffer
buffer holding the last distance images
virtual void UpdateCamera()
updates the camera for image acquisition
float ** m_AmplitudeDataBuffer
buffer holding the last infra-red (IR) images
bool GetBoolProperty(const char *propertyKey, bool &boolValue)
get a bool from the property list
int m_RGBPixelNumber
number of pixels in the range image (m_RGBImageWidth*m_RGBImageHeight)
int m_PixelNumber
number of pixels in the range image (m_CaptureWidth*m_CaptureHeight)
virtual void GetDistances(float *distanceArray, int &imageSequence)
gets the distance data from the ToF camera measuring the distance between the camera and the differen...
DataCollection - Class to facilitate loading/accessing structured data.
PropertyList::Pointer m_PropertyList
a list of the corresponding properties
int GetRGBCaptureHeight()
returns the height of the RGB image
float * m_DistanceArray
float array holding the distance image
int m_ThreadID
ID of the started thread.
virtual bool OnConnectCamera()
opens a connection to the ToF camera
Interface for all representations of Kinect devices. KinectDevice internally holds an instance of Kin...
itk::FastMutexLock::Pointer m_CameraActiveMutex
mutex for the cameraActive flag
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.
virtual bool IsCameraActive()
returns whether the camera is currently active or not
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue)
set a BaseProperty property in the property list
int m_RGBImageHeight
height of the RGB image (y dimension)
#define MITK_WARN
Definition: mitkLogMacros.h:19
bool m_CameraActive
flag indicating if the camera is currently active or not. Caution: thread safe access only! ...
virtual void GetAmplitudes(float *amplitudeArray, int &imageSequence)
gets the amplitude data from the ToF camera as the strength of the active illumination of every pixel...
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! ...
KinectController::Pointer m_Controller
corresponding CameraController
bool t2(false)
int m_CaptureWidth
width of the range image (x dimension)
virtual void GetAllImages(float *distanceArray, float *amplitudeArray, float *intensityArray, char *sourceDataArray, int requiredImageSequence, int &capturedImageSequence, unsigned char *rgbDataArray=nullptr)
gets the 3 images (distance, amplitude, intensity) from the ToF camera. Caution! The user is responsi...
itk::FastMutexLock::Pointer m_ImageMutex
mutex for images provided by the range camera
virtual void GetIntensities(float *intensityArray, int &imageSequence)
gets the intensity data from the ToF camera as a greyscale image. Caution! The user is responsible fo...
int m_BufferSize
buffer size of the image buffer needed for loss-less acquisition of range data
KinectController::Pointer GetController()
returns the corresponding camera controller
static Pointer New()
virtual bool DisconnectCamera()
closes the connection to the camera
unsigned char ** m_RGBDataBuffer
buffer holding the last RGB image
int m_MaxBufferSize
maximal buffer size needed for initialization of data arrays. Default value is 100.
int m_CaptureHeight
height of the range image (y dimension)
virtual void StopCamera()
stops the continuous updating of the camera
virtual void StartCamera()
starts the continuous updating of the camera. A separate thread updates the source data...
float * m_AmplitudeArray
float array holding the amplitude image
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue)
set a BaseProperty
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)
int GetRGBCaptureWidth()
returns the width of the RGB image
virtual int GetCaptureWidth()
get the currently set capture width
int m_ImageSequence
counter for acquired images