VirtualRangeCam.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include "../include/cob_camera_sensors/StdAfx.h"
19 
20 #ifdef __LINUX__
23 #include "tinyxml.h"
24 #else
26 #include "cob_common/cob_vision_utils/common/include/cob_vision_utils/VisionUtils.h"
27 #include "cob_vision/windows/src/extern/TinyXml/tinyxml.h"
28 #endif
29 
30 #include <opencv/highgui.h>
31 
32 namespace fs = boost::filesystem;
33 using namespace ipa_CameraSensors;
34 
36 {
38 }
39 
41 {
42  m_initialized = false;
43  m_open = false;
44 
45  m_BufferSize = 1;
46 
47  m_ImageCounter = 0;
48 }
49 
50 
52 {
53  if (isOpen())
54  {
55  Close();
56  }
57 }
58 
59 unsigned long VirtualRangeCam::Init(std::string directory, int cameraIndex)
60 {
61  if (isInitialized())
62  {
64  }
65 
67 
68  // It is important to put this before LoadParameters
69  m_CameraDataDirectory = directory;
70 
71  // Load SR parameters from xml-file
72  if (LoadParameters((directory + "cameraSensorsIni.xml").c_str(), cameraIndex) & RET_FAILED)
73  {
74  std::cerr << "ERROR - VirtualRangeCam::Init:" << std::endl;
75  std::cerr << "\t ... Parsing xml configuration file failed" << std::endl;
76  return (RET_FAILED | RET_INIT_CAMERA_FAILED);
77  }
78 
79  m_CoeffsInitialized = true;
81  {
82  // Load z-calibration files
83  std::string filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA0.xml";
84  CvMat* c_mat = (CvMat*)cvLoad(filename.c_str());
85  if (! c_mat)
86  {
87  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
88  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA0.txt" << "." << std::endl;
89  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
90  m_CoeffsInitialized = false;
91  // no RET_FAILED, as we might want to calibrate the camera to create these files
92  }
93  else
94  {
95  m_CoeffsA0 = c_mat;
96  cvReleaseMat(&c_mat);
97  }
98 
99  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA1.xml";
100  c_mat = (CvMat*)cvLoad(filename.c_str());
101  if (! c_mat)
102  {
103  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
104  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA1.txt" << "." << std::endl;
105  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
106  m_CoeffsInitialized = false;
107  // no RET_FAILED, as we might want to calibrate the camera to create these files
108  }
109  else
110  {
111  m_CoeffsA1 = c_mat;
112  cvReleaseMat(&c_mat);
113  }
114 
115  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA2.xml";
116  c_mat = (CvMat*)cvLoad(filename.c_str());
117  if (! c_mat)
118  {
119  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
120  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA2.txt" << "." << std::endl;
121  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
122  m_CoeffsInitialized = false;
123  // no RET_FAILED, as we might want to calibrate the camera to create these files
124  }
125  else
126  {
127  m_CoeffsA2 = c_mat;
128  cvReleaseMat(&c_mat);
129  }
130 
131  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA3.xml";
132  c_mat = (CvMat*)cvLoad(filename.c_str());
133  if (! c_mat)
134  {
135  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
136  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA3.txt" << "." << std::endl;
137  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
138  m_CoeffsInitialized = false;
139  // no RET_FAILED, as we might want to calibrate the camera to create these files
140  }
141  else
142  {
143  m_CoeffsA3 = c_mat;
144  cvReleaseMat(&c_mat);
145  }
146 
147  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA4.xml";
148  c_mat = (CvMat*)cvLoad(filename.c_str());
149  if (! c_mat)
150  {
151  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
152  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA4.txt" << "." << std::endl;
153  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
154  m_CoeffsInitialized = false;
155  // no RET_FAILED, as we might want to calibrate the camera to create these files
156  }
157  else
158  {
159  m_CoeffsA4 = c_mat;
160  cvReleaseMat(&c_mat);
161  }
162 
163  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA5.xml";
164  c_mat = (CvMat*)cvLoad(filename.c_str());
165  if (! c_mat)
166  {
167  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
168  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA5.txt" << "." << std::endl;
169  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
170  m_CoeffsInitialized = false;
171  // no RET_FAILED, as we might want to calibrate the camera to create these files
172  }
173  else
174  {
175  m_CoeffsA5 = c_mat;
176  cvReleaseMat(&c_mat);
177  }
178 
179  filename = directory + "MatlabCalibrationData/PMD/ZCoeffsA6.xml";
180  c_mat = (CvMat*)cvLoad(filename.c_str());
181  if (! c_mat)
182  {
183  std::cerr << "ERROR - PMDCamCube::LoadParameters:" << std::endl;
184  std::cerr << "\t ... Error while loading " << directory + "MatlabCalibrationData/ZcoeffsA6.txt" << "." << std::endl;
185  std::cerr << "\t ... Data is necessary for z-calibration of swissranger camera" << std::endl;
186  m_CoeffsInitialized = false;
187  // no RET_FAILED, as we might want to calibrate the camera to create these files
188  }
189  else
190  {
191  m_CoeffsA6 = c_mat;
192  cvReleaseMat(&c_mat);
193  }
194  }
195 
196  m_CameraIndex = cameraIndex;
197 
198  // set init flag
199  m_initialized = true;
200 
201  return RET_OK;
202 }
203 
204 
205 inline void VirtualRangeCam::UpdateImageDimensionsOnFirstImage(std::string filename, std::string ext)
206 {
207  if (m_ImageWidth == -1 || m_ImageHeight == -1)
208  {
209  if (ext != ".bin")
210  {
211  IplImage* image = (IplImage*) cvLoad(filename.c_str(), 0);
212  m_ImageWidth = image->width;
213  m_ImageHeight = image->height;
214  cvReleaseImage(&image);
215  }
216  else
217  {
218  cv::Mat mat;
219  ipa_Utils::LoadMat(mat, filename);
220  m_ImageHeight = mat.rows;
221  m_ImageWidth = mat.cols;
222  }
223  }
224 }
225 
226 
227 inline void VirtualRangeCam::FindSourceImageFormat(std::map<std::string, int>::iterator& itCounter, std::string& ext)
228 {
229  if (itCounter->second > 0)
230  {
231  if (ext == "") ext = itCounter->first;
232  else
233  {
234  std::cerr << "ERROR - VirtualRangeCam::Open:\n";
235  std::cerr << "\t ... The provided path contains data in mixed formats (e.g. .xml and .bin).\n";
236  assert(false);
237  }
238  }
239 }
240 
241 
242 unsigned long VirtualRangeCam::Open()
243 {
244  if (!isInitialized())
245  {
247  }
248 
249  if (isOpen())
250  {
251  return (RET_OK | RET_CAMERA_ALREADY_OPEN);
252  }
253 
254  // Convert camera ID to string
255  std::stringstream ss;
256  std::string sCameraIndex;
257  ss << m_CameraIndex;
258  ss >> sCameraIndex;
259 
260  m_ImageWidth = -1;
261  m_ImageHeight = -1;
262 
263  // Create absolute filename and check if directory exists
264  fs::path absoluteDirectoryName( m_CameraDataDirectory );
265  if ( !fs::exists( absoluteDirectoryName ) )
266  {
267  std::cerr << "ERROR - VirtualRangeCam::Open:" << std::endl;
268  std::cerr << "\t ... Path '" << absoluteDirectoryName.file_string() << "' not found" << std::endl;
270  }
271 
272  std::vector<std::string> extensionList;
273  extensionList.push_back(".xml"); extensionList.push_back(".bin"); extensionList.push_back(".png"); extensionList.push_back(".jpg"); extensionList.push_back(".bmp");
274  std::map<std::string, int> amplitudeImageCounter; // first index is the extension (.xml, .bin), second is the number of such images found
275  std::map<std::string, int> intensityImageCounter; // first index is the extension (.xml, .bin, .png, .jpg, .bmp), second is the number of such images found
276  std::map<std::string, int> coordinateImageCounter; // first index is the extension (.xml, .bin), second is the number of such images found
277  std::map<std::string, int> rangeImageCounter; // first index is the extension (.xml, .bin), second is the number of such images found
278  std::map<std::string, std::vector<std::string> > amplitudeImageFileNames; // first index is the extension (.xml, .bin), second is the vector of file names
279  std::map<std::string, std::vector<std::string> > intensityImageFileNames; // first index is the extension (.xml, .bin, .png, .jpg, .bmp), second is the vector of file names
280  std::map<std::string, std::vector<std::string> > coordinateImageFileNames; // first index is the extension (.xml, .bin), second is the vector of file names
281  std::map<std::string, std::vector<std::string> > rangeImageFileNames; // first index is the extension (.xml, .bin), second is the vector of file names
282  // Extract all image filenames from the directory
283  if ( fs::exists( absoluteDirectoryName ) )
284  {
285  std::cout << "INFO - VirtualRangeCam::Open :" << std::endl;
286  std::cout << "\t ... Parsing directory '" << absoluteDirectoryName.directory_string() << "'" << std::endl;
287 
288  fs::directory_iterator end_iter;
289  for ( fs::directory_iterator dir_itr( absoluteDirectoryName ); dir_itr != end_iter; ++dir_itr )
290  {
291  try
292  {
293  if (fs::is_regular_file(dir_itr->status()))
294  {
295  std::string filename = dir_itr->path().string();
296 
297  // intensity image formats
298  for (unsigned int extIndex=0; extIndex<extensionList.size(); extIndex++)
299  {
300  std::string ext = extensionList[extIndex];
301  std::string format = "32F1_";
302  if (extIndex>=2) format = "8U3_";
303  if ((dir_itr->path().extension() == ext) && filename.find( "RangeCamIntensity_" + format + sCameraIndex, 0 ) != std::string::npos)
304  {
305  (intensityImageCounter.find(ext) == intensityImageCounter.end()) ? intensityImageCounter[ext] = 1 : intensityImageCounter[ext]++;
306  //std::cout << "VirtualRangeCam::Open(): Reading '" << filename << "\n";
307  intensityImageFileNames[ext].push_back(filename);
308  UpdateImageDimensionsOnFirstImage(filename, ext);
309  }
310  }
311 
312  // amplitude image formats
313  for (unsigned int extIndex=0; extIndex<2; extIndex++)
314  {
315  std::string ext = extensionList[extIndex];
316  if ((dir_itr->path().extension() == ext) && filename.find( "RangeCamAmplitude_32F1_" + sCameraIndex, 0 ) != std::string::npos)
317  {
318  (amplitudeImageCounter.find(ext) == amplitudeImageCounter.end()) ? amplitudeImageCounter[ext] = 1 : amplitudeImageCounter[ext]++;
319  //std::cout << "VirtualRangeCam::Open(): Reading '" << filename << "\n";
320  amplitudeImageFileNames[ext].push_back(filename);
321  UpdateImageDimensionsOnFirstImage(filename, ext);
322  }
323  }
324 
325  // coordinate image formats
326  for (unsigned int extIndex=0; extIndex<2; extIndex++)
327  {
328  std::string ext = extensionList[extIndex];
329  if ((dir_itr->path().extension() == ext) && filename.find( "RangeCamCoordinate_32F3_" + sCameraIndex, 0 ) != std::string::npos)
330  {
331  (coordinateImageCounter.find(ext) == coordinateImageCounter.end()) ? coordinateImageCounter[ext] = 1 : coordinateImageCounter[ext]++;
332  coordinateImageFileNames[ext].push_back(filename);
333  UpdateImageDimensionsOnFirstImage(filename, ext);
334  //std::cout << "VirtualRangeCam::Open(): Reading '" << filename << "\n";
335  }
336  }
337 
338  // range image formats
339  for (unsigned int extIndex=0; extIndex<2; extIndex++)
340  {
341  std::string ext = extensionList[extIndex];
342  if ((dir_itr->path().extension() == ext) && filename.find( "RangeCamRange_32F1_" + sCameraIndex, 0 ) != std::string::npos)
343  {
344  (rangeImageCounter.find(ext) == rangeImageCounter.end()) ? rangeImageCounter[ext] = 1 : rangeImageCounter[ext]++;
345  //std::cout << "VirtualRangeCam::Open(): Reading '" << filename << "\n";
346  rangeImageFileNames[ext].push_back(filename);
347  UpdateImageDimensionsOnFirstImage(filename, ext);
348  }
349  }
350  }
351  }
352  catch ( const std::exception &ex )
353  {
354  std::cout << "WARNING - VirtualRangeCam::Open:" << std::endl;
355  std::cout << "\t ... Exception catch of '" << ex.what() << "'" << std::endl;
356  }
357  }
358  // intensity
359  std::map<std::string, int>::iterator itCounter;
360  std::string extInt = "";
361  for (itCounter = intensityImageCounter.begin(); itCounter != intensityImageCounter.end(); itCounter++) FindSourceImageFormat(itCounter, extInt);
362  if (extInt != "") m_IntensityImageFileNames = intensityImageFileNames[extInt];
363 
364  // amplitude
365  std::string extAmp = "";
366  for (itCounter = amplitudeImageCounter.begin(); itCounter != amplitudeImageCounter.end(); itCounter++) FindSourceImageFormat(itCounter, extAmp);
367  if (extAmp != "") m_AmplitudeImageFileNames = amplitudeImageFileNames[extAmp];
368 
369  // coordinates
370  std::string extCoord = "";
371  for (itCounter = coordinateImageCounter.begin(); itCounter != coordinateImageCounter.end(); itCounter++) FindSourceImageFormat(itCounter, extCoord);
372  if (extCoord != "") m_CoordinateImageFileNames = coordinateImageFileNames[extCoord];
373 
374  // range
375  std::string extRange = "";
376  for (itCounter = rangeImageCounter.begin(); itCounter != rangeImageCounter.end(); itCounter++) FindSourceImageFormat(itCounter, extRange);
377  if (extRange != "") m_RangeImageFileNames = rangeImageFileNames[extRange];
378 
379  std::sort(m_IntensityImageFileNames.begin(),m_IntensityImageFileNames.end());
380  std::sort(m_AmplitudeImageFileNames.begin(),m_AmplitudeImageFileNames.end());
382  std::sort(m_RangeImageFileNames.begin(),m_RangeImageFileNames.end());
383  std::cout << "INFO - VirtualRangeCam::Open:" << std::endl;
384  std::cout << "\t ... Extracted '" << intensityImageCounter[extInt] << "' intensity images (3*8 or 16 bit/value)\n";
385  std::cout << "\t ... Extracted '" << amplitudeImageCounter[extAmp] << "' amplitude images (16 bit/value)\n";
386  std::cout << "\t ... Extracted '" << coordinateImageCounter[extCoord] << "' coordinate images (3*16 bit/value)\n";
387  std::cout << "\t ... Extracted '" << rangeImageCounter[extRange] << "' range images (16 bit/value)\n";
388 
389  if (intensityImageCounter[extInt] == 0 && amplitudeImageCounter[extAmp] == 0)
390  {
391  std::cerr << "ERROR - VirtualRangeCam::Open:" << std::endl;
392  std::cerr << "\t ... Could not detect any intensity or amplitude images" << std::endl;
393  std::cerr << "\t ... from the specified directory." << std::endl;
395  }
396 
397  if (coordinateImageCounter[extCoord] != 0 &&
398  ((intensityImageCounter[extInt] != coordinateImageCounter[extCoord] &&
399  amplitudeImageCounter[extAmp] != coordinateImageCounter[extCoord]) ||
400  (coordinateImageCounter[extCoord] != rangeImageCounter[extRange])))
401  {
402  std::cerr << "ERROR - VirtualRangeCam::Open:" << std::endl;
403  std::cerr << "\t ... Number of intensity, range and coordinate images must agree." << std::endl;
405  }
406 
407  if((m_CalibrationMethod == NATIVE || m_CalibrationMethod == MATLAB_NO_Z) && coordinateImageCounter[extCoord] == 0 )
408  {
409  std::cerr << "ERROR - VirtualRangeCam::Open:" << std::endl;
410  std::cerr << "\t ... Coordinate images must be available for calibration mode NATIVE or MATLAB_NO_Z." << std::endl;
412  }
413  }
414  else
415  {
416  std::cerr << "ERROR - VirtualRangeCam::Open():" << std::endl;
417  std::cerr << "\t ... Path '" << absoluteDirectoryName.file_string() << "' is not a directory." << std::endl;
419  }
420 
421 
422  std::cout << "**************************************************" << std::endl;
423  std::cout << "VirtualRangeCam::Open(): Virtual range camera OPEN" << std::endl;
424  std::cout << "**************************************************" << std::endl<< std::endl;
425  m_open = true;
426 
427  return RET_OK;
428 }
429 
430 
431 unsigned long VirtualRangeCam::Close()
432 {
433  if (!isOpen())
434  {
435  return (RET_OK);
436  }
437 
438  m_open = false;
439  return RET_OK;
440 
441 }
442 
443 
444 unsigned long VirtualRangeCam::SetProperty(t_cameraProperty* cameraProperty)
445 {
446  switch (cameraProperty->propertyID)
447  {
449 
450  default:
451  std::cerr << "ERROR - VirtualRangeCam::SetProperty:" << std::endl;
452  std::cerr << "\t ... Property " << cameraProperty->propertyID << " unspecified.\n";
453  return RET_FAILED;
454  break;
455  }
456 
457  return RET_OK;
458 }
459 
460 
462 {
464 }
465 
466 
467 unsigned long VirtualRangeCam::GetProperty(t_cameraProperty* cameraProperty)
468 {
469  switch (cameraProperty->propertyID)
470  {
472  cameraProperty->cameraResolution.xResolution = m_ImageWidth;
473  cameraProperty->cameraResolution.yResolution = m_ImageHeight;
474  cameraProperty->propertyType = TYPE_CAMERA_RESOLUTION;
475  break;
476 
478  cameraProperty->u_integerData = m_BufferSize;
479  return RET_OK;
480  break;
481 
482  default:
483  std::cerr << "VirtualRangeCam::GetProperty:" << std::endl;
484  std::cerr << "\t ... Property " << cameraProperty->propertyID << " unspecified.";
485  return RET_FAILED;
486  break;
487 
488  }
489 
490  return RET_OK;
491 }
492 
493 
494 // Wrapper for IplImage retrival from AcquireImage
495 // Images have to be initialized prior to calling this function
496 unsigned long VirtualRangeCam::AcquireImages(cv::Mat* rangeImage, cv::Mat* grayImage, cv::Mat* cartesianImage,
497  bool getLatestFrame, bool undistort, ipa_CameraSensors::t_ToFGrayImageType grayImageType)
498 {
499  //std::cout << m_ImageCounter << std::endl;
500 
501  char* rangeImageData = 0;
502  char* grayImageData = 0;
503  char* cartesianImageData = 0;
504  int widthStepRange = -1;
505  int widthStepGray = -1;
506  int widthStepCartesian = -1;
507 
508  if(rangeImage)
509  {
510  rangeImage->create(m_ImageHeight, m_ImageWidth, CV_32FC1);
511  rangeImageData = (char*) rangeImage->data;
512  widthStepRange = rangeImage->step;
513  }
514 
515  if(grayImage)
516  {
517  if (grayImageType == ipa_CameraSensors::INTENSITY_8U3) grayImage->create(m_ImageHeight, m_ImageWidth, CV_8UC3);
518  else grayImage->create(m_ImageHeight, m_ImageWidth, CV_32FC1);
519  grayImageData = (char*) grayImage->data;
520  widthStepGray = grayImage->step;
521  }
522 
523  if(cartesianImage)
524  {
525  cartesianImage->create(m_ImageHeight, m_ImageWidth, CV_32FC3);
526  cartesianImageData = (char*) cartesianImage->data;
527  widthStepCartesian = cartesianImage->step;
528  }
529 
530  if (widthStepRange+widthStepGray+widthStepCartesian == -3)
531  {
532  return RET_OK;
533  }
534 
535  return AcquireImages(widthStepRange, widthStepGray, widthStepCartesian, rangeImageData, grayImageData, cartesianImageData, getLatestFrame, undistort, grayImageType);
536 
537 }
538 
539 unsigned long VirtualRangeCam::AcquireImages(int widthStepRange, int widthStepGray, int widthStepCartesian, char* rangeImageData, char* grayImageData, char* cartesianImageData,
540  bool getLatestFrame, bool undistort, ipa_CameraSensors::t_ToFGrayImageType grayImageType)
541 {
542  if (!m_open)
543  {
544  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:" << std::endl;
545  std::cerr << "\t ... Camera not open." << std::endl;
546  return (RET_FAILED | RET_CAMERA_NOT_OPEN);
547  }
548 
550 // Range image (distorted or undistorted)
552  if (rangeImageData)
553  {
554  float* f_ptr = 0;
555  float* f_ptr_dst = 0;
556  bool releaseNecessary = false;
557 
558  cv::Mat rangeMat;
559  IplImage rangeIpl;
560  IplImage* rangeImage = &rangeIpl;
561  if (m_RangeImageFileNames[m_ImageCounter].find(".bin") != std::string::npos)
562  {
564  rangeIpl = (IplImage)rangeMat;
565  }
566  else if (m_RangeImageFileNames[m_ImageCounter].find(".xml") != std::string::npos)
567  {
568  rangeImage = (IplImage*) cvLoad(m_RangeImageFileNames[m_ImageCounter].c_str(), 0);
569  releaseNecessary = true;
570  }
571  else
572  {
573  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:\n";
574  std::cerr << "\t ... Wrong file format for file " << m_RangeImageFileNames[m_ImageCounter] << ".\n";
575  CV_Assert(false);
576  }
577 
578  if (!undistort)
579  {
580  // put data in corresponding IPLImage structures
581  for(unsigned int row=0; row<(unsigned int)m_ImageHeight; row++)
582  {
583  f_ptr = (float*) (rangeImage->imageData + row*rangeImage->widthStep);
584  f_ptr_dst = (float*) (rangeImageData + row*widthStepRange);
585 
586  for (unsigned int col=0; col<(unsigned int)m_ImageWidth; col++)
587  {
588  f_ptr_dst[col] = f_ptr[col];
589  }
590  }
591  }
592  else
593  {
594  cv::Mat undistortedData (m_ImageHeight, m_ImageWidth, CV_32FC1, (float*) rangeImageData);
595  cv::Mat cpp_rangeImage = rangeImage;
596 
597  assert (!m_undistortMapX.empty() && !m_undistortMapY.empty());
598  cv::remap(cpp_rangeImage, undistortedData, m_undistortMapX, m_undistortMapY, cv::INTER_LINEAR);
599  }
600 
601  if (releaseNecessary) cvReleaseImage(&rangeImage);
602  } // End if (rangeImage)
604 // Gray image based on amplitude or intensity (distorted or undistorted)
606  if(grayImageData)
607  {
608  float* f_ptr = 0;
609  float* f_ptr_dst = 0;
610  unsigned char* uc_ptr = 0;
611  unsigned char* uc_ptr_dst = 0;
612  cv::Mat grayMat;
613  IplImage grayIpl;
614  IplImage* grayImage = &grayIpl;
615  bool releaseNecessary = false;
616 
617  // load image
618  if ((grayImageType == ipa_CameraSensors::INTENSITY_32F1) || (grayImageType == ipa_CameraSensors::INTENSITY_8U3))
619  {
620  // intensity image
621  if (m_IntensityImageFileNames[m_ImageCounter].find(".bin") != std::string::npos)
622  {
624  grayIpl = (IplImage)grayMat;
625  }
626  else if (m_IntensityImageFileNames[m_ImageCounter].find(".xml") != std::string::npos)
627  {
628  grayImage = (IplImage*) cvLoad(m_IntensityImageFileNames[m_ImageCounter].c_str());
629  releaseNecessary = true;
630  }
631  else if ((m_IntensityImageFileNames[m_ImageCounter].find(".png") != std::string::npos) || (m_IntensityImageFileNames[m_ImageCounter].find(".bmp") != std::string::npos) ||
632  (m_IntensityImageFileNames[m_ImageCounter].find(".jpg") != std::string::npos))
633  {
634  grayMat = cv::imread(m_IntensityImageFileNames[m_ImageCounter], -1);
635  grayIpl = (IplImage)grayMat;
636  }
637  else
638  {
639  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:\n";
640  std::cerr << "\t ... Wrong file format for file " << m_IntensityImageFileNames[m_ImageCounter] << ".\n";
641  CV_Assert(false);
642  }
643  }
644  else
645  {
646  // amplitude image
647  if (m_AmplitudeImageFileNames[m_ImageCounter].find(".bin") != std::string::npos)
648  {
650  grayIpl = (IplImage)grayMat;
651  }
652  else if (m_AmplitudeImageFileNames[m_ImageCounter].find(".xml") != std::string::npos)
653  {
654  grayImage = (IplImage*) cvLoad(m_AmplitudeImageFileNames[m_ImageCounter].c_str());
655  releaseNecessary = true;
656  }
657  else
658  {
659  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:\n";
660  std::cerr << "\t ... Wrong file format for file " << m_AmplitudeImageFileNames[m_ImageCounter] << ".\n";
661  CV_Assert(false);
662  }
663  }
664 
665  // process image
666  if (!undistort)
667  {
668  if (grayImageType == ipa_CameraSensors::INTENSITY_8U3)
669  {
670  for(unsigned int row=0; row<(unsigned int)m_ImageHeight; row++)
671  {
672  f_ptr = (float*) (grayImage->imageData + row*grayImage->widthStep);
673  f_ptr_dst = (float*) (grayImageData + row*widthStepGray);
674 
675  for (unsigned int col=0; col<(unsigned int)m_ImageWidth; col++)
676  {
677  f_ptr_dst[col] = f_ptr[col];
678  }
679  }
680  }
681  else
682  {
683  for(unsigned int row=0; row<(unsigned int)m_ImageHeight; row++)
684  {
685  uc_ptr = (unsigned char*) (grayImage->imageData + row*grayImage->widthStep);
686  uc_ptr_dst = (unsigned char*) (grayImageData + row*widthStepGray);
687 
688  for (unsigned int col=0; col<(unsigned int)m_ImageWidth; col++)
689  {
690  uc_ptr_dst[col] = uc_ptr[col];
691  }
692  }
693  }
694  }
695  else
696  {
697  cv::Mat undistortedData;
698  if (grayImageType == ipa_CameraSensors::INTENSITY_8U3)
699  {
700  undistortedData = cv::Mat(m_ImageHeight, m_ImageWidth, CV_8UC3, (unsigned char*) grayImageData);
701  }
702  else
703  {
704  undistortedData = cv::Mat(m_ImageHeight, m_ImageWidth, CV_32FC1, (float*) grayImageData);
705  }
706  cv::Mat cpp_grayImage = grayImage;
707 
708  assert (!m_undistortMapX.empty() && !m_undistortMapY.empty());
709  cv::remap(cpp_grayImage, undistortedData, m_undistortMapX, m_undistortMapY, cv::INTER_LINEAR);
710  }
711 
712  if (releaseNecessary) cvReleaseImage(&grayImage);
713  }
715 // Cartesian image (always undistorted)
717  if(cartesianImageData)
718  {
719  float x = -1;
720  float y = -1;
721  float zCalibrated = -1;
722  float* f_ptr = 0;
723  float* f_ptr_dst = 0;
724  bool releaseNecessary = false;
725 
727  {
728  CV_Assert(false);
729  }
731  {
732  // XYZ image is assumed to be undistorted
733  // Unfortunately we have no access to the swissranger calibration
734 
735  cv::Mat coordinateMat;
736  IplImage coordinateIpl;
737  IplImage* coordinateImage = &coordinateIpl;
738  if (m_CoordinateImageFileNames[m_ImageCounter].find(".bin") != std::string::npos)
739  {
741  coordinateIpl = (IplImage)coordinateMat;
742  }
743  else if (m_CoordinateImageFileNames[m_ImageCounter].find(".xml") != std::string::npos)
744  {
745  coordinateImage = (IplImage*) cvLoad(m_CoordinateImageFileNames[m_ImageCounter].c_str(), 0);
746  releaseNecessary = true;
747  }
748  else
749  {
750  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:\n";
751  std::cerr << "\t ... Wrong file format for file " << m_CoordinateImageFileNames[m_ImageCounter] << ".\n";
752  CV_Assert(false);
753  }
754 
755  for(unsigned int row=0; row<(unsigned int)m_ImageHeight; row++)
756  {
757  f_ptr = (float*) (coordinateImage->imageData + row*coordinateImage->widthStep);
758  f_ptr_dst = (float*) (cartesianImageData + row*widthStepCartesian);
759 
760  for (unsigned int col=0; col<(unsigned int)m_ImageWidth; col++)
761  {
762  int colTimes3 = 3*col;
763 
764  zCalibrated = f_ptr[colTimes3+2];
765  GetCalibratedXYMatlab(col, row, zCalibrated, x, y);
766 
767  f_ptr_dst[colTimes3] = x;
768  f_ptr_dst[colTimes3 + 1] = y;
769  f_ptr_dst[colTimes3 + 2] = zCalibrated;
770 
771  if (f_ptr_dst[colTimes3 + 2] < 0)
772  {
773  std::cout << "<0: " << row << " " << col << "\n";
774  }
775  }
776  }
777  if (releaseNecessary) cvReleaseImage(&coordinateImage);
778  }
779  else if(m_CalibrationMethod==NATIVE)
780  {
781  cv::Mat coordinateMat;
782  IplImage coordinateIpl;
783  IplImage* coordinateImage = &coordinateIpl;
784  if (m_CoordinateImageFileNames[m_ImageCounter].find(".bin") != std::string::npos)
785  {
787  coordinateIpl = (IplImage)coordinateMat;
788  }
789  else if (m_CoordinateImageFileNames[m_ImageCounter].find(".xml") != std::string::npos)
790  {
791  coordinateImage = (IplImage*) cvLoad(m_CoordinateImageFileNames[m_ImageCounter].c_str(), 0);
792  releaseNecessary = true;
793  }
794  else
795  {
796  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:\n";
797  std::cerr << "\t ... Wrong file format for file " << m_CoordinateImageFileNames[m_ImageCounter] << ".\n";
798  CV_Assert(false);
799  }
800 
801  for(unsigned int row=0; row<(unsigned int)m_ImageHeight; row++)
802  {
803  f_ptr = (float*) (coordinateImage->imageData + row*coordinateImage->widthStep);
804  f_ptr_dst = (float*) (cartesianImageData + row*widthStepCartesian);
805 
806  for (unsigned int col=0; col<(unsigned int)m_ImageWidth; col++)
807  {
808  int colTimes3 = 3*col;
809 
810  f_ptr_dst[colTimes3] =f_ptr[colTimes3+0];;
811  f_ptr_dst[colTimes3 + 1] = f_ptr[colTimes3+1];
812  f_ptr_dst[colTimes3 + 2] = f_ptr[colTimes3+2];
813  }
814  }
815  if (releaseNecessary) cvReleaseImage(&coordinateImage);
816  }
817  else
818  {
819  std::cerr << "ERROR - VirtualRangeCam::AcquireImages:" << std::endl;
820  std::cerr << "\t ... Calibration method unknown.\n";
821  return RET_FAILED;
822  }
823  }
824 
825  std::cout << m_ImageCounter << " \r" << std::endl;
826  m_ImageCounter++;
827  if ((m_IntensityImageFileNames.size() != 0 && m_ImageCounter >= m_IntensityImageFileNames.size()) ||
829  (m_RangeImageFileNames.size() != 0 && m_ImageCounter >= m_RangeImageFileNames.size()) ||
831  {
832  // Reset image counter
833  m_ImageCounter = 0;
834  }
835 
836  return RET_OK;
837 }
838 
840 {
841  if (m_IntensityImageFileNames.size() == 0 &&
842  m_AmplitudeImageFileNames.size() == 0 &&
843  m_RangeImageFileNames.size() == 0 &&
844  m_CoordinateImageFileNames.size() == 0)
845  {
846  return 0;
847  }
848 
849  int min=std::numeric_limits<int>::max();
850 
851  if (m_IntensityImageFileNames.size() != 0) min = (int)std::min((float)min, (float)m_IntensityImageFileNames.size());
852  if (m_AmplitudeImageFileNames.size() != 0) min = (int)std::min((float)min, (float)m_AmplitudeImageFileNames.size());
853  if (m_RangeImageFileNames.size() != 0) min = (int)std::min((float)min, (float)m_RangeImageFileNames.size());
854  if (m_CoordinateImageFileNames.size() != 0) min = (int)std::min((float)min, (float)m_CoordinateImageFileNames.size());
855 
856  return min;
857 }
858 
859 unsigned long VirtualRangeCam::SetPathToImages(std::string path)
860 {
861  m_CameraDataDirectory = path;
862  return ipa_Utils::RET_OK;
863 }
864 
865 unsigned long VirtualRangeCam::SaveParameters(const char* filename)
866 {
868 }
869 
870 
871 // Assert, that <code>m_CoeffsA.size()</code> and <code>m_CoeffsB.size()</code> is initialized
872 // Before calling <code>GetCalibratedZMatlab</code>
873 unsigned long VirtualRangeCam::GetCalibratedZMatlab(int u, int v, float zRaw, float& zCalibrated)
874 {
875  double c[7] = {m_CoeffsA0.at<double>(v,u), m_CoeffsA1.at<double>(v,u), m_CoeffsA2.at<double>(v,u),
876  m_CoeffsA3.at<double>(v,u), m_CoeffsA4.at<double>(v,u), m_CoeffsA5.at<double>(v,u), m_CoeffsA6.at<double>(v,u)};
877  double y = 0;
878 
879  ipa_Utils::EvaluatePolynomial((double) zRaw, 6, &c[0], &y);
880 
881  zCalibrated = (float) y;
882  return RET_OK;
883 }
884 
885 unsigned long VirtualRangeCam::GetCalibratedXYMatlab(int u, int v, float z, float& x, float& y)
886 {
887  // Conversion form m to mm
888  z *= 1000;
889 
890  // Use intrinsic camera parameters
891  double fx, fy, cx, cy;
892 
893  fx = m_intrinsicMatrix.at<double>(0, 0);
894  fy = m_intrinsicMatrix.at<double>(1, 1);
895 
896  cx = m_intrinsicMatrix.at<double>(0, 2);
897  cy = m_intrinsicMatrix.at<double>(1, 2);
898 
899  // Fundamental equation: u = (fx*x)/z + cx
900  if (fx == 0)
901  {
902  std::cerr << "VirtualRangeCam::GetCalibratedXYMatlab:" << std::endl;
903  std::cerr << "\t ... fx is 0.\n";
904  return RET_FAILED;
905  }
906  x = (float) (z*(u-cx)/fx) ;
907 
908  // Fundamental equation: v = (fy*y)/z + cy
909  if (fy == 0)
910  {
911  std::cerr << "VirtualRangeCam::GetCalibratedXYMatlab:" << std::endl;
912  std::cerr << "\t ... fy is 0.\n";
913  return RET_FAILED;
914  }
915  y = (float) (z*(v-cy)/fy);
916 
917  // Conversion from mm to m
918  x /= 1000;
919  y /= 1000;
920 
921  return RET_OK;
922 }
923 
924 unsigned long VirtualRangeCam::GetCalibratedUV(double x, double y, double z, double& u, double& v)
925 {
927  {
928  double fx, fy, cx, cy;
929  fx = m_intrinsicMatrix.at<double>(0, 0);
930  fy = m_intrinsicMatrix.at<double>(1, 1);
931 
932  cx = m_intrinsicMatrix.at<double>(0, 2);
933  cy = m_intrinsicMatrix.at<double>(1, 2);
934 
935  // Conversion from m to mm
936  x *= 1000;
937  y *= 1000;
938  z *= 1000;
939 
940  // Fundamental equation: u = (fx*x)/z + cx
941  if (z == 0)
942  {
943  std::cerr << "ERROR - VirtualRangeCam::GetCalibratedUV:" << std::endl;
944  std::cerr << "\t ... z is 0.\n";
945  return RET_FAILED;
946  }
947 
948  u = (fx*x)/z + cx;
949  v = (fy*y)/z + cy;
950  }
951  else if(m_CalibrationMethod==NATIVE)
952  {
953  // implement me
954  std::cerr << "ERROR - VirtualRangeCam::GetCalibratedUV:" << std::endl;
955  std::cerr << "\t ... Function not implemented.\n";
956  return RET_FAILED;
957  }
958 
959  // Maybe skip this part... JBK skipped this - the calling function has to check!!
960 
961  if(u<0) u=0;
962  if(u>=m_ImageWidth) u=m_ImageWidth-1;
963  if(v<0) v=0;
964  if(v>=m_ImageHeight) v=m_ImageHeight-1;
965 
966  return RET_OK;
967 }
968 
969 unsigned long VirtualRangeCam::LoadParameters(const char* filename, int cameraIndex)
970 {
971  // Load SwissRanger parameters.
972  boost::shared_ptr<TiXmlDocument> p_configXmlDocument (new TiXmlDocument( filename ));
973 
974  if (!p_configXmlDocument->LoadFile())
975  {
976  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
977  std::cerr << "\t ... Error while loading xml configuration file" << std::endl;
978  std::cerr << "\t ...(Check filename and syntax):" << std::endl;
979  std::cerr << "\t ... " << filename << std::endl;
980  return (RET_FAILED | RET_FAILED_OPEN_FILE);
981  }
982  std::cout << "INFO - VirtualRangeCam::LoadParameters:" << std::endl;
983  std::cout << "\t ... Parsing xml configuration file" << std::endl;
984  std::cout << "\t ... '" << filename << "'" << std::endl;
985 
986  if ( p_configXmlDocument )
987  {
988 
989 //************************************************************************************
990 // BEGIN LibCameraSensors
991 //************************************************************************************
992  // Tag element "LibCameraSensors" of Xml Inifile
993  TiXmlElement *p_xmlElement_Root = NULL;
994  p_xmlElement_Root = p_configXmlDocument->FirstChildElement( "LibCameraSensors" );
995 
996  if ( p_xmlElement_Root )
997  {
998 
999 //************************************************************************************
1000 // BEGIN LibCameraSensors->VirtualRangeCam
1001 //************************************************************************************
1002  // Tag element "VirtualRangeCam" of Xml Inifile
1003  TiXmlElement *p_xmlElement_Root_VirtualRangeCam = NULL;
1004  std::stringstream ss;
1005  ss << "VirtualRangeCam_" << cameraIndex;
1006  p_xmlElement_Root_VirtualRangeCam = p_xmlElement_Root->FirstChildElement( ss.str() );
1007  if ( p_xmlElement_Root_VirtualRangeCam )
1008  {
1009 
1010 //************************************************************************************
1011 // BEGIN LibCameraSensors->VirtualRangeCam->CameraDataDirectory
1012 //************************************************************************************
1013  // Subtag element "IntrinsicParameters" of Xml Inifile
1014  TiXmlElement *p_xmlElement_Child = NULL;
1015  p_xmlElement_Child = p_xmlElement_Root_VirtualRangeCam->FirstChildElement( "CameraDataDirectory" );
1016  if ( p_xmlElement_Child )
1017  {
1018  // read and save value of attribute
1019  std::string tempString;
1020  if ( p_xmlElement_Child->QueryValueAttribute( "relativePath", &tempString ) != TIXML_SUCCESS)
1021  {
1022  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1023  std::cerr << "\t ... Can't find attribute 'relativePath' of tag 'CameraDataDirectory'." << std::endl;
1025  }
1026 
1027  m_CameraDataDirectory = m_CameraDataDirectory + tempString + "/";
1028  }
1029  else
1030  {
1031  std::cerr << "ERROR - VirtualColorCam::LoadParameters:" << std::endl;
1032  std::cerr << "\t ... Can't find tag 'CameraDataDirectory'." << std::endl;
1033  return (RET_FAILED | RET_XML_TAG_NOT_FOUND);
1034  }
1035 
1036 //************************************************************************************
1037 // BEGIN LibCameraSensors->VirtualRangeCam->CalibrationMethod
1038 //************************************************************************************
1039  // Subtag element "OperationMode" of Xml Inifile
1040  p_xmlElement_Child = NULL;
1041  p_xmlElement_Child = p_xmlElement_Root_VirtualRangeCam->FirstChildElement( "CalibrationMethod" );
1042  std::string tempString;
1043  if ( p_xmlElement_Child )
1044  {
1045  // read and save value of attribute
1046  if ( p_xmlElement_Child->QueryValueAttribute( "name", &tempString ) != TIXML_SUCCESS)
1047  {
1048  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1049  std::cerr << "\t ... Can't find attribute 'name' of tag 'CalibrationMethod'." << std::endl;
1051  }
1052  if (tempString == "MATLAB") m_CalibrationMethod = MATLAB;
1053  else if (tempString == "MATLAB_NO_Z") m_CalibrationMethod = MATLAB_NO_Z;
1054  else if (tempString == "NATIVE") m_CalibrationMethod = NATIVE;
1055  else
1056  {
1057  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1058  std::cerr << "\t ... Calibration mode " << tempString << " unspecified." << std::endl;
1059  return (RET_FAILED);
1060  }
1061  }
1062  else
1063  {
1064  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1065  std::cerr << "\t ... Can't find tag 'CalibrationMethod'." << std::endl;
1066  return (RET_FAILED | RET_XML_TAG_NOT_FOUND);
1067  }
1068  }
1069 //************************************************************************************
1070 // END LibCameraSensors->VirtualRangeCam
1071 //************************************************************************************
1072  else
1073  {
1074  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1075  std::cerr << "\t ... Can't find tag '" << ss.str() << "'" << std::endl;
1076  return (RET_FAILED | RET_XML_TAG_NOT_FOUND);
1077  }
1078  }
1079 
1080 //************************************************************************************
1081 // END LibCameraSensors
1082 //************************************************************************************
1083  else
1084  {
1085  std::cerr << "ERROR - VirtualRangeCam::LoadParameters:" << std::endl;
1086  std::cerr << "\t ... Can't find tag 'LibCameraSensors'." << std::endl;
1087  return (RET_FAILED | RET_XML_TAG_NOT_FOUND);
1088  }
1089  }
1090 
1091  std::cout << "\t ... Parsing xml calibration file ... [OK] \n";
1092 
1093  return RET_OK;
1094 }
std::vector< std::string > m_AmplitudeImageFileNames
cv::Mat m_intrinsicMatrix
Intrinsic parameters [fx 0 cx; 0 fy cy; 0 0 1].
cv::Mat m_CoeffsA4
a4 z-calibration parameters. One matrix entry corresponds to one pixel
t_CalibrationMethod m_CalibrationMethod
Calibration method MATLAB, MATLAB_NO_Z or SWISSRANGER.
unsigned long GetCalibratedXYMatlab(int u, int v, float z, float &x, float &y)
unsigned long SetPathToImages(std::string path)
unsigned long LoadParameters(const char *filename, int cameraIndex)
cv::Mat m_CoeffsA3
a3 z-calibration parameters. One matrix entry corresponds to one pixel
unsigned long SaveParameters(const char *filename)
__DLL_LIBCAMERASENSORS__ AbstractRangeImagingSensorPtr CreateRangeImagingSensor_VirtualCam()
unsigned long LoadMat(cv::Mat &mat, std::string filename, int type=CV_32F)
void FindSourceImageFormat(std::map< std::string, int >::iterator &itCounter, std::string &ext)
unsigned long Init(std::string directory, int cameraIndex=0)
unsigned long GetCalibratedZMatlab(int u, int v, float zRaw, float &zCalibrated)
unsigned long AcquireImages(int widthStepRange, int widthStepGray, int widthStepCartesian, char *rangeImage=NULL, char *intensityImage=NULL, char *cartesianImage=NULL, bool getLatestFrame=true, bool undistort=true, ipa_CameraSensors::t_ToFGrayImageType grayImageType=ipa_CameraSensors::INTENSITY_32F1)
unsigned int m_BufferSize
Number of images, the camera buffers internally.
std::vector< std::string > m_IntensityImageFileNames
boost::shared_ptr< AbstractRangeImagingSensor > AbstractRangeImagingSensorPtr
cv::Mat m_undistortMapX
The output array of x coordinates for the undistortion map.
cv::Mat m_CoeffsA0
a0 z-calibration parameters. One matrix entry corresponds to one pixel
cv::Mat m_CoeffsA6
a6 z-calibration parameters. One matrix entry corresponds to one pixel
unsigned long GetCalibratedUV(double x, double y, double z, double &u, double &v)
cv::Mat m_CoeffsA2
a2 z-calibration parameters. One matrix entry corresponds to one pixel
cv::Mat m_CoeffsA1
a1 z-calibration parameters. One matrix entry corresponds to one pixel
unsigned int m_ImageCounter
Holds the index of the image that is extracted during the next call of AcquireImages ...
cv::Mat m_CoeffsA5
a5 z-calibration parameters. One matrix entry corresponds to one pixel
unsigned long EvaluatePolynomial(double x, int degree, double *coefficients, double *y)
cv::Mat m_undistortMapY
The output array of Y coordinates for the undistortion map.
int m_CameraIndex
Index of the specified camera. Important, when several cameras of the same type are present...
bool m_initialized
True, when the camera has sucessfully been initialized.
void UpdateImageDimensionsOnFirstImage(std::string filename, std::string ext=".xml")
std::vector< std::string > m_CoordinateImageFileNames
unsigned long GetProperty(t_cameraProperty *cameraProperty)
std::vector< std::string > m_RangeImageFileNames
unsigned long SetProperty(t_cameraProperty *cameraProperty)
std::string m_CameraDataDirectory
Directory where the image data resides.
#define __DLL_LIBCAMERASENSORS__
bool m_open
True, when the camera has sucessfully been opend.


cob_camera_sensors
Author(s): Jan Fischer , Richard Bormann
autogenerated on Thu Mar 19 2020 03:23:05