MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkKinectDevice.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found 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
19namespace mitk
20{
21
23{
24 m_Controller = mitk::KinectController::New();
25}
26
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{
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
164ITK_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
226void 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
242{
243}
244
245void 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
259void 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
307KinectController::Pointer KinectDevice::GetController()
308{
309 return this->m_Controller;
310}
311
312void 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}
Interface for all representations of Kinect devices. KinectDevice internally holds an instance of Kin...
KinectController::Pointer m_Controller
corresponding CameraController
float ** m_AmplitudeDataBuffer
buffer holding the last infra-red (IR) images
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue)
set a BaseProperty
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...
float ** m_DistanceDataBuffer
buffer holding the last distance images
virtual void GetDistances(float *distanceArray, int &imageSequence)
gets the distance data from the ToF camera measuring the distance between the camera and the differen...
virtual void UpdateCamera()
updates the camera for image acquisition
virtual void StopCamera()
stops the continuous updating of the camera
static ITK_THREAD_RETURN_TYPE Acquire(void *pInfoStruct)
Thread method continuously acquiring images from the ToF hardware.
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...
KinectController::Pointer GetController()
returns the corresponding camera controller
virtual bool OnConnectCamera()
opens a connection to the ToF camera
virtual bool IsCameraActive()
returns whether the camera is currently active or not
virtual void StartCamera()
starts the continuous updating of the camera. A separate thread updates the source data,...
virtual bool DisconnectCamera()
closes the connection to the camera
unsigned char ** m_RGBDataBuffer
buffer holding the last RGB image
int GetRGBCaptureWidth()
returns the width of the RGB image
int GetRGBCaptureHeight()
returns the height of the RGB image
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...
static Pointer New(void)
instanciates a new, operating-system dependant, instance of mitk::RealTimeClock.
int m_ImageSequence
counter for acquired images
PropertyList::Pointer m_PropertyList
a list of the corresponding properties
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue)
set a BaseProperty property in the property list
int m_CaptureWidth
width of the range image (x dimension)
void SetBoolProperty(const char *propertyKey, bool boolValue)
set a bool property in the property list
int m_FreePos
current position in the buffer which will be filled with data acquired from the hardware
int m_RGBImageWidth
width of the RGB image (x dimension)
int m_CurrentPos
current position in the buffer which will be retrieved by the Get methods
bool GetBoolProperty(const char *propertyKey, bool &boolValue)
get a bool from the property list
int m_PixelNumber
number of pixels in the range image (m_CaptureWidth*m_CaptureHeight)
bool m_CameraConnected
flag indicating if the camera is successfully connected or not. Caution: thread safe access only!
int m_CaptureHeight
height of the range image (y dimension)
bool m_CameraActive
flag indicating if the camera is currently active or not. Caution: thread safe access only!
float * m_AmplitudeArray
float array holding the amplitude image
int m_BufferSize
buffer size of the image buffer needed for loss-less acquisition of range data
int m_RGBPixelNumber
number of pixels in the range image (m_RGBImageWidth*m_RGBImageHeight)
std::mutex m_CameraActiveMutex
mutex for the cameraActive flag
std::mutex m_ImageMutex
mutex for images provided by the range camera
float * m_DistanceArray
float array holding the distance image
int m_RGBImageHeight
height of the RGB image (y dimension)
int m_MaxBufferSize
maximal buffer size needed for initialization of data arrays. Default value is 100.
IGT Exceptions.
int strcmp(const String &s1, const String &s2)
Definition relates.cpp:14