ViSP  2.6.2
vpMbtDistanceLine.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMbtDistanceLine.cpp 3672 2012-04-04 15:49:57Z ayol $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2012 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Make the complete tracking of an object by using its CAD model
36  *
37  * Authors:
38  * Nicolas Melchior
39  * Romain Tallonneau
40  * Eric Marchand
41  *
42  *****************************************************************************/
43 #include <visp/vpConfig.h>
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
45 
51 #include <visp/vpMbtDistanceLine.h>
52 #include <visp/vpPlane.h>
53 #include <visp/vpMeterPixelConversion.h>
54 #include <visp/vpFeatureBuilder.h>
55 #include <stdlib.h>
56 
60 vpMbtDistanceLine::vpMbtDistanceLine()
61 {
62  name = "";
63  p1 = NULL ;
64  p2 = NULL ;
65  line = NULL ;
66  meline = NULL ;
67  hiddenface = NULL ;
68  wmean = 1 ;
69  nbFeature =0 ;
70  Reinit = false;
71  isvisible = true;
72 }
73 
77 vpMbtDistanceLine::~vpMbtDistanceLine()
78 {
79 // cout << "Deleting line " << index << endl ;
80 
81  if (p1 != NULL) delete p1 ;
82  if (p2 != NULL) delete p2 ;
83  if (line != NULL) delete line ;
84  if (meline != NULL) delete meline ;
85 
86 }
87 
93 void
94 vpMbtDistanceLine::project(const vpHomogeneousMatrix &cMo)
95 {
96  line->project(cMo) ;
97  p1->project(cMo) ;
98  p2->project(cMo) ;
99 }
100 
109 void
110 buildPlane(vpPoint &P, vpPoint &Q, vpPoint &R, vpPlane &plane)
111 {
112  vpColVector a(3);
113  vpColVector b(3);
114  vpColVector n(3);
115  //Calculate vector corresponding to PQ
116  a[0]=P.get_oX()-Q.get_oX();
117  a[1]=P.get_oY()-Q.get_oY();
118  a[2]=P.get_oZ()-Q.get_oZ();
119 
120  //Calculate vector corresponding to PR
121  b[0]=P.get_oX()-R.get_oX();
122  b[1]=P.get_oY()-R.get_oY();
123  b[2]=P.get_oZ()-R.get_oZ();
124 
125  //Calculate normal vector to plane PQ x PR
126  n=vpColVector::cross(a,b);
127 
128  //Equation of the plane is given by:
129  double A = n[0];
130  double B = n[1];
131  double C = n[2];
132  double D=-(A*P.get_oX()+B*P.get_oY()+C*P.get_oZ());
133 
134  double norm = sqrt(A*A+B*B+C*C) ;
135  plane.setA(A/norm) ;
136  plane.setB(B/norm) ;
137  plane.setC(C/norm) ;
138  plane.setD(D/norm) ;
139 }
140 
141 
153 void
154 buildLine(vpPoint &P1, vpPoint &P2, vpPoint &P3, vpPoint &P4, vpLine &L)
155 {
156  vpPlane plane1;
157  vpPlane plane2 ;
158  buildPlane(P1,P2,P3,plane1) ;
159  buildPlane(P1,P2,P4,plane2) ;
160 
161  L.setWorldCoordinates(plane1.getA(),plane1.getB(), plane1.getC(),plane1.getD(),
162  plane2.getA(),plane2.getB(), plane2.getC(),plane2.getD()) ;
163 }
164 
165 
172 void
173 vpMbtDistanceLine::buildFrom(vpPoint &_p1, vpPoint &_p2)
174 {
175  line = new vpLine ;
176  p1 = new vpPoint ;
177  p2 = new vpPoint ;
178 
179  *p1 = _p1 ;
180  *p2 = _p2 ;
181 
182  vpColVector V1(3);
183  vpColVector V2(3);
184  vpColVector V3(3);
185  vpColVector V4(3);
186 
187  V1[0] = p1->get_oX();
188  V1[1] = p1->get_oY();
189  V1[2] = p1->get_oZ();
190  V2[0] = p2->get_oX();
191  V2[1] = p2->get_oY();
192  V2[2] = p2->get_oZ();
193 
194  //if((V1-V2).sumSquare()!=0)
195  if(std::fabs((V1-V2).sumSquare()) > std::numeric_limits<double>::epsilon())
196  {
197  {
198  V3[0]=double(rand()%1000)/100;
199  V3[1]=double(rand()%1000)/100;
200  V3[2]=double(rand()%1000)/100;
201 
202 
203  vpColVector v_tmp1,v_tmp2;
204  v_tmp1 = V2-V1;
205  v_tmp2 = V3-V1;
206  V4=vpColVector::cross(v_tmp1,v_tmp2);
207  }
208 
209  vpPoint P3;
210  P3.setWorldCoordinates(V3[0],V3[1],V3[2]);
211  vpPoint P4;
212  P4.setWorldCoordinates(V4[0],V4[1],V4[2]);
213  buildLine(*p1,*p2, P3,P4, *line) ;
214  }
215  else
216  {
217  vpPoint P3;
218  P3.setWorldCoordinates(V1[0],V1[1],V1[2]);
219  vpPoint P4;
220  P4.setWorldCoordinates(V2[0],V2[1],V2[2]);
221  buildLine(*p1,*p2,P3,P4,*line) ;
222  }
223 }
224 
225 
231 void
232 vpMbtDistanceLine::setMovingEdge(vpMe *_me)
233 {
234  me = _me ;
235  if (meline != NULL)
236  {
237  meline->setMe(me) ;
238  }
239 }
240 
241 
249 void
250 vpMbtDistanceLine::initMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo)
251 {
252  if(isvisible)
253  {
254  p1->changeFrame(cMo);
255  p2->changeFrame(cMo);
256  line->changeFrame(cMo);
257 
258  p1->projection();
259  p2->projection();
260  line->projection();
261 
262  vpImagePoint ip1, ip2;
263  double rho,theta;
264 
265  vpMeterPixelConversion::convertPoint(cam,p1->get_x(),p1->get_y(),ip1);
266  vpMeterPixelConversion::convertPoint(cam,p2->get_x(),p2->get_y(),ip2);
267  //rho theta uv
268  vpMeterPixelConversion::convertLine(cam,line->getRho(),line->getTheta(),rho,theta);
269 
270  while (theta > M_PI) { theta -= M_PI ; }
271  while (theta < -M_PI) { theta += M_PI ; }
272 
273  if (theta < -M_PI/2.0) theta = -theta - 3*M_PI/2.0;
274  else theta = M_PI/2.0 - theta;
275 
276  meline = new vpMbtMeLine ;
277  meline->setMe(me) ;
278 
279 // meline->setDisplay(vpMeSite::RANGE_RESULT) ;
280  meline->setInitRange(0);
281 
282  int marge = /*10*/5; //ou 5 normalement
283  if (ip1.get_j()<ip2.get_j()) { meline->jmin = (int)ip1.get_j()-marge ; meline->jmax = (int)ip2.get_j()+marge ; } else{ meline->jmin = (int)ip2.get_j()-marge ; meline->jmax = (int)ip1.get_j()+marge ; }
284  if (ip1.get_i()<ip2.get_i()) { meline->imin = (int)ip1.get_i()-marge ; meline->imax = (int)ip2.get_i()+marge ; } else{ meline->imin = (int)ip2.get_i()-marge ; meline->imax = (int)ip1.get_i()+marge ; }
285 
286  try
287  {
288  meline->initTracking(I,ip1,ip2,rho,theta);
289  }
290  catch(...)
291  {
292  //vpTRACE("the line can't be initialized");
293  }
294  }
295 // trackMovingEdge(I,cMo) ;
296 }
297 
298 
299 
306 void
307 vpMbtDistanceLine::trackMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix & /*cMo*/)
308 {
309 
310  if (isvisible)
311  {
312 // p1->changeFrame(cMo) ;
313 // p2->changeFrame(cMo) ;
314 //
315 // p1->projection() ;
316 // p2->projection() ;
317 //
318 // vpImagePoint ip1, ip2;
319 //
320 // vpMeterPixelConversion::convertPoint(*cam,p1->get_x(),p1->get_y(),ip1) ;
321 // vpMeterPixelConversion::convertPoint(*cam,p2->get_x(),p2->get_y(),ip2) ;
322 //
323 // int marge = /*10*/5; //ou 5 normalement
324 // if (ip1.get_j()<ip2.get_j()) { meline->jmin = ip1.get_j()-marge ; meline->jmax = ip2.get_j()+marge ; }
325 // else{ meline->jmin = ip2.get_j()-marge ; meline->jmax = ip1.get_j()+marge ; }
326 // if (ip1.get_i()<ip2.get_i()) { meline->imin = ip1.get_i()-marge ; meline->imax = ip2.get_i()+marge ; }
327 // else{ meline->imin = ip2.get_i()-marge ; meline->imax = ip1.get_i()+marge ; }
328 
329  try
330  {
331  meline->track(I) ;
332  }
333  catch(...)
334  {
335  Reinit = true;
336  }
337  nbFeature = meline->getMeList().size();
338  }
339 }
340 
341 
348 void
349 vpMbtDistanceLine::updateMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo)
350 {
351  if (isvisible)
352  {
353  p1->changeFrame(cMo) ;
354  p2->changeFrame(cMo) ;
355  line->changeFrame(cMo) ;
356 
357  p1->projection() ;
358  p2->projection() ;
359  line->projection() ;
360 
361  vpImagePoint ip1, ip2;
362  double rho,theta;
363 
364  vpMeterPixelConversion::convertPoint(cam,p1->get_x(),p1->get_y(),ip1);
365  vpMeterPixelConversion::convertPoint(cam,p2->get_x(),p2->get_y(),ip2);
366  vpMeterPixelConversion::convertLine(cam,line->getRho(),line->getTheta(),rho,theta);
367 
368  while (theta > M_PI) { theta -= M_PI ; }
369  while (theta < -M_PI) { theta += M_PI ; }
370 
371  if (theta < -M_PI/2.0) theta = -theta - 3*M_PI/2.0;
372  else theta = M_PI/2.0 - theta;
373 
374  int marge = /*10*/5; //ou 5 normalement
375  if (ip1.get_j()<ip2.get_j()) { meline->jmin = (int)ip1.get_j()-marge ; meline->jmax = (int)ip2.get_j()+marge ; } else{ meline->jmin = (int)ip2.get_j()-marge ; meline->jmax = (int)ip1.get_j()+marge ; }
376  if (ip1.get_i()<ip2.get_i()) { meline->imin = (int)ip1.get_i()-marge ; meline->imax = (int)ip2.get_i()+marge ; } else{ meline->imin = (int)ip2.get_i()-marge ; meline->imax = (int)ip1.get_i()+marge ; }
377 
378  try
379  {
380  //meline->updateParameters(I,rho,theta) ;
381  meline->updateParameters(I,ip1,ip2,rho,theta) ;
382  }
383  catch(...)
384  {
385  Reinit = true;
386  }
387  nbFeature = meline->getMeList().size();
388  }
389 }
390 
391 
400 void
401 vpMbtDistanceLine::reinitMovingEdge(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo)
402 {
403  if(meline!= NULL)
404  delete meline;
405 
406  initMovingEdge(I,cMo);
407 
408  Reinit = false;
409 }
410 
411 
422 void
423 vpMbtDistanceLine::display(const vpImage<unsigned char>&I, const vpHomogeneousMatrix &cMo, const vpCameraParameters&cam, const vpColor col, const unsigned int thickness, const bool displayFullModel)
424 {
425  if (isvisible ==true || displayFullModel)
426  {
427  p1->changeFrame(cMo) ;
428  p2->changeFrame(cMo) ;
429  line->changeFrame(cMo) ;
430 
431  p1->projection() ;
432  p2->projection() ;
433  line->projection() ;
434 
435  vpImagePoint ip1, ip2;
436 
437  vpMeterPixelConversion::convertPoint(cam,p1->get_x(),p1->get_y(),ip1) ;
438  vpMeterPixelConversion::convertPoint(cam,p2->get_x(),p2->get_y(),ip2) ;
439 
440  vpDisplay::displayLine(I,ip1,ip2,col, thickness);
441  }
442 }
443 
444 
455 void
456 vpMbtDistanceLine::display(const vpImage<vpRGBa>&I, const vpHomogeneousMatrix &cMo, const vpCameraParameters&cam, const vpColor col, const unsigned int thickness, const bool displayFullModel)
457 {
458  if (isvisible ==true || displayFullModel)
459  {
460  p1->changeFrame(cMo) ;
461  p2->changeFrame(cMo) ;
462  line->changeFrame(cMo) ;
463 
464  p1->projection() ;
465  p2->projection() ;
466  line->projection() ;
467 
468  vpImagePoint ip1, ip2;
469 
470  vpMeterPixelConversion::convertPoint(cam,p1->get_x(),p1->get_y(),ip1) ;
471  vpMeterPixelConversion::convertPoint(cam,p2->get_x(),p2->get_y(),ip2) ;
472 
473  vpDisplay::displayLine(I,ip1,ip2,col, thickness);
474  }
475 }
476 
477 
488 void
489 vpMbtDistanceLine::displayMovingEdges(const vpImage<unsigned char> &I)
490 {
491  if (meline != NULL)
492  {
493  meline->display(I);
494  }
495 }
496 
500 void
501 vpMbtDistanceLine::initInteractionMatrixError()
502 {
503  if (isvisible == true)
504  {
505  L.resize(meline->getMeList().size(),6) ;
506  error.resize(meline->getMeList().size()) ;
507  nbFeature = meline->getMeList().size() ;
508  }
509  else
510  nbFeature = 0 ;
511 }
512 
516 void
517 vpMbtDistanceLine::computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
518 {
519 
520  if (isvisible)
521  {
522  // feature projection
523  line->changeFrame(cMo) ;
524  line->projection() ;
525 
526  vpFeatureBuilder::create(featureline,*line) ;
527 
528  double rho = featureline.getRho() ;
529  double theta = featureline.getTheta() ;
530 
531  double co = cos(theta);
532  double si = sin(theta);
533 
534  double mx = 1.0/cam.get_px() ;
535  double my = 1.0/cam.get_py() ;
536  double xc = cam.get_u0() ;
537  double yc = cam.get_v0() ;
538 
539  double alpha ;
540  vpMatrix H ;
541  H = featureline.interaction() ;
542 
543  double x,y ;
544  vpMeSite p ;
545  unsigned int j =0 ;
546  for(std::list<vpMeSite>::const_iterator it=meline->getMeList().begin(); it!=meline->getMeList().end(); ++it){
547  x = (double)it->j ;
548  y = (double)it->i ;
549 
550  x = (x-xc)*mx ;
551  y = (y-yc)*my ;
552 
553  alpha = x*si - y*co;
554 
555  double *Lrho = H[0] ;
556  double *Ltheta = H[1] ;
557  // Calculate interaction matrix for a distance
558  for (unsigned int k=0 ; k < 6 ; k++)
559  {
560  L[j][k] = (Lrho[k] + alpha*Ltheta[k]);
561  }
562  error[j] = rho - ( x*co + y*si) ;
563  j++;
564  }
565  }
566 }
567 
575 bool
576 vpMbtDistanceLine::closeToImageBorder(const vpImage<unsigned char>& I, const unsigned int threshold)
577 {
578  if(threshold > I.getWidth() || threshold > I.getHeight()){
579  return true;
580  }
581  if (isvisible){
582 
583  for(std::list<vpMeSite>::const_iterator it=meline->getMeList().begin(); it!=meline->getMeList().end(); ++it){
584  int i = it->i ;
585  int j = it->j ;
586 
587  if(i < 0 || j < 0){ //out of image.
588  return true;
589  }
590 
591  if( ((unsigned int)i > (I.getHeight()- threshold) ) || (unsigned int)i < threshold ||
592  ((unsigned int)j > (I.getWidth ()- threshold) ) || (unsigned int)j < threshold ) {
593  return true;
594  }
595  }
596  }
597  return false;
598 }
599 
600 #endif
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
double get_u0() const
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:154
static vpColVector cross(const vpColVector &a, const vpColVector &b)
Definition: vpColVector.h:152
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
void setWorldCoordinates(const double &A1, const double &B1, const double &C1, const double &D1, const double &A2, const double &B2, const double &C2, const double &D2)
Definition: vpLine.cpp:98
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Definition: vpMeSite.h:76
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
Class to define colors available for display functionnalities.
Definition: vpColor.h:123
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.h:136
Contains predetermined masks for sites and holds moving edges tracking parameters.
Definition: vpMe.h:70
double get_py() const
double get_j() const
Definition: vpImagePoint.h:192
Class that defines what is a point.
Definition: vpPoint.h:65
Class that defines a line in the object frame, the camera frame and the image plane. All the parameters must be set in meter.
Definition: vpLine.h:124
double get_v0() const
Generic class defining intrinsic camera parameters.
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.h:138
double get_px() const
void setA(const double A)
Definition: vpPlane.h:91
void setC(const double C)
Definition: vpPlane.h:95
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
line coordinates conversion (rho,theta)
void setD(const double D)
Definition: vpPlane.h:97
double get_oX() const
Get the point X coordinate in the object frame.
Definition: vpPoint.h:134
int j
Definition: vpMeSite.h:98
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
double getB() const
Definition: vpPlane.h:114
double getA() const
Definition: vpPlane.h:112
unsigned int getHeight() const
Definition: vpImage.h:145
double getC() const
Definition: vpPlane.h:116
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
This class defines the container for a plane geometrical structure.
Definition: vpPlane.h:67
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
void setB(const double B)
Definition: vpPlane.h:93
double getD() const
Definition: vpPlane.h:118
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74