Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
clfTrimmedICP.cpp
1 #include <Base/Common/BIASpragma.hh>
2 #include <algorithm>
3 #include <MathAlgo/SVD.hh>
4 #include <OpenCLFramework/Algorithm/clfTrimmedICP.hh>
5 #include <iostream>
6 #include <OpenCLFramework/Algorithm/clfRadixSort.hh>
7 
8 #define SORT_GPU 1
9 
10 using namespace std;
11 using namespace BIAS;
12 using namespace BIAS;
13 
14 struct PointVertex {
15  GLfloat position[3];
16  GLfloat color[4];
17 };
18 
19 struct plainpair {
20  float data[3];
21  float model[3];
22  float distance;
23 };
24 
25 clfTrimmedICP::clfTrimmedICP(int w, int h) : context_(true), radixsort_(&context_) {
26  sizeofvertex_ = 7;
27  maxIterations_ = 40;
29  lasterror_ = 10000.0f;
30  w_ = w;
31  h_ = h;
36 
38 
40 
41  // add code to our program
42  programCL_->AddSource("/OpenCLFramework/Algorithm/cl/trimmedicp.cl");
43 
44  programCL_->Build();
45 
46  programCL_->AddKernel( "findNearestPairs" );
47  programCL_->AddKernel( "movePointCloud" );
48 
49  dataBuffer_ = NULL;
50  modelBuffer_ = NULL;
51 
53  cout << "Sizeof : " << sizeof( plainpair ) << endl;
54  outBuffer_->Allocate( w_*h_ * sizeof( plainpair ), false, false);
55  programCL_->KernelSetArgument( "findNearestPairs", 2, *outBuffer_ );
56  programCL_->KernelSetArgument( "movePointCloud", 1, *outBuffer_ );
57  pairs_.resize( w_*h_);
58  sortedidx_ = NULL;
59  distToSort_ = NULL;
60 }
61 
63 }
64 
66  modelpointcnt_ = setFromDepthMap_(modelPoints_, depthMap, ampImage, false);
67  if (modelBuffer_ == NULL) {
70  programCL_->KernelSetArgument( "findNearestPairs", 0, *modelBuffer_ );
71  }
72  programCL_->KernelSetArgument( "findNearestPairs", 3, (int)modelpointcnt_ );
74  return modelpointcnt_;
75 }
77  datapointcnt_ = setFromDepthMap_(dataPoints_, depthMap, ampImage, true, true);
78  if (dataBuffer_ == NULL) {
81  programCL_->KernelSetArgument( "findNearestPairs", 1, *dataBuffer_ );
82  programCL_->KernelSetArgument( "movePointCloud", 0, *dataBuffer_ );
83  }
85  return datapointcnt_;
86 }
87 
88 
89 unsigned int clfTrimmedICP::
90 setFromDepthMap_(glfVertexBuffer &buffer, const Camera<float> depthMap, const Camera<unsigned char> ampImage, bool keep, bool padData) {
91 
92  lasterror_ = 10000.0f;
93 
94  unsigned int ret = 0;
95 
96  PointVertex *vertices = (PointVertex*)buffer.Map();
99  const float **ida = depthMap.GetImageDataArray();
100  HomgPoint2D p2d;
101  unsigned int idx;
102  for (int y=0;y<h_;y++) {
103  for (int x=0;x<w_;x++) {
104  idx = ret;
105  float d = ida[y][x];
106  if (fabs(d) > 0.1) {
107  p2d.Set(x,y,1);
108  if (ppd != NULL)
109  ppd->UnDistortDepth(p2d, d, false);
110  HomgPoint3D p3d = ppp->UnProjectToPoint(p2d, d, false);
111  Vector3<double> p3dv = p3d.GetEuclidean();
112  // position
113  vertices[idx].position[0] = (float)p3dv[0];
114  vertices[idx].position[1] = (float)p3dv[1];
115  vertices[idx].position[2] = (float)p3dv[2];
116  // color
117  vertices[idx].color[0] = (float)x/(float)w_;
118  vertices[idx].color[1] = (float)y/(float)h_;
119  vertices[idx].color[2] = (float)d/(float)10000.0f;
120  vertices[idx].color[3] = 1.0f;
121  ret ++;
122  }
123  }
124  }
125  if (padData) {
126  unsigned int padval = ret % maxComputeUnits_;
127  if (padval != 0) {
128  padval = maxComputeUnits_ - padval;
129  }
130  cout << "padding " << padval << " " << endl;
131  unsigned int start = ret;
132  for (unsigned int idx=start;idx<start+padval;idx++) {
133  // position
134  vertices[idx].position[0] = (float)0.0f;
135  vertices[idx].position[1] = (float)0.0f;
136  vertices[idx].position[2] = (float)16000.0f;
137  // color
138  vertices[idx].color[0] = 0.0f;
139  vertices[idx].color[1] = 0.0f;
140  vertices[idx].color[2] = 16000.0f/10000.0f;
141  vertices[idx].color[3] = 1.0f;
142  ret ++;
143  }
144  cout << "padding " << padval << " full: " << ret << endl;
145 
146  }
147  buffer.Unmap();
148  glFlush();
149  glFinish();
150 
151  if (keep) {
152  inDepth_ = depthMap;
153  inTex_ = ampImage;
154  }
155  return ret;
156 }
157 
158 int clfTrimmedICP::
159 Compute(float nearestDistance, unsigned int numberOfPoints) {
160  float res=0;
161  ComputeNearestPoints_(nearestDistance, numberOfPoints, res);
162  if (res < 10e-3 && res>0) {
163  std::cout << "CONVERGENCE!!" << std::endl;
164  return 0;
165  } else if (res > lasterror_ && false) {
166  std::cout << "previous result was better than current, finishing" << std::endl;
167  return 0;
168  } else if (iterationCounter_ > maxIterations_) {
169  std::cout << "max iterations reached" << std::endl;
170  return 0;
171  }
172  lasterror_ = res;
173 
176 
177  centerA_.SetZero();
178  centerB_.SetZero();
179 
180  // compute optimal motion here!
181  ComputeOptimalMotion_(c, R);
182  diff = c - dataParams_->GetC();
183  if (diff.NormL2() < 0.1) {
184  std::cout << "optimum found" << std::endl;
185  return 0;
186  }
187  // calculate new parameters here!
188  dataParams_->SetC( c );
189  dataParams_->SetR( R );
190 
191  // todo change dataPoints HERE
192 
194  return 1;
195 }
196 
197 int clfTrimmedICP::Fuse(float nearestDistance) {
198  BIASWARN ("fuse function disabled");
199  /* todo what is this for anyways...
200  OcTree3D **branches = incomingTree_->GetNodes();
201  for (unsigned int i=0;i<8;i++) {
202  delete branches[i];
203  branches[i] = NULL;
204  }
205 // setFromDepthMap_(incomingTree_, inDepth_, inTex_);
206  incomingTree_->AddDepthMap(inDepth_, dataParams_, inTex_,0,5.0);
207 
208  // for each point in incoming, find nearest point in model.
209  std::vector<OcTree3D* > nIn;
210  std::vector<OcTree3D* > nModel;
211  incomingTree_->GetAllActiveNodes(nIn);
212  pairs_.clear();
213  icppair p;
214 
215 // #pragma omp parallel for private (nModel)
216  for (unsigned int i=0;i<nIn.size();i++) {
217  modelTree_->GetSupersetVolumeNodes(nModel, nearestDistance, nIn[i]->GetPosition());
218  if (nModel.empty())
219  continue;
220  OcTree3D* minDistNode = NULL;
221  float minDist = 10e5;
222  float dist = 10e5;
223  BIAS::Vector3<double> *pos = nIn[i]->GetPosition();
224  for (unsigned int j=0;j<nModel.size();j++) {
225  dist = nModel[j]->GetPosition()->Dist( *pos );
226  if (dist < minDist) {
227  minDist = dist;
228  minDistNode = nModel[j];
229  }
230  }
231  p.inputpoint = nIn[i]->GetPosition();
232  p.modelpoint = minDistNode->GetPosition();
233  p.distance = minDist;
234  pairs_.push_back(p);
235 // std::cout << "point " << *(p.inputpoint) << " " << *(p.modelpoint) << " distance: " << p.distance << " " << nModel.size() << std::endl;
236  nModel.clear();
237  }
238  std::sort(pairs_.begin(), pairs_.end(), clfTrimmedICP::comparePairByDistance);
239  OcTree3D fusedtree;
240  fusedtree.SetSize(16000);
241  fusedtree.SetContentActive(false);
242 
243 // #pragma omp parallel for
244  for (unsigned int i=0;i<pairs_.size();i++) {
245  OcTree3D *oct = modelTree_->GetDeepestNodeContaining(pairs_[i].modelpoint);
246  if (oct == NULL) continue;
247  DataElementBase *modelelement = oct->GetContent();
248  oct = incomingTree_->GetDeepestNodeContaining(pairs_[i].inputpoint);
249  if (oct == NULL) continue;
250  DataElementBase *inputelement = oct->GetContent();
251  if (modelelement != NULL && inputelement != NULL) {
252  DataElementBase *newElement = new DataElementBase();
253  newElement->SetPosition(*(pairs_[i].modelpoint));
254  fusedtree.AddTreeItem(newElement, 5.0, 0.5);
255  }
256  if (modelelement != NULL)
257  modelTree_->DeleteTreeItem(modelelement);
258  if (inputelement != NULL)
259  incomingTree_->DeleteTreeItem(inputelement);
260  }
261 
262  std::cout << "saving fuse result" << std::endl;
263  fusedtree.Write("fused-tree.txt");
264  nIn.clear();
265  incomingTree_->GetAllActiveNodes(nIn);
266  modelTree_->GetAllActiveNodes(nModel);
267  branches = fusedtree.GetNodes();
268  for (unsigned int i=0;i<8;i++) {
269  delete branches[i];
270  branches[i] = NULL;
271  }
272  for (unsigned int i=0;i<nIn.size();i++) {
273  fusedtree.AddTreeItem(nIn[i]);
274  }
275  for (unsigned int i=0;i<nModel.size();i++) {
276  fusedtree.AddTreeItem(nModel[i]);
277  }
278  std::cout << "saving remains result" << std::endl;
279  fusedtree.Write("remains-tree.txt");
280  */
281  return 0;
282 }
283 
284 int clfTrimmedICP::
285 ComputeNearestPoints_(float nearestDistance, unsigned int numberOfPoints, float &res) {
286  cout << "1" << endl;
287  numberOfPoints_ = numberOfPoints;
288  cout << "2" << endl;
289 
290  try {
293  cout << "run on " << datapointcnt_ << " points" << endl;
295  context_.Finish();
296  cout << "release gl" << endl;
299  context_.Finish();
300  } catch (clfException &e) {
301  cout << "find nearest exception: " << e.GetDetailedString() << endl;
302  }
303 
304  plainpair *pairs = (plainpair*)outBuffer_->MapBuffer(false);
305  context_.Finish();
306 
307 // for (int i=0;i<w_*h_;i++) {
308 // for (int j=0;j<3;j++) cout << pairs[i].data[j] << " ";
309 // for (int j=0;j<3;j++) cout << pairs[i].model[j] << " ";
310 // cout << pairs[i].distance << endl;
311 // }
312 
313 // plainpair *pairs = new plainpair[w_*h_];
314 // outBuffer_->ReadFromBuffer(pairs);
315 
316  std::cout << "sort!" << std::endl;
317  // copy stuff to vector
318  if (distToSort_ == NULL) {
319  distToSort_ = new float[w_*h_];
320  }
321  for (unsigned int i=0;i<datapointcnt_;i++) {
322  pairs_[i].inputpoint.Set(pairs[i].data[0], pairs[i].data[1],pairs[i].data[2]);
323  pairs_[i].modelpoint.Set(pairs[i].model[0], pairs[i].model[1],pairs[i].model[2]);
324  pairs_[i].distance = pairs[i].distance;
325  distToSort_[i] = pairs[i].distance;
326  }
327  outBuffer_->UnMap( pairs );
328  context_.Finish();
329 // delete pairs;
330  std::cout << "copy done." << endl;
331 
332 
333  if (pairs_.size() < numberOfPoints_) {
334  numberOfPoints_ = pairs_.size();
335  }
336  if (numberOfPoints_ > datapointcnt_) {
338  }
339 
340  if (SORT_GPU) {
341  try {
342  radixsort_.SetData(datapointcnt_, distToSort_);
343  radixsort_.Sort();
346  } catch (clfException &e) {
347  cout << "Radixsort Exception: " << e.GetDetailedString() << endl;
348  }
349  } else {
350  if (sortedidx_ == NULL) {
351  sortedidx_ = new unsigned int[w_*h_];
352  for (int i=0;i<w_*h_;i++) {
353  sortedidx_[i] = i;
354  }
355  }
357  }
358 
359  std::cout << "sort finished!" << std::endl;
360  std::cout << numberOfPoints_ << " -> " << pairs_[numberOfPoints_-1].distance << std::endl;
361 
362 // for (unsigned int i=0;i<datapointcnt_;i++) {
363 // cout << pairs_[i].inputpoint << " " << pairs_[i].modelpoint << " " << pairs_[i].distance << endl;
364 // if (pairs_[i].distance > 1.0) {
365 // cout << "first non null: " << i << " " << pairs_[i].distance << endl;
366 // //break;
367 // }
368 //// cout << pairs_[i].inputpoint << " " << pairs_[i].modelpoint << " " << pairs_[i].distance << endl;
369 // }
370  double sum = 0.0;
371  for (unsigned int i=0;i<numberOfPoints_;i++) {
372  if (pairs_[ sortedidx_[i] ].distance > 1000.0) {
373  numberOfPoints_ = i;
374  break;
375  }
376  //std::cout << pairs_[ sortedidx_[i] ].distance << std::endl;
377  sum += pairs_[sortedidx_[i] ].distance;
378  }
379  if (numberOfPoints_ == 0) {
380  res = 0;
381  std::cout << "no pairs?!" << std::endl;
382  return 0;
383  }
384  sum /= double(numberOfPoints_);
385  std::cout << "current error: " << sqrt(sum) << std::endl;
386  res = (float)sum;
387 
388  return 0;
389 }
390 
391 int clfTrimmedICP::
393 
394  for (unsigned int i=0;i<numberOfPoints_;i++) {
395  centerA_ += (pairs_[sortedidx_[i] ].modelpoint);
396  centerB_ += (pairs_[sortedidx_[i] ].inputpoint);
397  }
398  centerA_.DivideIP(double(numberOfPoints_));
399  centerB_.DivideIP(double(numberOfPoints_));
400 
402  M.SetZero();
403  for (unsigned int i=0;i<numberOfPoints_;i++) {
404  for (unsigned int x=0;x<3;x++) {
405  for (unsigned int y=0;y<3;y++) {
406  M[x][y] += ((pairs_[sortedidx_[i] ].modelpoint)[x] - centerA_[x]) * ( (pairs_[sortedidx_[i] ].inputpoint) [y] - centerB_[y]);
407  }
408  }
409  }
411  unsigned int x=0, y=1, z=2;
412  S[0][0] = M[x][x] + M[y][y] + M[z][z];
413  S[0][1] = M[y][z] - M[z][y];
414  S[0][2] = M[z][x] - M[x][z];
415  S[0][3] = M[x][y] - M[y][x];
416  S[1][0] = S[0][1];
417  S[1][1] = M[x][x] - M[y][y] - M[z][z];
418  S[1][2] = M[x][y] + M[y][x];
419  S[1][3] = M[z][x] + M[x][z];
420  S[2][0] = S[0][2];
421  S[2][1] = S[1][2];
422  S[2][2] = -M[x][x] + M[y][y] - M[z][z];
423  S[2][3] = M[y][z] + M[z][y];
424  S[3][0] = S[0][3];
425  S[3][1] = S[1][3];
426  S[3][2] = S[2][3];
427  S[3][3] = -M[x][x] - M[y][y] + M[z][z];
428 
429  BIAS::SVD svd(S);
430 
431  BIAS::Matrix<double> vt = svd.GetVT();
432  std::vector<icpvecandval> eigValues(vt.GetRows());
433  // now we need the eigenvalues (with sign !)
434  // compute this by projecting the (normalized) eigenvectors onto their images
435  BIAS::Vector<double> eigenvector, eigenimage;
436  for (unsigned int i=0; i<vt.GetRows(); i++) {
437  // get ith eigenvector and its image
438  eigenvector=vt.GetRow(i);
439  eigenimage = S * eigenvector;
440  // compute scalar product
441  icpvecandval t;
442  t.value = (float)(eigenimage * eigenvector);
443  t.vector = eigenvector;
444  eigValues[i] = t;
445  }
446  std::sort(eigValues.begin(),eigValues.end(), compareVectorByValue);
447 
448  BIAS::Vector<double> qnorm = eigValues[eigValues.size()-1].vector;
450  q[3] = qnorm[0];
451  q[0] = qnorm[1];
452  q[1] = qnorm[2];
453  q[2] = qnorm[3];
454  BIAS::RMatrix turn;
455  turn.SetFromQuaternion(q);
456  turn.InvertIP();
457 
458  BIAS::Vector3<double> centertocamera = c - centerB_;
459 
460  BIAS::Vector3<double> centertocamera_rotated = turn * centertocamera;
461 
462  BIAS::Vector3<double> cmod = centertocamera_rotated - centertocamera;
463 
464  cmod += (centerA_-centerB_);
465  c = c + cmod;
466  std::cout << " rot : " << q << std::endl;
467  std::cout << " trans : " << cmod << std::endl;
468 
469  R = turn * R;
470 
471  float *tmat = (float*)outBuffer_->MapBuffer(true, 0, 15*sizeof(float));
472 
473  for (int i=0;i<9;i++) {
474  tmat[i] = (float)turn.GetData()[i];
475  }
476  for (int i=0;i<3;i++) {
477  tmat[9+i] = (float)(centerA_-centerB_)[i];
478  }
479  for (int i=0;i<3;i++) {
480  tmat[12+i] = (float)(centerB_)[i];
481  }
482  outBuffer_->UnMap( tmat );
483 
485  cout << "move" << endl;
487  cout << "release gl" << endl;
489  context_.Finish();
490 
491  return 0;
492 }
493 
virtual BIAS::Vector3< double > GetC() const
Get projection center.
unsigned int datapointcnt_
int Compute(float nearestDistance, unsigned int numberOfPoints)
void GetEuclidean(Vector3< HOMGPOINT3D_TYPE > &dest) const
calculate affine coordinates of this and write them to dest affine coordinates are projective coordin...
Definition: HomgPoint3D.hh:336
BIAS::Camera< float > inDepth_
clfBuffer * CreateBuffer()
create buffer object
Definition: clfContext.hh:79
std::string AddSource(std::string filename)
adds source code from a file
Definition: clfProgram.cpp:64
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
unsigned int sizeofvertex_
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
BIAS::glfVertexBuffer modelPoints_
void * MapBuffer(bool write=false, unsigned int offset=0, unsigned int size=0)
Definition: clfBuffer.cpp:152
additional depth calibration parameters for a perspective depth camera to be used for ToF-(PMD) camer...
virtual void SetR(const BIAS::RMatrix &R)
Set orientation from rotation matrix R.
BIAS::glfVertexBuffer dataPoints_
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
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...
unsigned int iterationCounter_
BIAS::Vector< double > vector
void SetZero()
set all values to 0
Definition: Vector3.hh:559
void AllocateFromVertexBuffer(BIAS::glfVertexBuffer &vbo, bool readonly=false, bool writeonly=false)
Allocation of a memory buffer from a GL vertexBuffer (works only on shared context!) ...
Definition: clfBuffer.cpp:96
clfBuffer * dataBuffer_
BIAS::glfVertexFormat vertexFormat_
void SetData(int num, float *data, int scale=1)
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
A vertex buffer contains an array of vertices that can be used for rendering.
void Unmap()
Unmaps the vertex buffer.
void UnDistortDepth(HomgPoint2D const &pos, float &d, bool bIsInCartesianCoords=false)
UnDistort depth value d at image position pos.
void UnMap(void *data)
Definition: clfMemory.cpp:54
void * Map()
Maps the vertex buffer to system memory, so it can be modified after creation.
int Fuse(float nearestDistance)
void Create(int numVertices, const glfVertexFormat &format, const void *data=NULL, bool useBufferIfPossible=true)
Creates the vertex buffer for the given number of vertices and vertex format.
void Build(int deviceNr=0, std::string options="")
builds the sources added by AddSource and AddSourceFromString
Definition: clfProgram.cpp:115
void AcquireGLObject(clfMemory &buffer)
acquire a buffer allocated from opengl, call glfinish first!
Definition: clfContext.cpp:271
BIAS::Vector3< double > centerB_
const std::string & GetDetailedString() const
detailed combination of all info available
3D rotation matrix
Definition: RMatrix.hh:49
clfProgram * CreateProgram()
create program object
Definition: clfContext.hh:71
clfRadixSort radixsort_
static bool compareVectorByValue(icpvecandval a, icpvecandval b)
static bool comparePairByDistance(icppair a, icppair b)
int ComputeOptimalMotion_(BIAS::Vector3< double > &c, BIAS::RMatrix &R)
unsigned int SetModelFromDepthMap(const BIAS::Camera< float > depthMap, const BIAS::Camera< unsigned char > ampImage)
unsigned int GetRows() const
Definition: Matrix.hh:202
clfProgram * programCL_
void AddAttribute(Attribute attrib, int index, GLenum type, int size, bool normalized=false)
Adds a vertex attribute to the format.
clfDeviceInfo GetDeviceInfo(unsigned int device=0)
Definition: clfContext.hh:141
clf Exception wrapper, is thrown in case of most clf errors
Definition: clfException.hh:48
void Finish()
force finishing the command queue
Definition: clfContext.cpp:289
const Matrix< double > & GetVT() const
return VT (=transposed(V))
Definition: SVD.hh:177
BIAS::Camera< unsigned char > inTex_
void Allocate(unsigned int bufsize, bool readonly=false, bool writeonly=false, void *hostptr=NULL, bool copy=false)
Allocation of a memory buffer A memory buffer can be created on device or host, it can be initialized...
Definition: clfBuffer.cpp:45
virtual BIAS::RMatrix GetR() const
Get orientation as rotation matrix R.
Vector< T > GetRow(const int &row) const
return a copy of row &quot;row&quot; of this matrix, zero based counting
Definition: Matrix.cpp:233
unsigned int numberOfPoints_
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
void KernelSetArgument(std::string kernelname, unsigned int argnumber, clfBuffer &buffer)
set kernel argument
Definition: clfProgram.cpp:177
BIAS::ProjectionParametersBase * modelParams_
unsigned int * sortedidx_
void AddKernel(std::string kernelname)
adds a kernel to the program.
Definition: clfProgram.cpp:158
unsigned int * GetPermutation(unsigned int num=0)
unsigned int modelpointcnt_
clfBuffer * outBuffer_
void ReleaseGLObject(clfMemory &buffer)
release a buffer allocated from opengl, call Finish first!
Definition: clfContext.cpp:280
int ComputeNearestPoints_(float nearestDistance, unsigned int numberOfPoints, float &res)
int InvertIP()
In place matrix conversion.
Definition: Matrix3x3.cpp:420
BIAS::ProjectionParametersBase * dataParams_
void DivideIP(const T &scalar)
Division (in place) of an scalar.
Definition: Vector3.hh:719
void RunOn1DRange(clfProgram &program, std::string kernelname, unsigned int globalrange, unsigned int localrange=0)
run a kernel on a 1D memory range
Definition: clfContext.cpp:220
void Set(const HOMGPOINT2D_TYPE &x, const HOMGPOINT2D_TYPE &y)
set elementwise with given 2 euclidean scalar values.
Definition: HomgPoint2D.hh:174
const BIAS::Projection & GetProj() const
Definition: Camera.hh:109
ProjectionParametersBase * GetParameterCloneWithAbsolutePose(unsigned int cam=0) const
Allocates memory for parameters base type and returns pointer to it!
Definition: Projection.hh:218
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
unsigned int SetDataFromDepthMap(const BIAS::Camera< float > depthMap, const BIAS::Camera< unsigned char > ampImage)
unsigned int maxIterations_
clfBuffer * modelBuffer_
std::vector< icppair > pairs_
BIAS::Vector3< double > centerA_
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153
unsigned int setFromDepthMap_(BIAS::glfVertexBuffer &buffer, const BIAS::Camera< float > depthMap, const BIAS::Camera< unsigned char > ampImage, bool keep=false, bool padData=false)