PageRenderTime 45ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Modules/ToFHardware/mitkToFCameraPMDDevice.cpp

https://github.com/cim-unito/MITK
C++ | 411 lines | 311 code | 35 blank | 65 comment | 47 complexity | fe5dbca8dd5655e00b80c36e04f84892 MD5 | raw file
  1. /*=========================================================================
  2. Program: Medical Imaging & Interaction Toolkit
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date: 2010-05-27 16:06:53 +0200 (Do, 27 Mai 2010) $
  6. Version: $Revision: $
  7. Copyright (c) German Cancer Research Center, Division of Medical and
  8. Biological Informatics. All rights reserved.
  9. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
  10. This software is distributed WITHOUT ANY WARRANTY; without even
  11. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE. See the above copyright notices for more information.
  13. =========================================================================*/
  14. #include "mitkToFCameraPMDDevice.h"
  15. #include "mitkRealTimeClock.h"
  16. #include "itkMultiThreader.h"
  17. #include <itksys/SystemTools.hxx>
  18. namespace mitk
  19. {
  20. ToFCameraPMDDevice::ToFCameraPMDDevice() :
  21. m_SourceDataBuffer(NULL), m_SourceDataArray(NULL)
  22. {
  23. }
  24. ToFCameraPMDDevice::~ToFCameraPMDDevice()
  25. {
  26. this->CleanUpSourceData();
  27. }
  28. bool ToFCameraPMDDevice::ConnectCamera()
  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_SourceDataSize = m_Controller->GetSourceDataStructSize();
  39. this->m_PixelNumber = this->m_CaptureWidth * this->m_CaptureHeight;
  40. // allocate buffers
  41. AllocatePixelArrays();
  42. this->AllocateSourceData();
  43. m_CameraConnected = true;
  44. }
  45. }
  46. return ok;
  47. }
  48. bool ToFCameraPMDDevice::DisconnectCamera()
  49. {
  50. bool ok = false;
  51. if (m_Controller)
  52. {
  53. ok = m_Controller->CloseCameraConnection();
  54. if (ok)
  55. {
  56. m_CameraConnected = false;
  57. }
  58. }
  59. return ok;
  60. }
  61. void ToFCameraPMDDevice::StartCamera()
  62. {
  63. if (m_CameraConnected)
  64. {
  65. // get the first image
  66. this->m_Controller->UpdateCamera();
  67. this->m_ImageMutex->Lock();
  68. //this->m_Controller->GetSourceData(this->m_SourceDataArray);
  69. this->m_Controller->GetSourceData(this->m_SourceDataBuffer[this->m_FreePos]);
  70. this->m_FreePos = (this->m_FreePos+1) % this->m_BufferSize;
  71. this->m_CurrentPos = (this->m_CurrentPos+1) % this->m_BufferSize;
  72. this->m_ImageSequence++;
  73. this->m_ImageMutex->Unlock();
  74. this->m_CameraActiveMutex->Lock();
  75. this->m_CameraActive = true;
  76. this->m_CameraActiveMutex->Unlock();
  77. this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->Acquire, this);
  78. // wait a little to make sure that the thread is started
  79. itksys::SystemTools::Delay(10);
  80. }
  81. else
  82. {
  83. MITK_INFO<<"Camera not connected";
  84. }
  85. }
  86. void ToFCameraPMDDevice::StopCamera()
  87. {
  88. m_CameraActiveMutex->Lock();
  89. m_CameraActive = false;
  90. m_CameraActiveMutex->Unlock();
  91. itksys::SystemTools::Delay(100);
  92. if (m_MultiThreader.IsNotNull())
  93. {
  94. m_MultiThreader->TerminateThread(m_ThreadID);
  95. }
  96. // wait a little to make sure that the thread is terminated
  97. itksys::SystemTools::Delay(10);
  98. }
  99. bool ToFCameraPMDDevice::IsCameraActive()
  100. {
  101. m_CameraActiveMutex->Lock();
  102. bool ok = m_CameraActive;
  103. m_CameraActiveMutex->Unlock();
  104. return ok;
  105. }
  106. void ToFCameraPMDDevice::UpdateCamera()
  107. {
  108. if (m_Controller)
  109. {
  110. m_Controller->UpdateCamera();
  111. }
  112. }
  113. ITK_THREAD_RETURN_TYPE ToFCameraPMDDevice::Acquire(void* pInfoStruct)
  114. {
  115. /* extract this pointer from Thread Info structure */
  116. struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
  117. if (pInfo == NULL)
  118. {
  119. return ITK_THREAD_RETURN_VALUE;
  120. }
  121. if (pInfo->UserData == NULL)
  122. {
  123. return ITK_THREAD_RETURN_VALUE;
  124. }
  125. ToFCameraPMDDevice* toFCameraDevice = (ToFCameraPMDDevice*)pInfo->UserData;
  126. if (toFCameraDevice!=NULL)
  127. {
  128. mitk::RealTimeClock::Pointer realTimeClock;
  129. realTimeClock = mitk::RealTimeClock::New();
  130. double t1, t2;
  131. t1 = realTimeClock->GetCurrentStamp();
  132. int n = 100;
  133. bool overflow = false;
  134. bool printStatus = false;
  135. while (toFCameraDevice->IsCameraActive())
  136. {
  137. // update the ToF camera
  138. toFCameraDevice->UpdateCamera();
  139. // get the source data from the camera and write it at the next free position in the buffer
  140. toFCameraDevice->m_ImageMutex->Lock();
  141. toFCameraDevice->m_Controller->GetSourceData(toFCameraDevice->m_SourceDataBuffer[toFCameraDevice->m_FreePos]);
  142. toFCameraDevice->m_ImageMutex->Unlock();
  143. // call modified to indicate that cameraDevice was modified
  144. toFCameraDevice->Modified();
  145. /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  146. TODO Buffer Handling currently only works for buffer size 1
  147. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
  148. //toFCameraDevice->m_ImageSequence++;
  149. toFCameraDevice->m_FreePos = (toFCameraDevice->m_FreePos+1) % toFCameraDevice->m_BufferSize;
  150. toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize;
  151. toFCameraDevice->m_ImageSequence++;
  152. if (toFCameraDevice->m_FreePos == toFCameraDevice->m_CurrentPos)
  153. {
  154. // buffer overflow
  155. //MITK_INFO << "Buffer overflow!! ";
  156. //toFCameraDevice->m_CurrentPos = (toFCameraDevice->m_CurrentPos+1) % toFCameraDevice->m_BufferSize;
  157. //toFCameraDevice->m_ImageSequence++;
  158. overflow = true;
  159. }
  160. if (toFCameraDevice->m_ImageSequence % n == 0)
  161. {
  162. printStatus = true;
  163. }
  164. if (overflow)
  165. {
  166. //itksys::SystemTools::Delay(10);
  167. overflow = false;
  168. }
  169. /*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  170. END TODO Buffer Handling currently only works for buffer size 1
  171. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
  172. // print current framerate
  173. if (printStatus)
  174. {
  175. t2 = realTimeClock->GetCurrentStamp() - t1;
  176. //MITK_INFO << "t2: " << t2 <<" Time (s) for 1 image: " << (t2/1000) / n << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence;
  177. MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFCameraDevice->m_ImageSequence;
  178. t1 = realTimeClock->GetCurrentStamp();
  179. printStatus = false;
  180. }
  181. } // end of while loop
  182. }
  183. return ITK_THREAD_RETURN_VALUE;
  184. }
  185. // TODO: Buffer size currently set to 1. Once Buffer handling is working correctly, method may be reactivated
  186. // void ToFCameraPMDDevice::ResetBuffer(int bufferSize)
  187. // {
  188. // this->m_BufferSize = bufferSize;
  189. // this->m_CurrentPos = -1;
  190. // this->m_FreePos = 0;
  191. // }
  192. void ToFCameraPMDDevice::GetAmplitudes(float* amplitudeArray, int& imageSequence)
  193. {
  194. if (m_CameraActive)
  195. {
  196. // 1) copy the image buffer
  197. // 2) Flip around y- axis (vertical axis)
  198. m_ImageMutex->Lock();
  199. this->m_Controller->GetAmplitudes(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_AmplitudeArray);
  200. m_ImageMutex->Unlock();
  201. for (int i=0; i<this->m_CaptureHeight; i++)
  202. {
  203. for (int j=0; j<this->m_CaptureWidth; j++)
  204. {
  205. amplitudeArray[i*this->m_CaptureWidth+j] = this->m_AmplitudeArray[(i+1)*this->m_CaptureWidth-1-j];
  206. }
  207. }
  208. imageSequence = this->m_ImageSequence;
  209. }
  210. else
  211. {
  212. MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
  213. }
  214. }
  215. void ToFCameraPMDDevice::GetIntensities(float* intensityArray, int& imageSequence)
  216. {
  217. if (m_CameraActive)
  218. {
  219. // 1) copy the image buffer
  220. // 2) Flip around y- axis (vertical axis)
  221. m_ImageMutex->Lock();
  222. this->m_Controller->GetIntensities(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_IntensityArray);
  223. m_ImageMutex->Unlock();
  224. for (int i=0; i<this->m_CaptureHeight; i++)
  225. {
  226. for (int j=0; j<this->m_CaptureWidth; j++)
  227. {
  228. intensityArray[i*this->m_CaptureWidth+j] = this->m_IntensityArray[(i+1)*this->m_CaptureWidth-1-j];
  229. }
  230. }
  231. imageSequence = this->m_ImageSequence;
  232. }
  233. else
  234. {
  235. MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
  236. }
  237. m_ImageMutex->Unlock();
  238. }
  239. void ToFCameraPMDDevice::GetDistances(float* distanceArray, int& imageSequence)
  240. {
  241. if (m_CameraActive)
  242. {
  243. // 1) copy the image buffer
  244. // 2) convert the distance values from m to mm
  245. // 3) Flip around y- axis (vertical axis)
  246. m_ImageMutex->Lock();
  247. this->m_Controller->GetDistances(this->m_SourceDataBuffer[this->m_CurrentPos], this->m_DistanceArray);
  248. m_ImageMutex->Unlock();
  249. for (int i=0; i<this->m_CaptureHeight; i++)
  250. {
  251. for (int j=0; j<this->m_CaptureWidth; j++)
  252. {
  253. distanceArray[i*this->m_CaptureWidth+j] = 1000 * this->m_DistanceArray[(i+1)*this->m_CaptureWidth-1-j];
  254. }
  255. }
  256. imageSequence = this->m_ImageSequence;
  257. }
  258. else
  259. {
  260. MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
  261. }
  262. }
  263. void ToFCameraPMDDevice::GetAllImages(float* distanceArray, float* amplitudeArray, float* intensityArray, char* sourceDataArray,
  264. int requiredImageSequence, int& capturedImageSequence)
  265. {
  266. if (m_CameraActive)
  267. {
  268. // 1) copy the image buffer
  269. // 2) convert the distance values from m to mm
  270. // 3) Flip around y- axis (vertical axis)
  271. // check for empty buffer
  272. if (this->m_ImageSequence < 0)
  273. {
  274. // buffer empty
  275. MITK_INFO << "Buffer empty!! ";
  276. capturedImageSequence = this->m_ImageSequence;
  277. return;
  278. }
  279. // determine position of image in buffer
  280. int pos = 0;
  281. if ((requiredImageSequence < 0) || (requiredImageSequence > this->m_ImageSequence))
  282. {
  283. capturedImageSequence = this->m_ImageSequence;
  284. pos = this->m_CurrentPos;
  285. //MITK_INFO << "Required image not found! Required: " << requiredImageSequence << " delivered/current: " << this->m_ImageSequence;
  286. }
  287. else if (requiredImageSequence <= this->m_ImageSequence - this->m_BufferSize)
  288. {
  289. capturedImageSequence = (this->m_ImageSequence - this->m_BufferSize) + 1;
  290. pos = (this->m_CurrentPos + 1) % this->m_BufferSize;
  291. //MITK_INFO << "Out of buffer! Required: " << requiredImageSequence << " delivered: " << capturedImageSequence << " current: " << this->m_ImageSequence;
  292. }
  293. else // (requiredImageSequence > this->m_ImageSequence - this->m_BufferSize) && (requiredImageSequence <= this->m_ImageSequence)
  294. {
  295. capturedImageSequence = requiredImageSequence;
  296. pos = (this->m_CurrentPos + (10-(this->m_ImageSequence - requiredImageSequence))) % this->m_BufferSize;
  297. }
  298. m_ImageMutex->Lock();
  299. this->m_Controller->GetDistances(this->m_SourceDataBuffer[pos], this->m_DistanceArray);
  300. this->m_Controller->GetAmplitudes(this->m_SourceDataBuffer[pos], this->m_AmplitudeArray);
  301. this->m_Controller->GetIntensities(this->m_SourceDataBuffer[pos], this->m_IntensityArray);
  302. memcpy(sourceDataArray, this->m_SourceDataBuffer[this->m_CurrentPos], this->m_SourceDataSize);
  303. m_ImageMutex->Unlock();
  304. int u, v;
  305. for (int i=0; i<this->m_CaptureHeight; i++)
  306. {
  307. for (int j=0; j<this->m_CaptureWidth; j++)
  308. {
  309. u = i*this->m_CaptureWidth+j;
  310. v = (i+1)*this->m_CaptureWidth-1-j;
  311. distanceArray[u] = 1000 * this->m_DistanceArray[v]; // unit in minimeter
  312. //distanceArray[u] = this->m_DistanceArray[v]; // unit in meter
  313. amplitudeArray[u] = this->m_AmplitudeArray[v];
  314. intensityArray[u] = this->m_IntensityArray[v];
  315. }
  316. }
  317. }
  318. else
  319. {
  320. MITK_WARN("ToF") << "Warning: Data can only be acquired if camera is active.";
  321. }
  322. }
  323. ToFCameraPMDController::Pointer ToFCameraPMDDevice::GetController()
  324. {
  325. return this->m_Controller;
  326. }
  327. void ToFCameraPMDDevice::SetProperty( const char *propertyKey, BaseProperty* propertyValue )
  328. {
  329. ToFCameraDevice::SetProperty(propertyKey,propertyValue);
  330. this->m_PropertyList->SetProperty(propertyKey, propertyValue);
  331. if (strcmp(propertyKey, "ModulationFrequency") == 0)
  332. {
  333. int modulationFrequency = 0;
  334. GetIntProperty(propertyValue, modulationFrequency);
  335. m_Controller->SetModulationFrequency(modulationFrequency);
  336. }
  337. else if (strcmp(propertyKey, "IntegrationTime") == 0)
  338. {
  339. int integrationTime = 0;
  340. GetIntProperty(propertyValue, integrationTime);
  341. m_Controller->SetIntegrationTime(integrationTime);
  342. }
  343. }
  344. void ToFCameraPMDDevice::AllocateSourceData()
  345. {
  346. // clean up if array and data have already been allocated
  347. CleanUpSourceData();
  348. // (re-) allocate memory
  349. this->m_SourceDataArray = new char[this->m_SourceDataSize];
  350. for(int i=0; i<this->m_SourceDataSize; i++) {this->m_SourceDataArray[i]=0;}
  351. this->m_SourceDataBuffer = new char*[this->m_MaxBufferSize];
  352. for(int i=0; i<this->m_MaxBufferSize; i++)
  353. {
  354. this->m_SourceDataBuffer[i] = new char[this->m_SourceDataSize];
  355. }
  356. }
  357. void ToFCameraPMDDevice::CleanUpSourceData()
  358. {
  359. if (m_SourceDataArray)
  360. {
  361. delete[] m_SourceDataArray;
  362. }
  363. if (m_SourceDataBuffer)
  364. {
  365. for(int i=0; i<this->m_MaxBufferSize; i++)
  366. {
  367. delete[] this->m_SourceDataBuffer[i];
  368. }
  369. delete[] this->m_SourceDataBuffer;
  370. }
  371. }
  372. }