MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkToFCameraMESADevice.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============================================================================*/
13#include "mitkRealTimeClock.h"
14
15#include "itkMultiThreader.h"
16#include <itksys/SystemTools.hxx>
17
18namespace mitk
19{
23
27
29 {
30 bool ok = false;
31 if (m_Controller)
32 {
33 ok = m_Controller->OpenCameraConnection();
34 if (ok)
35 {
36 this->m_CaptureWidth = m_Controller->GetCaptureWidth();
37 this->m_CaptureHeight = m_Controller->GetCaptureHeight();
38 this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight;
39
40 // allocate buffer
41 this->m_IntensityArray = new float[this->m_PixelNumber];
42 for(int i=0; i<this->m_PixelNumber; i++) {this->m_IntensityArray[i]=0.0;}
43 this->m_DistanceArray = new float[this->m_PixelNumber];
44 for(int i=0; i<this->m_PixelNumber; i++) {this->m_DistanceArray[i]=0.0;}
45 this->m_AmplitudeArray = new float[this->m_PixelNumber];
46 for(int i=0; i<this->m_PixelNumber; i++) {this->m_AmplitudeArray[i]=0.0;}
47
48 this->m_DistanceDataBuffer = new float*[this->m_MaxBufferSize];
49 for(int i=0; i<this->m_MaxBufferSize; i++)
50 {
51 this->m_DistanceDataBuffer[i] = new float[this->m_PixelNumber];
52 }
53 this->m_AmplitudeDataBuffer = new float*[this->m_MaxBufferSize];
54 for(int i=0; i<this->m_MaxBufferSize; i++)
55 {
56 this->m_AmplitudeDataBuffer[i] = new float[this->m_PixelNumber];
57 }
58 this->m_IntensityDataBuffer = new float*[this->m_MaxBufferSize];
59 for(int i=0; i<this->m_MaxBufferSize; i++)
60 {
61 this->m_IntensityDataBuffer[i] = new float[this->m_PixelNumber];
62 }
63
64 m_CameraConnected = true;
65 }
66 }
67 return ok;
68 }
69
71 {
72 bool ok = false;
73 if (m_Controller)
74 {
75 ok = m_Controller->CloseCameraConnection();
76
77 // clean-up only if camera was connected
79 {
80 delete [] m_IntensityArray;
81 delete [] m_DistanceArray;
82 delete [] m_AmplitudeArray;
83
84 for(int i=0; i<this->m_MaxBufferSize; i++)
85 {
86 delete[] this->m_DistanceDataBuffer[i];
87 }
88 delete[] this->m_DistanceDataBuffer;
89 for(int i=0; i<this->m_MaxBufferSize; i++)
90 {
91 delete[] this->m_AmplitudeDataBuffer[i];
92 }
93 delete[] this->m_AmplitudeDataBuffer;
94 for(int i=0; i<this->m_MaxBufferSize; i++)
95 {
96 delete[] this->m_IntensityDataBuffer[i];
97 }
98 delete[] this->m_IntensityDataBuffer;
99
100 m_CameraConnected = false;
101 }
102
103 }
104 return ok;
105 }
106
108 {
110 {
111 // get the first image
112 this->m_Controller->UpdateCamera();
113 this->m_ImageMutex->Lock();
114 this->m_Controller->GetDistances(this->m_DistanceDataBuffer[this->m_FreePos]);
115 this->m_Controller->GetAmplitudes(this->m_AmplitudeDataBuffer[this->m_FreePos]);
116 this->m_Controller->GetIntensities(this->m_IntensityDataBuffer[this->m_FreePos]);
117 this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize;
118 this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize;
119 this->m_ImageSequence++;
120 this->m_ImageMutex->Unlock();
121
122 this->m_CameraActiveMutex->Lock();
123 this->m_CameraActive = true;
124 this->m_CameraActiveMutex->Unlock();
125 this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this);
126 // wait a little to make sure that the thread is started
127 itksys::SystemTools::Delay(10);
128 }
129 else
130 {
131 MITK_INFO<<"Camera not connected";
132 }
133 }
134
136 {
137 m_CameraActiveMutex->Lock();
138 m_CameraActive = false;
139 m_CameraActiveMutex->Unlock();
140 itksys::SystemTools::Delay(100);
141 if (m_MultiThreader.IsNotNull())
142 {
143 m_MultiThreader->TerminateThread(m_ThreadID);
144 }
145 // wait a little to make sure that the thread is terminated
146 itksys::SystemTools::Delay(10);
147 }
148
150 {
151 m_CameraActiveMutex->Lock();
152 bool ok = m_CameraActive;
153 m_CameraActiveMutex->Unlock();
154 return ok;
155 }
156
158 {
159 if (m_Controller)
160 {
161 m_Controller->UpdateCamera();
162 }
163 }
164
165 ITK_THREAD_RETURN_TYPE ToFCameraMESADevice::Acquire(void* pInfoStruct)
166 {
167 /* extract this pointer from Thread Info structure */
168 struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
169 if (pInfo == nullptr)
170 {
171 return ITK_THREAD_RETURN_VALUE;
172 }
173 if (pInfo->UserData == nullptr)
174 {
175 return ITK_THREAD_RETURN_VALUE;
176 }
177 ToFCameraMESADevice* toFCameraDevice = (ToFCameraMESADevice*)pInfo->UserData;
178 if (toFCameraDevice!=nullptr)
179 {
180 mitk::RealTimeClock::Pointer realTimeClock;
181 realTimeClock = mitk::RealTimeClock::New();
182 double t1, t2;
183 t1 = realTimeClock->GetCurrentStamp();
184 int n = 100;
185 bool overflow = false;
186 bool printStatus = false;
187 while (toFCameraDevice->IsCameraActive())
188 {
189 // update the ToF camera
190 toFCameraDevice->UpdateCamera();
191 // get the image data from the camera and write it at the next free position in the buffer
192 toFCameraDevice->m_ImageMutex->Lock();
193 toFCameraDevice->m_Controller->GetDistances(toFCameraDevice->m_DistanceDataBuffer[toFCameraDevice->m_FreePos]);
194 toFCameraDevice->m_Controller->GetAmplitudes(toFCameraDevice->m_AmplitudeDataBuffer[toFCameraDevice->m_FreePos]);
195 toFCameraDevice->m_Controller->GetIntensities(toFCameraDevice->m_IntensityDataBuffer[toFCameraDevice->m_FreePos]);
196 toFCameraDevice->m_ImageMutex->Unlock();
197
198 // call modified to indicate that cameraDevice was modified
199 toFCameraDevice->Modified();
200
201 toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize;
202 toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize;
203 toFCameraDevice->m_ImageSequence++;
204 if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos)
205 {
206 overflow = true;
207 }
208 if (toFCameraDevice->m_ImageSequence % n == 0)
209 {
210 printStatus = true;
211 }
212 if (overflow)
213 {
214 overflow = false;
215 }
216
217 // print current framerate
218 if (printStatus)
219 {
220 t2 = realTimeClock->GetCurrentStamp() - t1;
221 MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence;
222 t1 = realTimeClock->GetCurrentStamp();
223 printStatus = false;
224 }
225 } // end of while loop
226 }
227 return ITK_THREAD_RETURN_VALUE;
228 }
229
230 void ToFCameraMESADevice::GetAmplitudes(float* amplitudeArray, int& imageSequence)
231 {
232 m_ImageMutex->Lock();
233 if (m_CameraActive)
234 {
235 // copy the image buffer
236 for (int i=0; i<this->m_PixelNumber; i++)
237 {
238 amplitudeArray[i] = this->m_AmplitudeDataBuffer[this->m_CurrentPos][i];
239 }
240 imageSequence = this->m_ImageSequence;
241 }
242 else
243 {
244 MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
245 }
246 m_ImageMutex->Unlock();
247 }
248
249 void ToFCameraMESADevice::GetIntensities(float* intensityArray, int& imageSequence)
250 {
251 m_ImageMutex->Lock();
252 if (m_CameraActive)
253 {
254 for (int i=0; i<this->m_PixelNumber; i++)
255 {
256 intensityArray[i] = this->m_IntensityDataBuffer[this->m_CurrentPos][i];
257 }
258 imageSequence = this->m_ImageSequence;
259 }
260 else
261 {
262 MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
263 }
264 m_ImageMutex->Unlock();
265 }
266
267 void ToFCameraMESADevice::GetDistances(float* distanceArray, int& imageSequence)
268 {
269 m_ImageMutex->Lock();
270 if (m_CameraActive)
271 {
272 for (int i=0; i<this->m_PixelNumber; i++)
273 {
274 distanceArray[i] = this->m_DistanceDataBuffer[this->m_CurrentPos][i];
275 }
276 imageSequence = this->m_ImageSequence;
277 }
278 else
279 {
280 MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
281 }
282 m_ImageMutex->Unlock();
283 }
284
285 void ToFCameraMESADevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray,
286 int requiredImageSequence, int& capturedImageSequence, unsigned char* rgbDataArray)
287 {
288 if (m_CameraActive)
289 {
290 // check for empty buffer
291 if (this->m_ImageSequence < 0)
292 {
293 // buffer empty
294 MITK_INFO << "Buffer empty!! ";
295 capturedImageSequence = this->m_ImageSequence;
296 return;
297 }
298 // determine position of image in buffer
299 int pos = 0;
300 if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence))
301 {
302 capturedImageSequence = this->m_ImageSequence;
303 pos = this->m_CurrentPos;
304 }
305 else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize)
306 {
307 capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1;
308 pos = (this->m_CurrentPos + 1) % this->m_BufferSize;
309 }
310 else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence)
311
312 {
313 capturedImageSequence = requiredImageSequence;
314 pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize;
315 }
316
317 // write image data to float arrays
318 for (int i=0; i<this->m_PixelNumber; i++)
319 {
320 distanceArray[i] = this->m_DistanceDataBuffer[pos][i] /* * 1000 */;
321 amplitudeArray[i] = this->m_AmplitudeDataBuffer[pos][i];
322 intensityArray[i] = this->m_IntensityDataBuffer[pos][i];
323 }
324 }
325 else
326 {
327 MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
328 }
329 }
330
331 ToFCameraMESAController::Pointer ToFCameraMESADevice::GetController()
332 {
333 return this->m_Controller;
334 }
335
336 void ToFCameraMESADevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue )
337 {
338 ToFCameraDevice::SetProperty(propertyKey,propertyValue);
339 this->m_PropertyList->SetProperty(propertyKey, propertyValue);
340 if (strcmp(propertyKey, "ModulationFrequency") == 0)
341 {
342 int modulationFrequency = 0;
343 GetIntProperty(propertyKey, modulationFrequency);
344 m_Controller->SetModulationFrequency(modulationFrequency);
345 }
346 else if (strcmp(propertyKey, "IntegrationTime") == 0)
347 {
348 int integrationTime = 0;
349 GetIntProperty(propertyKey, integrationTime);
350 m_Controller->SetIntegrationTime(integrationTime);
351 }
352 }
353}
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)
int m_FreePos
current position in the buffer which will be filled with data acquired from the hardware
int m_CurrentPos
current position in the buffer which will be retrieved by the Get methods
int m_PixelNumber
number of pixels in the range image (m_CaptureWidth*m_CaptureHeight)
bool GetIntProperty(const char *propertyKey, int &integer)
get an int from the property list
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
std::mutex m_CameraActiveMutex
mutex for the cameraActive flag
std::mutex m_ImageMutex
mutex for images provided by the range camera
float * m_IntensityArray
float array holding the intensity image
float * m_DistanceArray
float array holding the distance image
int m_MaxBufferSize
maximal buffer size needed for initialization of data arrays. Default value is 100.
Interface for all representations of MESA ToF devices. ToFCameraMESADevice internally holds an instan...
virtual bool IsCameraActive()
returns whether the camera is currently active or not
ToFCameraMESAController::Pointer m_Controller
corresponding CameraController
virtual bool OnConnectCamera()
opens a connection to the ToF camera
virtual bool DisconnectCamera()
closes the connection to the camera
float ** m_DistanceDataBuffer
buffer holding the last distance images
float ** m_AmplitudeDataBuffer
buffer holding the last amplitude images
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...
virtual void SetProperty(const char *propertyKey, BaseProperty *propertyValue)
set a BaseProperty
virtual void UpdateCamera()
updates the camera for image acquisition
float ** m_IntensityDataBuffer
buffer holding the last intensity images
virtual void StopCamera()
stops the continuous updating of the camera
ToFCameraMESAController::Pointer GetController()
returns the corresponding camera controller
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 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...
static ITK_THREAD_RETURN_TYPE Acquire(void *pInfoStruct)
Thread method continuously acquiring images from the ToF hardware.
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...
virtual void StartCamera()
starts the continuous updating of the camera. A separate thread updates the source data,...
IGT Exceptions.
int strcmp(const String &s1, const String &s2)
Definition relates.cpp:14