Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PMDImageProc.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 #include <Image/PMDImageProc.hh>
26 #include <Geometry/RMatrix.hh>
27 #include <Geometry/Projection.hh>
28 #include <Image/ProjectionMapping.hh>
29 #include <Image/HomographyMapping.hh>
30 #include <Base/Image/ImageIO.hh>
31 #include <Filter/Dilation.hh>
32 #include <Filter/Median.hh>
33 #include <bias_config.h>
34 #include <stdio.h>
35 #include <Base/Math/Random.hh>
36 #include <MathAlgo/SVD.hh>
37 #include <MathAlgo/Histogram1D.hh>
38 
39 using namespace BIAS;
40 using namespace std;
41 
43  const BIAS::Projection &proj2D,
44  const BIAS::Projection &projDepth,
45  int kernelsize)
46 {
47  Image<float> ImgDepthTo2D;
48  unsigned int depthWidth=0,depthHeight=0;
49  depthWidth= ImageDepth.GetWidth();
50  depthHeight= ImageDepth.GetHeight();
51 
52  unsigned int twoDWidth=0, twoDHeight=0;
53  proj2D.GetParameters()->GetImageSize(twoDWidth,twoDHeight);
54  ImgDepthTo2D.Init(twoDWidth,twoDHeight, 1);
55  ImgDepthTo2D.SetZero();
56 
57  float **idaDepth = ImageDepth.GetImageDataArray();
58  float **idaDepthTo2D = ImgDepthTo2D.GetImageDataArray();
59 
60  HomgPoint2D posOld(0,0,0), maxPosDiff(0,0,0);
61  double depthold=0;
62 
63  for (unsigned int x=0; x< depthWidth; x++) {
64  for (unsigned int y=0; y< depthHeight; y++) {
65  Vector3<double> p3D;
66  HomgPoint2D pos(x,y,1); // this is 2D point on depth image
67  float depth = idaDepth[y][x]; //depth value
68  if (depth>0.0) {
69  //now unproject to 3D point
70  p3D = projDepth.UnProjectToPoint(pos, depth);
71 
72  HomgPoint3D hp3D(p3D);
73  // now calculate the 2D point on 2D image
74  pos = proj2D.Project(hp3D);
75  unsigned int xx=(unsigned int)rintf(pos[0]);
76  unsigned int yy=(unsigned int)rintf(pos[1]);
77 
78  if (xx>=0 && xx < twoDWidth && yy >= 0 && yy < twoDHeight) {
79  idaDepthTo2D[yy][xx] = depth;
80 
81  if (y>0 && posOld.NormL2()>0 && fabs((depth-depthold)/depth)<0.001) {
82  if (maxPosDiff.NormL2()<(posOld-pos).NormL2()) {
83  maxPosDiff = posOld-pos;
84  }
85  }
86  posOld = pos;
87  depthold = depth;
88  } else {
89  posOld[0]=0;
90  posOld[1]=0;
91  posOld[2]=0;
92  depthold = 0;
93  }
94  } else {
95  depthold = 0;
96  }
97  }
98  posOld[0]=0;
99  posOld[1]=0;
100  posOld[2]=0;
101  }
102 
103  Image<float> res;
104  Dilation<float, float> dilation;
105 
106  //if no kernel size is given calculate the size
107  if(kernelsize == 0){
108  kernelsize=int(ceil(maxPosDiff.NormL2()));
109  if (kernelsize==0 || kernelsize>60) {
110  BIASERR("Calculation of Kernelsize did not work, calculated "
111  << kernelsize);
112  kernelsize=10;
113  } else {
114  kernelsize = kernelsize/2 +1;
115  }
116  }
117  cout<<"Kernelsize:"<<kernelsize<<endl;
118  dilation.SetKernelSize(kernelsize);
119  // kernelsize 3 wich is default is MUCH faster
121  dilation.Filter(ImgDepthTo2D,res);
122 
123  ImageDepth = res;
124 
125  return 0;
126 }
127 
128 
129 
130 
132  const PMDImageMetaData &MetaData2D,
133  PMDImageMetaData &MetaDataDepth)
134 {
135  Image<float> ImgMod;
136  int ret;
137  ImgMod = ImgDepth;
138  if (!Equal(MetaData2D.CameraCenter[0], MetaDataDepth.CameraCenter[0],1e-3) ||
139  !Equal(MetaData2D.CameraCenter[1], MetaDataDepth.CameraCenter[1],1e-3) ||
140  !Equal(MetaData2D.CameraCenter[2], MetaDataDepth.CameraCenter[2],1e-3))
141  {
142  ret = FitDepthTo2DImageFree_(ImgMod, ImgDepth, MetaData2D, MetaDataDepth);
143  } else {
144  if (!Equal(MetaData2D.CameraRotation[0],
145  MetaDataDepth.CameraRotation[0],1e-3) ||
146  !Equal(MetaData2D.CameraRotation[1],
147  MetaDataDepth.CameraRotation[1],1e-3) ||
148  !Equal(MetaData2D.CameraRotation[2],
149  MetaDataDepth.CameraRotation[2],1e-3))
150  {
151  ret = FitDepthTo2DImageHomogr_(ImgMod, MetaData2D, MetaDataDepth);
152  } else {
153  ret = FitDepthTo2DImageKOnly_(ImgMod, MetaData2D, MetaDataDepth);
154  }
155  }
156  ImgDepth = ImgMod;
157  return ret;
158 
159 }
160 
162  const Image<float> &ImgDepth,
163  const PMDImageMetaData &MetaData2D,
164  PMDImageMetaData &MetaDataDepth)
165 {
166  int ret;
167  if (!Equal(MetaData2D.CameraCenter[0], MetaDataDepth.CameraCenter[0],1e-3) ||
168  !Equal(MetaData2D.CameraCenter[1], MetaDataDepth.CameraCenter[1],1e-3) ||
169  !Equal(MetaData2D.CameraCenter[2], MetaDataDepth.CameraCenter[2],1e-3))
170  {
171  ret = FitDepthTo2DImageFree_(ImgModCoeff, ImgDepth,
172  MetaData2D, MetaDataDepth);
173  } else {
174  if (!Equal(MetaData2D.CameraRotation[0],
175  MetaDataDepth.CameraRotation[0],1e-3) ||
176  !Equal(MetaData2D.CameraRotation[1],
177  MetaDataDepth.CameraRotation[1],1e-3) ||
178  !Equal(MetaData2D.CameraRotation[2],
179  MetaDataDepth.CameraRotation[2],1e-3))
180  {
181  ret = FitDepthTo2DImageHomogr_(ImgModCoeff, MetaData2D, MetaDataDepth);
182  } else {
183  ret = FitDepthTo2DImageKOnly_(ImgModCoeff, MetaData2D, MetaDataDepth);
184  }
185  }
186  return ret;
187 }
188 
190  const PMDImageMetaData &MetaData2D,
191  PMDImageMetaData &MetaDataDepth)
192 {
194 
195  KMatrix K2D, KDepth;
196  K2D = KFromMeta(MetaData2D);
197  KDepth = KFromMeta(MetaDataDepth);
198 
199  HMatrix H = KDepth*K2D.Invert();;
200  int ret = 0;
201  if (!H.IsIdentity()) {
202  hm.SetHomography(H);
203  Image<float> mapto(MetaData2D.width, MetaData2D.height, 1);
204  ret = hm.Map(ImgToModify, mapto);
205  ImgToModify = mapto;
206  MetaDataDepth = MetaData2D;
207  } else ret = -1;
208  return ret;
209 }
210 
212  const Image<float> &ImgDepth,
213  const PMDImageMetaData &MetaData2D,
214  PMDImageMetaData &MetaDataDepth)
215 {
216  BIASWARN("This is only a rough approximation better performance in derived" <<
217  "class 'GLFilter/PMDImageProcGL' (class unimplemented ischiller 04/07)");
218  Projection proj2D, projDepth;
219  vector<double> undistDepth(4,0.0);
220  undistDepth[0] = MetaDataDepth.UndistCoeff[0];
221  undistDepth[1] = MetaDataDepth.UndistCoeff[1];
222  undistDepth[2] = MetaDataDepth.UndistCoeff[2];
223  undistDepth[3] = MetaDataDepth.UndistCoeff[3];
224 
225  vector<double> undist2D(4,0.0);
226  undist2D[0] =MetaData2D.UndistCoeff[0];
227  undist2D[1] =MetaData2D.UndistCoeff[1];
228  undist2D[2] =MetaData2D.UndistCoeff[2];
229  undist2D[3] =MetaData2D.UndistCoeff[3];
231 
232  projDepth.CreatePerspective(PMDImageProc::PoseFromMeta(MetaDataDepth),
233  PMDImageProc::KFromMeta(MetaDataDepth),
234  MetaDataDepth.width, MetaDataDepth.height,
235  radDistType, undistDepth);
236  proj2D.CreatePerspective(PMDImageProc::PoseFromMeta(MetaData2D),
237  PMDImageProc::KFromMeta(MetaData2D),
238  MetaData2D.width, MetaData2D.height,
239  radDistType,undist2D);
240 
241  Image<float> ImgDepthTo2D;
242  ImgDepthTo2D.Init(MetaData2D.width, MetaData2D.height, 1);
243  ImgDepthTo2D.SetZero();
244  HomgPoint2D posOld(0,0,0), maxPosDiff(0,0,0);
245  double depthold=0;
246  for (unsigned int x=0; x<ImgDepth.GetWidth(); x++) {
247  for (unsigned int y=0; y<ImgDepth.GetHeight(); y++) {
248  Vector3<double> p3D;
249  HomgPoint2D pos(x,y,1);
250  float depth = ImgDepth.PixelValue(x,y);
251  if (depth>0) {
252  p3D = projDepth.UnProjectToPoint(pos, depth);
253  //cout << "pos" << pos << " depth"<<depth<< " 3D:" << p3D;
254  HomgPoint3D hp3D(p3D);
255  pos = proj2D.Project(hp3D);
256  //cout << "pos" << pos <<endl;
257  int xx=(int)rintf(pos[0]);
258  int yy=(int)rintf(pos[1]);
259  if (xx>=0 && xx<(int)ImgDepthTo2D.GetWidth() &&
260  yy>=0 && yy<(int)ImgDepthTo2D.GetHeight()) {
261  //ImgDepthTo2D.SetPixel(float((proj2D.GetC()-p3D).NormL2()), xx, yy);
262  ImgDepthTo2D.SetPixel(ImgToModify.PixelValue(x,y), xx, yy);
263  if (y>0 && posOld.NormL2()>0 && fabs((depth-depthold)/depth)<0.001) {
264  if (maxPosDiff.NormL2()<(posOld-pos).NormL2()) {
265  maxPosDiff = posOld-pos;
266  }
267  }
268  posOld = pos;
269  depthold = depth;
270  } else {
271  posOld[0]=0;
272  posOld[1]=0;
273  posOld[2]=0;
274  depthold = 0;
275  }
276  } else {
277  depthold = 0;
278  }
279  }
280  posOld[0]=0;
281  posOld[1]=0;
282  posOld[2]=0;
283  }
284  //ImageIO::Save("warpeddepth.mip",ImgDepthTo2D);
285  Image<float> res;
286  Dilation<float, float> dilation;
287  int kernelsize=int(ceil(maxPosDiff.NormL2()));
288  if (kernelsize==0 || kernelsize>25) {
289  BIASERR("Calculation of Kernelsize did not work, calculated " << kernelsize);
290  kernelsize=3;
291  } else {
292  kernelsize = kernelsize/2*2+1;
293  }
294  dilation.SetKernelSize(kernelsize); // kernelsize 3 wich is default is MUCH faster
296  dilation.Filter(ImgDepthTo2D,res);
297  ImgToModify = res;
298 
299  return 0;
300 
301 }
302 
304  const PMDImageMetaData &MetaData2D,
305  PMDImageMetaData &MetaDataDepth) {
306 
308  HMatrix H = HFromMeta_(MetaData2D, MetaDataDepth);
309  int ret = 0;
310  if (!H.IsIdentity()) {
311  hm.SetHomography(H);
312  Image<float> mapto(MetaData2D.width, MetaData2D.height, 1);
313  ret = hm.Map(ImgToModify, mapto);
314  if (ret>=0) {
315  ImgToModify = mapto;
316  MetaDataDepth = MetaData2D;
317  }
318  } else ret = -1;
319  return ret;
320 }
321 
322 
323 void PMDImageProc::
325  Image<unsigned char>& textureImage,
326  Projection& depthProj,Projection& textureProj,
327  Image<unsigned char>& newColorImage)
328 {
329  unsigned w = depthImage.GetWidth(), h = depthImage.GetHeight();
330  unsigned c = textureImage.GetChannelCount();
331  if(newColorImage.IsEmpty()) newColorImage.Init(w,h,c );
332  else if(newColorImage.GetWidth() != w || newColorImage.GetHeight() != h ||
333  newColorImage.GetChannelCount() != c) newColorImage.ReInit(w,h,c);
334 
335  unsigned char color[3]={0,0,0};
336  newColorImage.FillImageWithConstValue(color);
337 
338  float** idaD = depthImage.GetImageDataArray();
339  unsigned char** idaC = newColorImage.GetImageDataArray();
340  unsigned char** idaOldC = textureImage.GetImageDataArray();
341  for(unsigned y=0;y<h;y++){
342  for(unsigned x=0;x<w;x++){
343  if(idaD[y][x] != 0.0){
344  double depth = idaD[y][x];
345  Vector3<double> p = depthProj.UnProjectToPoint(HomgPoint2D(x,y,1),depth);
346  HomgPoint2D p2D;
347  if(textureProj.DoesPointProjectIntoImage(HomgPoint3D(p),p2D)){
348  for(unsigned i=0;i<c;i++){
349  idaC[y][x*c+i] = idaOldC[unsigned(p2D[1])][(unsigned)(p2D[0])*c+i];
350  }
351  }
352  }
353  }
354  }
355 }
356 
357 
359  const PMDImageMetaData &MetaDataDepth) {
360 
361  if (!Equal(MetaData2D.CameraCenter[0], MetaDataDepth.CameraCenter[0],1e-3) ||
362  !Equal(MetaData2D.CameraCenter[1], MetaDataDepth.CameraCenter[1],1e-3) ||
363  !Equal(MetaData2D.CameraCenter[2], MetaDataDepth.CameraCenter[2],1e-3))
364  {
365  BIASERR("Can not Fit Depth Image to 2D Image, centers are not equal!!");
367  }
368  KMatrix K2D, KDepth;
369  K2D = KFromMeta(MetaData2D);
370  KDepth = KFromMeta(MetaDataDepth);
371 
372  Vector3<double> rot2D(MetaData2D.CameraRotation[0],
373  MetaData2D.CameraRotation[1],
374  MetaData2D.CameraRotation[2]);
375  Vector3<double> rotDepth(MetaDataDepth.CameraRotation[0],
376  MetaDataDepth.CameraRotation[1],
377  MetaDataDepth.CameraRotation[2]);
378  RMatrix RDepth, R2D;
379  RDepth.SetFromAxisAngle(rotDepth);
380  R2D.SetFromAxisAngle(rot2D);
381  HMatrix H = KDepth*RDepth.Transpose()*R2D*K2D.Invert();
382  return H;
383 
384 }
385 
386 
388  KMatrix K;
389  K.SetIdentity();
390  K[0][0] = MetaData.FocallengthX;
391  K[1][1] = MetaData.AspectRatio * MetaData.FocallengthX;
392  K[0][2] = MetaData.PrincipalX;
393  K[1][2] = MetaData.PrincipalY;
394  return K;
395 }
396 
397 
399  Pose pose;
400  RMatrix R;
403  R.GetQuaternion(Q);
404  pose.SetQ(Q);
405  pose.SetC(Vector3<double>(MetaData.CameraCenter));
406  return pose;
407 }
408 
409 
411  const KMatrix &K, int width,
412  int height, int channels)
413 {
415  Vector3<double> axis, C;
416  double angle;
417  Po.GetQ().GetAxisAngle(axis, angle);
418  axis.Normalize();
419  axis = axis * angle;
420  MetaData.CameraRotation[0] = axis[0];
421  MetaData.CameraRotation[1] = axis[1];
422  MetaData.CameraRotation[2] = axis[2];
423  C = Po.GetC();
424  MetaData.CameraCenter[0] = C[0];
425  MetaData.CameraCenter[1] = C[1];
426  MetaData.CameraCenter[2] = C[2];
427 
428  MetaData.FocallengthX = K[0][0];
429  MetaData.AspectRatio = K[1][1] / MetaData.FocallengthX;
430  MetaData.PrincipalX = K[0][2];
431  MetaData.PrincipalY = K[1][2];
432 
433  MetaData.UndistCoeff[0] = 0;
434  MetaData.UndistCoeff[1] = 0;
435  MetaData.UndistCoeff[2] = 0;
436  MetaData.UndistCoeff[3] = 0;
437 
438  MetaData.width = width;
439  MetaData.height = height;
440  MetaData.channels = channels;
441 
442  return MetaData;
443 }
444 
445 void PMDImageProc::
447  float maxDeviation)
448 {
449  unsigned w = depthImage.GetWidth();
450  unsigned h = depthImage.GetHeight();
451  float** ida = depthImage.GetImageDataArray();
452  float mean=0.0; int counter=0;
453 
454  float min=100000.0f,max=0.0f;
455  vector<float> histogramData;
456  ////////// analyze image with histogram /////////////
457  for(unsigned y=0;y<h;y++){
458  for(unsigned x=0;x<w;x++){
459  if (ida[y][x] == 0) {
460  continue;
461  }
462 
463  if(ida[y][x] < min) min = ida[y][x];
464  if(ida[y][x] > max) max = ida[y][x];
465  mean += ida[y][x];
466  counter++;
467  histogramData.push_back(ida[y][x]);
468  }
469  }
470 
471  if(counter > 0){
472  Histogram1D<float> hist;
473  hist.SetHistogramBoundaries(min,max);
474  hist.SetNumBins(30);
475  mean/=counter;
476 
477  //build up histogram
478  hist.AddData(histogramData);
479  //Get Maximum Value (bin with maximum number of entries)
480  float depthAccumulationValue = hist.GetBinCenterWithMaxEntries();
481 
482  // now go over all pixel and limit spread to
483  // histogramCenter+- maxDeviation
484  for(unsigned y=0;y<h;y++){
485  for(unsigned x=0;x<w;x++){
486  if(ida[y][x] != 0.0){
487  if(ida[y][x] > depthAccumulationValue+maxDeviation) {
488  ida[y][x] = depthAccumulationValue+maxDeviation;
489  } else if (ida[y][x] < depthAccumulationValue-maxDeviation) {
490  ida[y][x] = depthAccumulationValue-maxDeviation;
491  }
492  }
493  }
494  }
495  }//end if(counter>0)
496 }
497 
499  int size,
500  double sigmaVarianz) {
501  Image<float> res;
502  Median<float, float> median;
503  median.SetSize(size); // 1 = 3x3, 2=5x5
505  median.Filter(ImgDepth, res);
506  DeleteHighVarianceValues(res, sigmaVarianz,size);
507  ImgDepth = res;
508  return 0;
509 }
510 
511 
513 
514  Random rnd;
515  Image<float> ImgIn=ImgDepth;
516  for (unsigned int x=0; x<ImgDepth.GetWidth(); x++) {
517  for (unsigned int y=0; y<ImgDepth.GetHeight(); y++) {
518  if (ImgDepth.PixelValue(x, y)!=0) {
519  double sigma = PMDImageProc::CalcSigmaDepth(ImgIn, x, y, 1);
520  if (sigma>0) {
521  float pixval = ImgIn.PixelValue(x, y);
522  pixval = (float)rnd.GetNormalDistributed(pixval, sigma);
523  ImgDepth.SetPixel(pixval,x, y);
524  }
525  }
526  }
527  }
528  return 0;
529 }
530 
531 
533  double scaleFactor) {
534 
535  for (unsigned int x=0; x<ImgDepth.GetWidth(); x++) {
536  for (unsigned int y=0; y<ImgDepth.GetHeight(); y++) {
537  ImgDepth.SetPixel(ImgDepth.PixelValue(x, y) * (float)scaleFactor, x, y);
538  }
539  }
540 
541 }
542 
543 
545  const unsigned int x,
546  const unsigned int y,
547  const unsigned int HalfWinSize)
548 {
549  if (x<HalfWinSize || x>ImgDepth.GetWidth()-HalfWinSize-1 ||
550  y<HalfWinSize || y>ImgDepth.GetHeight()-HalfWinSize-1) {
551  return -1;
552  }
553 
554  // Surrounding min and max depth in m
555  double minDepth = 1000.0;
556  double maxDepth = 0.0;
557 
558  for (int dx=-1*(int)HalfWinSize; dx<=int(HalfWinSize); dx++) {
559  for (int dy=-1*(int)HalfWinSize; dy<=int(HalfWinSize); dy++) {
560  if (ImgDepth.PixelValue(x+dx, y+dy)<minDepth &&
561  ImgDepth.PixelValue(x+dx, y+dy)!=0)
562  minDepth = ImgDepth.PixelValue(x+dx, y+dy);
563  if (ImgDepth.PixelValue(x+dx, y+dy)>maxDepth)
564  maxDepth = ImgDepth.PixelValue(x+dx, y+dy);
565  }
566  }
567  // Standard deviation for a certain depth in meter
568  //where do these values come from ?? (ischiller)
569  double minDev= 0.002734*minDepth*minDepth +
570  0.00286723*minDepth - 0.0004229692;
571  double maxDev= 0.002734*maxDepth*maxDepth +
572  0.00286723*maxDepth - 0.0004229692;
573 
574  //depth value is in this range
575  minDepth -= minDev;
576  maxDepth += maxDev;
577  return (maxDepth-minDepth)/2;
578 }
579 
580 
582  const double sigmaThresh,
583  const int halfwinSize)
584 {
585  BIAS::Image<float> res=img;
586  float **data = img.GetImageDataArray();
587  int cols=(int)img.GetWidth();
588  int rows=(int)img.GetHeight();
589  double var,diff;
590  double count=0;
591  for (int row=0; row<rows; row++)
592  for (int col=0; col<cols; col++) {
593  var=0;
594  count=0;
595  for ( int i=-halfwinSize; i<=halfwinSize; i++){
596  for (int j=-halfwinSize; j<=halfwinSize; j++){
597  if ( ((row+i)>=0) && ((col+j)>=0) &&
598  ((row+i)<rows) && ((col+j)<cols) )
599  {
600  diff= data[row+i][col+j]-data[row][col];
601  var+= diff*diff;
602  count++;
603  }
604  }
605  }
606  var/= count;
607  if (sqrt(var)>sigmaThresh) res.GetImageDataArray()[row][col]=0;
608  }
609  img=res;
610 }
611 
613  BIAS::Image<float> &mark, double sigmaThresh, int halfwinSize)
614 {
615  const float **data = img.GetImageDataArray();
616  float **mdata = mark.GetImageDataArray();
617 
618  int cols=(int)img.GetWidth();
619  int rows=(int)img.GetHeight();
620  if((int)mark.GetWidth() != cols || (int)mark.GetHeight()!= rows)
621  mark.ReInit(cols,rows,1);
622  double var,diff;
623  double count=0;
624  for (int row=0; row<rows; row++)
625  for (int col=0; col<cols; col++) {
626  var=0;
627  count=0;
628  for ( int i=-halfwinSize; i<halfwinSize; i++)
629  for (int j=-halfwinSize; j<halfwinSize; j++)
630  if ( ((row+i)>=0) && ((col+j)>=0) &&
631  ((row+i)<rows) && ((col+j)<cols) )
632  {
633  diff= data[row+i][col+j]-data[row][col];
634  var+= diff*diff;
635  count++;
636  }
637  var/= count;
638  if (sqrt(var)>sigmaThresh) mdata[row][col]=float(var);
639  else mdata[row][col]=0.0f;
640  }
641 }
642 
643 
644 int PMDImageProc::
646  std::vector<const BIAS::Image<float>* >& cImCheck,
647  std::vector<const Projection*>& cPCheck,
648  int searchSize)
649 {
650  unsigned w=0,h=0;
651  int counter=0;
652  w = cIm.GetWidth();
653  h = cIm.GetHeight();
654  //c = cIm.GetChannelCount();
655 
656  // get projection parameters
657  float** ida = cIm.GetImageDataArray();
658 
659  for(unsigned y=0;y<h;y++){
660  for(unsigned x=0;x<w;x++){
661 
662  if(ida[y][x] != 0){
663  HomgPoint3D point3D = cP.GetParameters()->UnProjectToPoint(HomgPoint2D(x,y,1),ida[y][x]);
664 
665  vector<bool> isIn;
666  for(unsigned i=0;i<cPCheck.size();i++){
667  isIn.push_back(false);
668  HomgPoint2D point;
669  bool projects = false;
670  projects = cPCheck[i]->DoesPointProjectIntoImage(point3D,point );
671 
672  if(projects && point[2]!=0){
673  unsigned w2,h2,width,height;
674  cPCheck[i]->GetParameters()->GetImageSize(w2,h2);
675  width = cImCheck[i]->GetWidth();
676  height = cImCheck[i]->GetHeight();
677  if(w2 != width || h2 != height) {
678  BIASERR("Unmatching image dimensions between projection and image");
679  return -1;
680  }
681 
682  int cX = (int) rint(point[0]);
683  int cY = (int) rint(point[1]);
684 
685  //if this point is not 0 in one of the other images invalidate
686  const float** idaCheck = cImCheck[i]->GetImageDataArray();
687  if (idaCheck[cY][cX] != 0.0) {
688  isIn[i] = true;
689  }
690  else //search around the point
691  {
692  bool found = false;
693  for (int runX = cX - searchSize; runX < (cX + searchSize); runX++) {
694  for (int runY = cY - searchSize; runY < (cY + searchSize); runY++) {
695  if (runX >= 0 && runY >= 0 && runX < (int)w2 && runY< (int)h2) {
696  if (idaCheck[runY][runX] != 0) {
697  isIn[i] = true;
698  found = true;
699  break;
700  }
701  }
702  } //end for Y
703  if (found) break;
704  }//end for X
705  }//end else
706  }//end if(projects && point[2]!=0)
707  else isIn[i] = false;
708  }// end for(unsigned i=0;i<cPCheck();i++)
709  bool bMustBeValidInAll=true;
710  if(bMustBeValidInAll){
711  for(unsigned i=0;i<isIn.size();i++) {
712  if(!isIn[i]){
713  ida[y][x] = 0.0;
714  counter++;
715  break;
716  }
717  }
718  }
719  else{
720  bool valid = false;
721  for(unsigned i=0;i<isIn.size();i++) {
722  valid &= isIn[i];
723  }
724  if(!valid){
725  ida[y][x] = 0.0;
726  counter++;
727  break;
728  }
729  }
730  }//end for x
731  }//end for y
732  }
733 
734  return counter;
735 }
736 
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
virtual function for interface definition
Definition: Median.cpp:69
void AddData(const std::vector< T > &data)
Definition: Histogram1D.cpp:21
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
a 3x3 Matrix describing projective transformations between planes
Definition: HMatrix.hh:39
Maps image src to image sink with homography H (software implementation)
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
Dilation operator for binary images (black and white)
Definition: Dilation.hh:43
static void LimitDepthSpread(BIAS::Image< float > &depthImage, float maxDeviation)
use to limit the depth spread to a certain range around the
virtual HomgPoint3D UnProjectToPoint(const HomgPoint2D &pos, double depth, bool IgnoreDistortion=false) const
calculates a 3D point in the global (not the rig) coordinate system, which belongs to the image posit...
void SetC(const Vector3< POSE_TYPE > &C, const Matrix3x3< POSE_TYPE > &cov)
Set translation (resp.
Definition: Pose.cpp:90
const Vector3< double > & GetC() const
Set origin of local coordinate system in global coordinates.
static int CrossCheck(Image< float > &cIm, const Projection &cP, std::vector< const Image< float > * > &cImCheck, std::vector< const Projection * > &cPCheck, int searchSize=3)
Projects all points != 0 in image cIm to both other images cIm1 and cIm2 and checks whether the 3D po...
static HMatrix HFromMeta_(const PMDImageMetaData &MetaData2D, const PMDImageMetaData &MetaDataDepth)
Create a H-Matrix that converts the depth image to the 2D view.
static int FitDepthTo2DImage(Image< float > &ImgDepth, const PMDImageMetaData &MetaData2D, PMDImageMetaData &MetaDataDepth)
convert a depth image such that the depth and the grey value at the same pixel position belong to the...
const Quaternion< double > & GetQ() const
Get orientation of local coordinate system as unit quaternion mapping from local coordinates to globa...
T GetBinCenterWithMaxEntries()
Definition: Histogram1D.cpp:64
virtual parent class for API definition of all (future) filters
Definition: FilterBase.hh:77
bool IsIdentity(const T eps=std::numeric_limits< T >::epsilon()) const
Definition: Matrix3x3.cpp:518
static int FitDepthTo2DImageHomogr_(Image< float > &ImgToModify, const PMDImageMetaData &MetaData2D, PMDImageMetaData &MetaDataDepth)
void SetQ(const Quaternion< POSE_TYPE > &Q, const Matrix4x4< POSE_TYPE > &cov)
Set rotation (resp.
Definition: Pose.cpp:103
void SetHistogramBoundaries(const T &min_val, const T &max_val)
Definition: Histogram1D.hh:60
unsigned int GetWidth() const
Definition: ImageBase.hh:312
int GetAxisAngle(Vector3< QUAT_TYPE > &axis, QUAT_TYPE &angle) const
Returns rotation in axis and angle notation (angle in radians).
double CameraRotation[3]
Definition: PMDImageIO.hh:80
StorageType PixelValue(const unsigned int x, const unsigned int y, const unsigned short int channel=0) const
Returns value of pixel at specific position, using specific channel as offset.
Definition: Image.hh:91
int GetQuaternion(Quaternion< ROTATION_MATRIX_TYPE > &quat) const
Calculates quaternion representation for this rotation matrix.
3D rotation matrix
Definition: RMatrix.hh:49
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
Definition: Pose.hh:73
static void MarkHighVarianceValues(const BIAS::Image< float > &img, BIAS::Image< float > &mark, double sigmaThresh, int halfwinSize=1)
Markes pixels in PMD-Image with a local variance &gt; sigmaThresh.
const ProjectionParametersBase * GetParameters(unsigned int cam=0) const
const parameter access function
Definition: Projection.hh:194
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Does the dilation.
Definition: Dilation.cpp:282
Implements a 2D median filter for images.
Definition: Median.hh:39
static void DeleteHighVarianceValues(BIAS::Image< float > &img, const double sigmaThresh, const int halfwinSize=1)
Deletes (sets to 0) pixels in PMD-Image with a local variance &gt; sigmaThresh.
void ReInit(const unsigned int &width, const unsigned int &height, const unsigned int nChannels=1, const enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true, const EColorModel colormodel=CM_Grey)
(Re-)Initialize Image data if required.
Definition: ImageBase.cpp:131
static int AddNoiseToDepthImage(Image< float > &ImgDepth)
This function adds noise to a depth image.
This class hides the underlying projection model, like projection matrix, spherical camera...
Definition: Projection.hh:70
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
Simple one dimensional histogram computation.
Definition: Histogram1D.hh:38
unsigned int GetHeight() const
Definition: ImageBase.hh:319
unsigned int channels
Definition: PMDImageIO.hh:73
int Map(const Image< InputStorageType > &src, Image< OutputStorageType > &sink, InterpolationMethod=MapTrilinear, bool newSink=false, double SuperSampling=1.0)
backward mapping with various interpolations
void SetBorderHandling(const int bh)
Definition: FilterBase.hh:127
void SetKernelSize(int size)
Definition: Morphology.hh:56
unsigned int width
Definition: PMDImageIO.hh:71
static void ScaleDepthImage(Image< float > &ImgDepth, double scaleFactor)
This function scales the depth image with the given scale factor.
unsigned int height
Definition: PMDImageIO.hh:72
static double CalcSigmaDepth(const Image< float > &ImgDepth, const unsigned int x, const unsigned int y, const unsigned int HalfWinSize)
Give the standard deviation for a pixel in the depth image.
void FillImageWithConstValue(StorageType Value)
fill grey images
Definition: Image.cpp:456
static PMDImageMetaData MetaFromPoseAndK(const Pose &Po, const KMatrix &K, int width, int height, int channels)
void SetSize(int newsize, int secondsize=-1)
Definition: Median.hh:140
Store extrinsic and intrinsic camera parameters for Rotation is in axis * angle representation image ...
Definition: PMDImageIO.hh:70
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual bool DoesPointProjectIntoImage(const BIAS::HomgPoint3D &X, BIAS::HomgPoint2D &x, unsigned int cam=0, bool IgnoreDistortion=false) const
Checks if 3D point projects into specified image and returns belonging 2D image point.
Definition: Projection.cpp:300
void SetPixel(const StorageType &value, const unsigned int &x, const unsigned int &y, const unsigned short int channel=0)
Set the value of a given pixel (x,y) in channel to value.
Definition: Image.hh:171
void SetFromAxisAngle(Vector3< ROTATION_MATRIX_TYPE > w)
Set from rotation axis * angle (modified Rodrigues vector)
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
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
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
static int FitDepthTo2DImageKOnly_(Image< float > &ImgToModify, const PMDImageMetaData &MetaData2D, PMDImageMetaData &MetaDataDepth)
These methods transform the depth image to fit the 2D-image.
static void Fit2DToDepthImage(Image< float > &depthImage, Image< unsigned char > &textureImage, Projection &depthProj, Projection &textureProj, Image< unsigned char > &newColorImage)
calculates a color image of the size of the depth image by projecting every pixel of the depth image ...
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
Definition: Matrix3x3.cpp:167
static int FitModCoeffTo2DImage(Image< float > &ImgModCoeff, const Image< float > &ImgDepth, const PMDImageMetaData &MetaData2D, PMDImageMetaData &MetaDataDepth)
Vector3< double > UnProjectToPoint(const HomgPoint2D &pos, double depth, unsigned int cam=0, bool IgnoreDistortion=false) const
calculates a 3D point in the global (not the rig) coordinate system, which belongs to the image posit...
Definition: Projection.cpp:349
this class collects all additional data chunks of type AppData to be written into/read from an image ...
Definition: MetaData.hh:121
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
void CreatePerspective(const BIAS::Pose &pose, const BIAS::KMatrix &K, int width, int height, BIAS_ProjParaPersp_DISTORTION_TYPE radDistType=DISTYPE_DEF, const std::vector< double > &UndistortionCoefficients=std::vector< double >(4, 0.0))
Create a perspective camera and add to projection.
Definition: Projection.cpp:133
static Pose PoseFromMeta(const PMDImageMetaData &MetaData)
KMatrix Invert() const
returns analyticaly inverted matrix
Definition: KMatrix.cpp:31
virtual HomgPoint2D Project(const HomgPoint3D &X, unsigned int cam=0, bool IgnoreDistortion=false) const
returns the 2d projection of X in camera cam, where X is given in the global coordinate frame (not th...
Definition: Projection.cpp:250
static KMatrix KFromMeta(const PMDImageMetaData &MetaData)
void SetHomography(const HMatrix &H)
set your homography H (source = H * sink) before calling Map()
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
class for producing random numbers from different distributions
Definition: Random.hh:51
void SetZero()
zeroes the image
Definition: ImageBase.hh:83
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
static int DenoiseDepthImage(Image< float > &ImgDepth, int size=1, double sigmaVarianz=0.5)
This function denoises a PMD-Depth image by Median and variance filtering.
class BIASGeometryBase_EXPORT HomgPoint2D
static int FitDepthTo2DImageFree_(Image< float > &ImgToModify, const Image< float > &ImgDepth, const PMDImageMetaData &MetaData2D, PMDImageMetaData &MetaDataDepth)
void SetNumBins(const unsigned val)
Definition: Histogram1D.hh:66
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153