Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
VideoSource_PMDZess.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifndef WIN32
26 # error The PMD-cameras can only be run under windows.
27 #endif //not WIN32
28 
29 //THE header
30 #include "VideoSource_PMDZess.hh"
31 
32 //std stuff
33 #include <string>
34 #include <sstream>
35 #include <iostream>
36 
37 //BIAS stuff
38 #include <Image/Camera.hh>
39 
40 //PMD stuff
41 #include <PMDDll.h>
42 #include <defines.hpp>
43 
44 using namespace BIAS;
45 using namespace std;
46 
47 
49  : VideoSource()
50 {
51  //for VideoSource-class
52  VideoSource::SetSize(-1,-1,1);
54  Width_ = -1;
55  Height_ = -1;
56 
57  //own standards
59  use2D_ = 1;
60  doCalcs_ = 1;
61  phaseAlgorithm_ = 4;
63  bIsOpen_ = false;
64  devicePort_ = "USB0";
65  bitFile_ = "";
66  dist_ = NULL;
67  mod_ = NULL;
68  grey_ = NULL;
69  total_ = NULL;
70  grey2D_ = NULL;
71 }
72 
74 {
75  if (bIsOpen_) CloseDevice();
76 }
77 
79 {
80  if (bIsOpen_) {
81  BIASERR("Device has been opened allready!!!");
82  return -1;
83  }
84 
85  if (bitFile_ == "") {
86  BIASERR("No bitfile for PMDZess given!!!");
87  return -1;
88  }
89 
90  use2D_ = 0;
91  doCalcs_ = 1;
92  phaseAlgorithm_ = 4;
93 
94  //TODO: activate 2D-output -> set 2.param to 1 (docum. see PMDDll.h)
95  if (z2D3D_setChip(type_, use2D_, doCalcs_, phaseAlgorithm_)<0) {
96  BIASERR("Connection to PMD-Camera via USB failed!");
97  return -1;
98  }
99 
100  //first param ?will get? used, if more than one cam is attaced via USB (N/A now)!
101  //Parameter NULL is passed for standard phase-shifts! (consult docs before using)
102  int ret = z2D3D_init(devicePort_.c_str(), bitFile_.c_str(), type_, use2D_,
103  modulationsFrequenz_, 0, doCalcs_, phaseAlgorithm_);
104  if ( ret < 0) {
105  char message[200];
106  int errorcode=0;
107  ret = z2D3D_getlasterror(message, 200,&errorcode);
108  cout<<"Error:"<<message<<endl;
109  BIASERR("Error initializing camera!!!"<<ret);
110  return -1;
111  }
112 
113 
114  switch(type_) {
115  case PMD_1K :
116  Width_ = 64;
117  Height_ = 16;
118  break;
119  case PMD_3K :
120  Width_ = 64;
121  Height_ = 48;
122  break;
123  case MultiCam_3K :
124  Width_ = 64;
125  Height_ = 48;
126  //addept to new vals when 2d-imaging is supported
127  Width2D_ = 640;
128  Height2D_ = 480;
129  break;
130  case MultiCam_19K :
131  Width_ = 160;
132  Height_ = 120;
133  //addept to new vals when 2d-imaging is supported
134  Width2D_ = 640;
135  Height2D_ = 480;
136  break;
137  default:
138  BIASERR("???Unknown PMD-type but init(...) succeeded???");
139  return -1;
140  }
141 
142  //set 3D-exposuretime to 2[ms] (= 2/(999 + 1) * 1000)
143  z2D3D_setexpo( 2, 999,1);
144  //set 2D-exposuretime to 5,1[ms] ( = 5ms * frametime(=1) + 10µs * rowtime(=10) )
145  z2D3D_SetExposureTimeInMS_2D( 10, 1,999 );
146 
147  //set standard application mode
148  if (z2D3D_SetApplicationMode(1) < 0) {
149  BIASERR("Error setting application-mode 1!!!");
150  //needed if OpenDevice was not completed
151  if (z2D3D_deinit() < 0)
152  BIASERR("Disonnection of PMD-Camera via USB failed!");
153 
154  return -1;
155  }
156 
157  //don't mirror/rotate anything CAUTION This is bitwise setting!
158  unsigned long mirrorRotOpts = 0;
159  if (z2D3D_MirrorRotOpts(&mirrorRotOpts , 1) < 0) {
160  BIASERR("Error setting mirror-modes to none!!!");
161  //needed if OpenDevice was not completed
162  if (z2D3D_deinit() < 0)
163  BIASERR("Disonnection of PMD-Camera via USB failed!");
164 
165  return -1;
166  }
167 
168  //activate metric depth-image
169  if (z2D3D_Scale(1) < 0) {
170  BIASERR("Error activating metric depth-output!!!");
171  //needed if OpenDevice was not completed
172  if (z2D3D_deinit() < 0)
173  BIASERR("Disonnection of PMD-Camera via USB failed!");
174 
175  return -1;
176  }
177 
178  //prepare mem for one image (processing image by image)
179  if (z2D3D_Prepare(1) < 0) {
180  BIASERR("Error reserving memory for PMD-library!!!");
181  //needed if OpenDevice was not completed
182  if (z2D3D_deinit() < 0)
183  BIASERR("Disonnection of PMD-Camera via USB failed!");
184 
185  return -1;
186  }
187 
188  dist_ = new double[Width_*Height_*ColorChannels_]; //depth image
189  mod_ = new double[Width_*Height_*ColorChannels_]; //Coefficient image
190  grey_ =
191  new signed short[Width_*Height_*ColorChannels_]; //PMD-grey image
192  total_ =
193  new signed short[((Width_*Height_+4)*2)*phaseAlgorithm_]; //not needed (raw img data)
194  grey2D_ =
195  new unsigned char[Width2D_*Height2D_*ColorChannels_]; //high res grey image
196 
197  if ((dist_ == NULL)||(mod_ == NULL)||(grey_ == NULL)||
198  (total_ == NULL)||(grey2D_ == NULL))
199  {
200  BIASERR("Error allocating memory for temp-images!!!");
201  //needed if OpenDevice was not completed
202  if (z2D3D_deinit() < 0)
203  BIASERR("Disonnection of PMD-Camera via USB failed!");
204 
205  return -1;
206  }
207 
208  //MIP 2D-grey image (not filled right now, templated <unsigned char>)
209  img2DPMD_.Init(Width_, Height_, ColorChannels_, ImageBase::ST_unsignedchar);
210  img2DPMD_.SetColorModel(ImageBase::CM_Grey);
211  //MIP depth image (templated <float>)
212  DepthImg_.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
213  DepthImg_.SetColorModel(ImageBase::CM_Grey);
214  //MIP image holding Modulation-Coeefincients (templated <float>)
215  ModCoeffImg_.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
216  ModCoeffImg_.SetColorModel(ImageBase::CM_Grey);
217  imgPMD2D_.Init(Width2D_, Height2D_, ColorChannels_, ImageBase::ST_unsignedchar);
218  imgPMD2D_.SetColorModel(ImageBase::CM_Grey);
219  bIsOpen_ = true;
220 
221  return 0;
222 }
223 
225 {
226  //set string for desired port
227  std::stringstream str("USB");
228  str << camNr;
229  devicePort_ = str.str();
230  //call standard open
231  return OpenDevice();
232 }
233 
235 {
236  if (!bIsOpen_) {
237  BIASERR("Cannot close device, it has not been opened successfully!!!");
238  return -1;
239  }
240 
241  if (z2D3D_deinit() < 0) {
242  BIASERR("Disonnection of PMD-Camera via USB failed!");
243  return -1;
244  }
245 
246  delete dist_; //depth image
247  delete mod_; //Coefficient image
248  delete grey_; //PMD-grey image
249  delete total_; //not needed (raw img data)
250  delete grey2D_; //high resolution 2D image
251 
252  bIsOpen_ = false;
253 
254  return 0;
255 }
256 
258 {
259  return 0;
260 }
261 
262 
264 {
265  return 0;
266 }
267 
269  if (!img.IsEmpty()){
270  BIASERR("VideoSource::InitImage() should be called with uninitialized image");
271  img.Release();
272  }
273  img.Init(Width_, Height_, ColorChannels_, ImageBase::ST_unsignedchar);
275  return 0;
276 }
277 
279  if (!img.IsEmpty()){
280  BIASERR("VideoSource::InitImage() should be called with uninitialized image");
281  img.Release();
282  }
283  img.Init(Width2D_, Height2D_, ColorChannels_, ImageBase::ST_unsignedchar);
285  return 0;
286 }
287 
288 
290  unsigned long f = (unsigned long)(dModulationFrequency);
291  //return z2D3D_ModulationFrequency(&f, 1);
292  modulationsFrequenz_ = f;
293  return 0;
294 }
295 
296 
298 // unsigned long f;
299  //int res = z2D3D_ModulationFrequency(&f, 0);
300  ////check fo errors
301  //if (res <= 0) return res;
302  ////everything's fine, return
303  //return (int)(f);
304  return modulationsFrequenz_;
305 }
306 
307 
309  //exptime [ms] = value * (prescaler + 1) / 1000 --> some conversion needed
310  unsigned long value, prescaler;
311  prescaler = 999;
312  //value = (unsigned long)(1000.0 * double(exptime));
313  value =(unsigned long)exptime;
314 
315  return z2D3D_setexpo(value, prescaler, value);
316 }
317 
319  unsigned long *value = new unsigned long;
320  unsigned long *value2 = new unsigned long;
321  unsigned long *prescaler = new unsigned long;
322  //get values from lib
323  if (z2D3D_getexpo(value, prescaler, value2) < 0)
324  BIASERR("Error getting shutter from cam!");
325 
326  //convert integer values to exposuretime in sec.
327  float res = float(*value) * (float(*prescaler) + 1.0f) / 1000.0f;
328 
329  delete value;
330  delete value2;
331  delete prescaler;
332  return res;
333 }
334 
336  //exptime [ms] = 5ms * frametime + 10µs * rowtime --> some conversion needed
337  unsigned long rowtime, frametime;
338  unsigned long tmp = (unsigned long)(exptime * 1000.0);
339  tmp %= 5000;
340  rowtime = (unsigned long)(rint(tmp/10.0));
341  frametime = (unsigned long)(exptime) / 5;
342  //correct for rowtime ==0 and ==1
343  if(rowtime <=1)
344  {
345  rowtime = 2;
346  }
347  //frametime = (unsigned long)exptime;
348  //rowtime = 10;
349  cout<<"Setting rowtime:"<<rowtime<<" frametime:"<<frametime<<endl;
350  int ret = z2D3D_SetExposureTimeInMS_2D(rowtime, frametime, 999);
351  if(ret != 0){
352  char message[200];
353  int errorcode=0;
354  ret = z2D3D_getlasterror(message, 200, &errorcode);
355  cout<<"Error:"<<message<<endl;
356  }
357  return ret;
358 }
359 
361  //exptime [ms] = 5ms * frametime + 10µs * rowtime --> some conversion needed
362  unsigned long *rowtime = new unsigned long;
363  unsigned long *frametime = new unsigned long;
364  unsigned long *prescaler = new unsigned long;
365  if (z2D3D_GetExposureTimeInMS_2D(rowtime, frametime, prescaler) < 0){
366  BIASERR("Error getting shutter from 2D-cam!");
367  char message[200];
368  int errorcode=0;
369  z2D3D_getlasterror(message, 200,&errorcode);
370  cout<<"Error:"<<message<<endl;
371  return -1;
372  }
373  cout<<"getting rowtime:"<<*rowtime<<" frametime:"<<*frametime<<endl;
374  //convert integer values to exposuretime in sec.
375  float res = float(*frametime) * 5.0f + 0.01f * float(*rowtime);
376 
377  delete rowtime;
378  delete frametime;
379  delete prescaler;
380  return res;
381 }
382 
384 {
385  unsigned long gainUL = (unsigned long)gain;
386  int ret = z2D3D_SetGain2D(gainUL,gainUL,gainUL,gainUL,gainUL);
387  return ret;
388 }
389 
391  unsigned long * gain = new unsigned long;
392  unsigned long * gainblue= new unsigned long;
393  unsigned long * gainred= new unsigned long;
394  unsigned long * gaingreen1= new unsigned long;
395  unsigned long * gaingreen2= new unsigned long;
396  int ret = z2D3D_GetGain2D(gain,gainblue,gainred,gaingreen1,gaingreen2);
397 
398  delete gain;
399  delete gainblue;
400  delete gainred;
401  delete gaingreen1;
402  delete gaingreen2;
403  float result = (float)(*gain);
404  return result;
405 }
406 
408  //(ImageNr from the container, 0 for phase image 1 for 2D image)
409  int res = z2D3D_CalcSinglePhase(0);
410 
411  res = z2D3D_Do(-1);
412  /* nr index of the image in memory which shall be transfered
413  Phasenr the phase for which you'd like to get the information for (-1..-4 or 7,1,5,3 etc.)
414  raw pointer to a field reserved for the raw data of the phase, may be zero, then data is not copied
415  expA may be zero, else expA is copied here
416  expB may be zero, else expB is copied here
417  pre may be zero, else pre is copied here
418  framecounter may be zero, else framecounter is copied here
419  realtimeclock may be zero, else realtimeclock is copied here*/
420 
421  signed short *raw;// *expA, *expB, *pre, *phase, *framecounter;
422  raw = new signed short[Width_*Height_*ColorChannels_];
423  //expA = new short[Width_*Height_*ColorChannels_];
424  //expB = new short[Width_*Height_*ColorChannels_];
425  //pre = new short[Width_*Height_*ColorChannels_];
426  //phase = new short[Width_*Height_*ColorChannels_];
427  //framecounter = new short;
428  //int *realtimeclock = new int;
429  res = z2D3D_Fetch1(0,-1,raw,0,0,0,0,0,0);
430  /*delete realtimeclock;
431  */
432  return res;
433 }
434 
436 {
437  int res=0;
438 
439  //clac next image (-1 for all stored imgs)
440  if (z2D3D_Do(-1) < 0) {
441  BIASERR("Error calculating next image!!!");
442  return -1;
443  }
444 
445  //get next image (index 0 in memory)
446  res = z2D3D_Fetch(0, dist_, mod_, grey_, total_, grey2D_);
447 
448  if (res < 0) {
449  BIASERR("Error getting image data from PMD-lib!!!");
450  return res;
451  }
452 
453  //convert from double/short to float/unsigned char
454  DepthImageFloatFromDouble_(dist_, DepthImg_);
455  ImageFloatFromDouble_(mod_, ModCoeffImg_);
456  ImageUcharFromShort_(grey_, image);
457  Convert2DImage_(grey2D_,img2D_);
458  return 0;
459 }
460 
463 {
464  if (dst.IsEmpty()) {
465  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_unsignedchar);
466  }
467 
468  double* pus=data;
469  double min = DBL_MAX;
470  double max = DBL_MIN;
471  for (unsigned int i=0; i<dst.GetWidth()*dst.GetHeight(); i++) {
472  if (*pus<min) min = *pus;
473  if (*pus>max) max = *pus;
474  pus++;
475  }
476  double divisor = max - min;
477 
478  pus=data;
479  if (divisor != 0) {
480  unsigned char** puc=dst.GetImageDataArray();
481  for (unsigned int y=0; y<dst.GetHeight(); y++) {
482  for (int x=0; x<int(dst.GetWidth()); x++) {
483  puc[y][int(dst.GetWidth())-1-x] =
484  (unsigned char)(255.0*((*pus)-min)/divisor);
485  pus++;
486  }
487  }
488  } else {
489  dst.SetZero();
490  }
491 }
492 
495 {
496  if (dst.IsEmpty()) {
497  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_unsignedchar);
498  }
499 
500  signed short* pus=data;
501  signed short min = *pus;
502  signed short max = *pus;
503  for (unsigned int i=0; i<dst.GetWidth()*dst.GetHeight(); i++) {
504  if (*pus<min) min = *pus;
505  if (*pus>max) max = *pus;
506  pus++;
507  }
508  double divisor = double(max - min);
509 
510  pus=data;
511  if (divisor != 0) {
512  unsigned char** puc=dst.GetImageDataArray();
513  for (unsigned int y=0; y<dst.GetHeight(); y++) {
514  for (int x=0; x<int(dst.GetWidth()); x++) {
515  puc[y][int(dst.GetWidth())-1-x] =
516  (unsigned char)(255.0*(double(*pus)-min)/divisor);
517  pus++;
518  }
519  }
520  } else {
521  dst.SetZero();
522  }
523 }
524 
526  Image<float> &dst)
527 {
528  if (dst.IsEmpty()) {
529  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
530  }
531  double f = 20000000.0;
532  double c = 299792458.0*1000.0;
533  float m = float(c/f/2);
534  double* pus=data;
535  float** puc=dst.GetImageDataArray();
536  for (unsigned int y=0; y<dst.GetHeight(); y++) {
537  for (int x=0; x<int(dst.GetWidth()); x++) {
538  puc[y][int(dst.GetWidth())-1-x] = (float)(*pus);
539  while(puc[y][int(dst.GetWidth())-1-x]<0.0){
540  puc[y][int(dst.GetWidth())-1-x]+=m;
541  }
542  while(puc[y][int(dst.GetWidth())-1-x]>m){
543  puc[y][int(dst.GetWidth())-1-x]-=m;
544  }
545  pus++;
546  }
547  }
548 }
549 
550 
552  Image<float> &dst)
553 {
554  if (dst.IsEmpty()) {
555  dst.Init(Width_, Height_, ColorChannels_, ImageBase::ST_float);
556  }
557 
558  double* pus=data;
559  float** puc=dst.GetImageDataArray();
560  for (unsigned int y=0; y<dst.GetHeight(); y++) {
561  for (int x=0; x<int(dst.GetWidth()); x++) {
562  puc[y][int(dst.GetWidth())-1-x] = (float)(*pus);
563  pus++;
564  }
565  }
566 }
567 
568 
571 {
572  if (dst.IsEmpty()) {
573  dst.Init(Width2D_, Height2D_, ColorChannels_, ImageBase::ST_float);
574  }
575 
576  unsigned char* srcDatap=data;
577  unsigned char** dstData=dst.GetImageDataArray();
578  for (unsigned int y=0; y<dst.GetHeight(); y++) {
579  for (unsigned int x=0; x< dst.GetWidth(); x++) {
580  dstData[y][int(dst.GetWidth())-1-x] = (*srcDatap);
581  srcDatap++;
582  }
583  }
584 }
int SetGain2D(float g)
Set gain to g with g[dB].
virtual void SetSize(int w, int h, int bytesperpixel=1)
Set image size and number of bytes per pixel (e.g.
int SetModulationFrequency(int dModulationFrequency)
Defines a common interface to different devices.
gray values, 1 channel
Definition: ImageBase.hh:130
int CaptureSinglePhase(Camera< unsigned char > &image)
Capture a single phase image only.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
void Convert2DImage_(unsigned char *data, Image< unsigned char > &dst)
int SetShutter2D(float exptime)
Set shutter (exposure time) to exptime in seconds [==] for 2D-chip.
void SetColorModel(EColorModel Model)
Definition: ImageBase.hh:561
float image storage type
Definition: ImageBase.hh:118
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void DepthImageFloatFromDouble_(double *data, Image< float > &dst)
int Width_
Image format.
virtual int SetColorModel(BIAS::ImageBase::EColorModel mode)
Select colormodel to use.
virtual int PreGrab()
Do last preparations before grabbing (e.g. start ISO transfer)
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void ImageUcharFromDouble_(double *data, Image< unsigned char > &dst)
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
Definition: ImageBase.cpp:350
virtual int InitImage(ImageBase &img)
virtual int OpenDevice()
selects the first available device to open (e.g.
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
Definition: ImageBase.cpp:229
void ImageUcharFromShort_(signed short *data, Image< unsigned char > &dst)
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
virtual int GrabSingle(Camera< unsigned char > &image)
Returns the 2D image, and reads depth and modulation coefficients.
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
virtual int Init2DImage(ImageBase &img)
virtual int PostGrab()
Stop anything started in PreGrab()
void SetZero()
zeroes the image
Definition: ImageBase.hh:83
virtual int SetShutter3D(float exptime)
Set shutter (exposure time) to exptime in seconds [==] for PMD-chip.
void ImageFloatFromDouble_(double *data, Image< float > &dst)
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153