ViSP  2.7.0
vpMbtDistanceLine.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMbtDistanceLine.cpp 4056 2013-01-05 13:04:42Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 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 
50 #include <visp/vpMbtDistanceLine.h>
51 #include <visp/vpPlane.h>
52 #include <visp/vpMeterPixelConversion.h>
53 #include <visp/vpFeatureBuilder.h>
54 #include <stdlib.h>
55 
60 {
61  name = "";
62  p1 = NULL ;
63  p2 = NULL ;
64  line = NULL ;
65  meline = NULL ;
66  hiddenface = NULL ;
67  wmean = 1 ;
68  nbFeature =0 ;
69  Reinit = false;
70  isvisible = true;
71 }
72 
77 {
78 // cout << "Deleting line " << index << endl ;
79 
80  if (p1 != NULL) delete p1 ;
81  if (p2 != NULL) delete p2 ;
82  if (line != NULL) delete line ;
83  if (meline != NULL) delete meline ;
84 
85 }
86 
92 void
93 vpMbtDistanceLine::project(const vpHomogeneousMatrix &cMo)
94 {
95  line->project(cMo) ;
96  p1->project(cMo) ;
97  p2->project(cMo) ;
98 }
99 
108 void
109 buildPlane(vpPoint &P, vpPoint &Q, vpPoint &R, vpPlane &plane)
110 {
111  vpColVector a(3);
112  vpColVector b(3);
113  vpColVector n(3);
114  //Calculate vector corresponding to PQ
115  a[0]=P.get_oX()-Q.get_oX();
116  a[1]=P.get_oY()-Q.get_oY();
117  a[2]=P.get_oZ()-Q.get_oZ();
118 
119  //Calculate vector corresponding to PR
120  b[0]=P.get_oX()-R.get_oX();
121  b[1]=P.get_oY()-R.get_oY();
122  b[2]=P.get_oZ()-R.get_oZ();
123 
124  //Calculate normal vector to plane PQ x PR
125  n=vpColVector::cross(a,b);
126 
127  //Equation of the plane is given by:
128  double A = n[0];
129  double B = n[1];
130  double C = n[2];
131  double D=-(A*P.get_oX()+B*P.get_oY()+C*P.get_oZ());
132 
133  double norm = sqrt(A*A+B*B+C*C) ;
134  plane.setA(A/norm) ;
135  plane.setB(B/norm) ;
136  plane.setC(C/norm) ;
137  plane.setD(D/norm) ;
138 }
139 
140 
152 void
153 buildLine(vpPoint &P1, vpPoint &P2, vpPoint &P3, vpPoint &P4, vpLine &L)
154 {
155  vpPlane plane1;
156  vpPlane plane2 ;
157  buildPlane(P1,P2,P3,plane1) ;
158  buildPlane(P1,P2,P4,plane2) ;
159 
160  L.setWorldCoordinates(plane1.getA(),plane1.getB(), plane1.getC(),plane1.getD(),
161  plane2.getA(),plane2.getB(), plane2.getC(),plane2.getD()) ;
162 }
163 
164 
171 void
173 {
174  line = new vpLine ;
175  p1 = new vpPoint ;
176  p2 = new vpPoint ;
177 
178  *p1 = _p1 ;
179  *p2 = _p2 ;
180 
181  vpColVector V1(3);
182  vpColVector V2(3);
183  vpColVector V3(3);
184  vpColVector V4(3);
185 
186  V1[0] = p1->get_oX();
187  V1[1] = p1->get_oY();
188  V1[2] = p1->get_oZ();
189  V2[0] = p2->get_oX();
190  V2[1] = p2->get_oY();
191  V2[2] = p2->get_oZ();
192 
193  //if((V1-V2).sumSquare()!=0)
194  if(std::fabs((V1-V2).sumSquare()) > std::numeric_limits<double>::epsilon())
195  {
196  {
197  V3[0]=double(rand()%1000)/100;
198  V3[1]=double(rand()%1000)/100;
199  V3[2]=double(rand()%1000)/100;
200 
201 
202  vpColVector v_tmp1,v_tmp2;
203  v_tmp1 = V2-V1;
204  v_tmp2 = V3-V1;
205  V4=vpColVector::cross(v_tmp1,v_tmp2);
206  }
207 
208  vpPoint P3;
209  P3.setWorldCoordinates(V3[0],V3[1],V3[2]);
210  vpPoint P4;
211  P4.setWorldCoordinates(V4[0],V4[1],V4[2]);
212  buildLine(*p1,*p2, P3,P4, *line) ;
213  }
214  else
215  {
216  vpPoint P3;
217  P3.setWorldCoordinates(V1[0],V1[1],V1[2]);
218  vpPoint P4;
219  P4.setWorldCoordinates(V2[0],V2[1],V2[2]);
220  buildLine(*p1,*p2,P3,P4,*line) ;
221  }
222 }
223 
224 
230 void
232 {
233  me = _me ;
234  if (meline != NULL)
235  {
236  meline->setMe(me) ;
237  }
238 }
239 
240 
248 void
250 {
251  if(isvisible)
252  {
253  p1->changeFrame(cMo);
254  p2->changeFrame(cMo);
255  line->changeFrame(cMo);
256 
257  p1->projection();
258  p2->projection();
259  line->projection();
260 
261  vpImagePoint ip1, ip2;
262  double rho,theta;
263 
266  //rho theta uv
268 
269  while (theta > M_PI) { theta -= M_PI ; }
270  while (theta < -M_PI) { theta += M_PI ; }
271 
272  if (theta < -M_PI/2.0) theta = -theta - 3*M_PI/2.0;
273  else theta = M_PI/2.0 - theta;
274 
275  meline = new vpMbtMeLine ;
276  meline->setMe(me) ;
277 
278 // meline->setDisplay(vpMeSite::RANGE_RESULT) ;
279  meline->setInitRange(0);
280 
281  int marge = /*10*/5; //ou 5 normalement
282  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 ; }
283  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 ; }
284 
285  try
286  {
287  meline->initTracking(I,ip1,ip2,rho,theta);
288  }
289  catch(...)
290  {
291  //vpTRACE("the line can't be initialized");
292  }
293  }
294 // trackMovingEdge(I,cMo) ;
295 }
296 
297 
298 
305 void
307 {
308 
309  if (isvisible)
310  {
311 // p1->changeFrame(cMo) ;
312 // p2->changeFrame(cMo) ;
313 //
314 // p1->projection() ;
315 // p2->projection() ;
316 //
317 // vpImagePoint ip1, ip2;
318 //
319 // vpMeterPixelConversion::convertPoint(*cam,p1->get_x(),p1->get_y(),ip1) ;
320 // vpMeterPixelConversion::convertPoint(*cam,p2->get_x(),p2->get_y(),ip2) ;
321 //
322 // int marge = /*10*/5; //ou 5 normalement
323 // if (ip1.get_j()<ip2.get_j()) { meline->jmin = ip1.get_j()-marge ; meline->jmax = ip2.get_j()+marge ; }
324 // else{ meline->jmin = ip2.get_j()-marge ; meline->jmax = ip1.get_j()+marge ; }
325 // if (ip1.get_i()<ip2.get_i()) { meline->imin = ip1.get_i()-marge ; meline->imax = ip2.get_i()+marge ; }
326 // else{ meline->imin = ip2.get_i()-marge ; meline->imax = ip1.get_i()+marge ; }
327 
328  try
329  {
330  meline->track(I) ;
331  }
332  catch(...)
333  {
334  Reinit = true;
335  }
336  nbFeature = meline->getMeList().size();
337  }
338 }
339 
340 
347 void
349 {
350  if (isvisible)
351  {
352  p1->changeFrame(cMo) ;
353  p2->changeFrame(cMo) ;
354  line->changeFrame(cMo) ;
355 
356  p1->projection() ;
357  p2->projection() ;
358  line->projection() ;
359 
360  vpImagePoint ip1, ip2;
361  double rho,theta;
362 
366 
367  while (theta > M_PI) { theta -= M_PI ; }
368  while (theta < -M_PI) { theta += M_PI ; }
369 
370  if (theta < -M_PI/2.0) theta = -theta - 3*M_PI/2.0;
371  else theta = M_PI/2.0 - theta;
372 
373  int marge = /*10*/5; //ou 5 normalement
374  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 ; }
375  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 ; }
376 
377  try
378  {
379  //meline->updateParameters(I,rho,theta) ;
380  meline->updateParameters(I,ip1,ip2,rho,theta) ;
381  }
382  catch(...)
383  {
384  Reinit = true;
385  }
386  nbFeature = meline->getMeList().size();
387  }
388 }
389 
390 
399 void
401 {
402  if(meline!= NULL)
403  delete meline;
404 
405  initMovingEdge(I,cMo);
406 
407  Reinit = false;
408 }
409 
410 
421 void
422 vpMbtDistanceLine::display(const vpImage<unsigned char>&I, const vpHomogeneousMatrix &cMo, const vpCameraParameters&cam, const vpColor col, const unsigned int thickness, const bool displayFullModel)
423 {
424  if (isvisible ==true || displayFullModel)
425  {
426  p1->changeFrame(cMo) ;
427  p2->changeFrame(cMo) ;
428 
429  p1->projection() ;
430  p2->projection() ;
431 
432  vpImagePoint ip1, ip2;
433 
436 
437  vpDisplay::displayLine(I,ip1,ip2,col, thickness);
438  }
439 }
440 
441 
452 void
453 vpMbtDistanceLine::display(const vpImage<vpRGBa>&I, const vpHomogeneousMatrix &cMo, const vpCameraParameters&cam, const vpColor col, const unsigned int thickness, const bool displayFullModel)
454 {
455  if (isvisible ==true || displayFullModel)
456  {
457  p1->changeFrame(cMo) ;
458  p2->changeFrame(cMo) ;
459 
460  p1->projection() ;
461  p2->projection() ;
462 
463  vpImagePoint ip1, ip2;
464 
467 
468  vpDisplay::displayLine(I,ip1,ip2,col, thickness);
469  }
470 }
471 
472 
483 void
485 {
486  if (meline != NULL)
487  {
488  meline->display(I);
489  }
490 }
491 
495 void
497 {
498  if (isvisible == true)
499  {
500  L.resize(meline->getMeList().size(),6) ;
501  error.resize(meline->getMeList().size()) ;
502  nbFeature = meline->getMeList().size() ;
503  }
504  else
505  nbFeature = 0 ;
506 }
507 
511 void
513 {
514 
515  if (isvisible)
516  {
517  // feature projection
518  line->changeFrame(cMo) ;
519  line->projection() ;
520 
521  vpFeatureBuilder::create(featureline,*line) ;
522 
523  double rho = featureline.getRho() ;
524  double theta = featureline.getTheta() ;
525 
526  double co = cos(theta);
527  double si = sin(theta);
528 
529  double mx = 1.0/cam.get_px() ;
530  double my = 1.0/cam.get_py() ;
531  double xc = cam.get_u0() ;
532  double yc = cam.get_v0() ;
533 
534  double alpha ;
535  vpMatrix H ;
536  H = featureline.interaction() ;
537 
538  double x,y ;
539  vpMeSite p ;
540  unsigned int j =0 ;
541  for(std::list<vpMeSite>::const_iterator it=meline->getMeList().begin(); it!=meline->getMeList().end(); ++it){
542  x = (double)it->j ;
543  y = (double)it->i ;
544 
545  x = (x-xc)*mx ;
546  y = (y-yc)*my ;
547 
548  alpha = x*si - y*co;
549 
550  double *Lrho = H[0] ;
551  double *Ltheta = H[1] ;
552  // Calculate interaction matrix for a distance
553  for (unsigned int k=0 ; k < 6 ; k++)
554  {
555  L[j][k] = (Lrho[k] + alpha*Ltheta[k]);
556  }
557  error[j] = rho - ( x*co + y*si) ;
558  j++;
559  }
560  }
561 }
562 
570 bool
571 vpMbtDistanceLine::closeToImageBorder(const vpImage<unsigned char>& I, const unsigned int threshold)
572 {
573  if(threshold > I.getWidth() || threshold > I.getHeight()){
574  return true;
575  }
576  if (isvisible){
577 
578  for(std::list<vpMeSite>::const_iterator it=meline->getMeList().begin(); it!=meline->getMeList().end(); ++it){
579  int i = it->i ;
580  int j = it->j ;
581 
582  if(i < 0 || j < 0){ //out of image.
583  return true;
584  }
585 
586  if( ((unsigned int)i > (I.getHeight()- threshold) ) || (unsigned int)i < threshold ||
587  ((unsigned int)j > (I.getWidth ()- threshold) ) || (unsigned int)j < threshold ) {
588  return true;
589  }
590  }
591  }
592  return false;
593 }
Definition of the vpMatrix class.
Definition: vpMatrix.h:96
void projection(const vpColVector &_cP, vpColVector &_p)
Projection onto the image plane of a point. Input: the 3D coordinates in the camera frame _cP...
Definition: vpPoint.cpp:132
double get_u0() const
vpLine * line
The 3D line.
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:154
bool Reinit
Indicates if the line has to be reinitialized.
static vpColVector cross(const vpColVector &a, const vpColVector &b)
Definition: vpColVector.h:153
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
void trackMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void track(const vpImage< unsigned char > &I)
vpPoint * p1
The first extremity.
void displayMovingEdges(const vpImage< unsigned char > &I)
double get_oY() const
Get the point Y coordinate in the object frame.
Definition: vpPoint.h:129
Contains predetermined masks for sites and holds moving edges tracking parameters.
Definition: vpMe.h:70
double getRho() const
double get_py() const
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.h:138
Implementation of a line used by the model-based tracker.
Definition: vpMbtMeLine.h:62
void initTracking(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, double rho, double theta)
double getTheta() const
bool isvisible
Indicates if the line is visible or not.
double get_j() const
Definition: vpImagePoint.h:192
void display(const vpImage< unsigned char > &, vpColor)
Definition: vpMbtMeLine.h:80
unsigned int nbFeature
The number of moving edges.
Class that defines what is a point.
Definition: vpPoint.h:65
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor col, const unsigned int thickness=1, const bool displayFullModel=false)
double getTheta() const
Definition: vpLine.h:166
double getRho() const
Definition: vpLine.h:177
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
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
void updateParameters(const vpImage< unsigned char > &I, double rho, double theta)
double get_v0() const
vpPoint * p2
The second extremity.
void setInitRange(const unsigned int &r)
Definition: vpMeTracker.h:126
vpColVector error
The error vector.
Generic class defining intrinsic camera parameters.
double get_oZ() const
Get the point Z coordinate in the object frame.
Definition: vpPoint.h:131
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.h:136
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
std::list< vpMeSite > & getMeList()
Definition: vpMeTracker.h:161
void projection()
Definition: vpLine.cpp:216
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP)
Definition: vpLine.cpp:366
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:127
bool closeToImageBorder(const vpImage< unsigned char > &I, const unsigned int threshold)
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
void setMovingEdge(vpMe *Me)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
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
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &_cP)
Definition: vpPoint.cpp:150
void initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
vpMbtMeLine * meline
The moving edge container.
void buildFrom(vpPoint &_p1, vpPoint &_p2)
double getD() const
Definition: vpPlane.h:118
void setMe(vpMe *me)
Definition: vpMeTracker.h:140
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
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94