ViSP  2.7.0
vpMbtPolygon.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMbtPolygon.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  * Aurelien Yol
42  *
43  *****************************************************************************/
44 
45 #include <limits.h>
46 
47 #include <visp/vpConfig.h>
53 #include <visp/vpMbtPolygon.h>
54 
59 {
60  nbpt = 0 ;
61  p = NULL ;
62  isappearing = false;
63  isvisible = false;
64 }
65 
70 {
71  if (p !=NULL)
72  {
73  delete[] p;
74  p = NULL;
75  }
76 }
77 
85 vpPoint &
86 vpMbtPolygon::getPoint(const unsigned int _index)
87 {
88  if(_index >= nbpt){
89  throw vpException(vpException::dimensionError, "index out of range");
90  }
91  return p[_index];
92 }
93 
99 void
100 vpMbtPolygon::setNbPoint(const unsigned int nb)
101 {
102  nbpt = nb ;
103  if (p != NULL)
104  delete[] p;
105  p = new vpPoint[nb] ;
106 }
107 
114 void
115 vpMbtPolygon::addPoint(const unsigned int n, const vpPoint &P)
116 {
117  //if( p!NULL && n < nbpt )
118  p[n] = P ;
119 }
120 
126 void
128 {
129  for (unsigned int i = 0 ; i < nbpt ; i++)
130  {
131  p[i].changeFrame(cMo) ;
132  p[i].projection() ;
133  }
134 }
135 
144 bool
145 vpMbtPolygon::isVisible(const vpHomogeneousMatrix &cMo, const bool &depthTest)
146 {
147  changeFrame(cMo) ;
148 
149  if(depthTest)
150  for (unsigned int i = 0 ; i < nbpt ; i++){
151  if(p[i].get_Z() < 0){
152  isappearing = false;
153  isvisible = false ;
154  return false ;
155  }
156  }
157 
158  if(nbpt <= 2){
159  /* a line is allways visible */
160  isvisible = true;
161  isappearing = false;
162  return true ;
163  }
164 
165  vpColVector e1(3) ;
166  vpColVector e2(3) ;
167  vpColVector facenormal(3) ;
168 
169  e1[0] = p[1].get_X() - p[0].get_X() ;
170  e1[1] = p[1].get_Y() - p[0].get_Y() ;
171  e1[2] = p[1].get_Z() - p[0].get_Z() ;
172 
173  e2[0] = p[2].get_X() - p[1].get_X() ;
174  e2[1] = p[2].get_Y() - p[1].get_Y() ;
175  e2[2] = p[2].get_Z() - p[1].get_Z() ;
176 
177  facenormal = vpColVector::crossProd(e1,e2) ;
178 
179  double angle = p[0].get_X()*facenormal[0] + p[0].get_Y()*facenormal[1] + p[0].get_Z()*facenormal[2] ;
180 
181  if(angle < -0.0001 )
182  {
183  isvisible = true;
184  isappearing = false;
185 
186  return true ;
187  }
188  else
189  {
190  if (angle < 0.0000001 ){
191  isappearing = true;
192  }
193  else {
194  isappearing = false;
195  }
196  isvisible = false ;
197  return false ;
198  }
199 }
200 
211 bool
212 vpMbtPolygon::isVisible(const vpHomogeneousMatrix &cMo, const double alpha)
213 {
214  // std::cout << "Computing angle from MBT Face (cMo, alpha)" << std::endl;
215  if(nbpt <= 2){
216  /* a line is allways visible */
217  isvisible = true;
218  isappearing = false;
219  return true ;
220  }
221 
222  changeFrame(cMo);
223 
224  vpColVector e1(3) ;
225  vpColVector e2(3) ;
226  vpColVector facenormal(3) ;
227 
228  e1[0] = p[1].get_X() - p[0].get_X() ;
229  e1[1] = p[1].get_Y() - p[0].get_Y() ;
230  e1[2] = p[1].get_Z() - p[0].get_Z() ;
231 
232  e2[0] = p[2].get_X() - p[1].get_X() ;
233  e2[1] = p[2].get_Y() - p[1].get_Y() ;
234  e2[2] = p[2].get_Z() - p[1].get_Z() ;
235 
236  e1.normalize();
237  e2.normalize();
238 
239  facenormal = vpColVector::crossProd(e1,e2) ;
240  facenormal.normalize();
241 
242  vpColVector e4(3) ;
243  vpPoint pt;
244  for (unsigned int i = 0; i < nbpt; i += 1){
245  pt.set_X(pt.get_X() + p[i].get_X());
246  pt.set_Y(pt.get_Y() + p[i].get_Y());
247  pt.set_Z(pt.get_Z() + p[i].get_Z());
248  }
249  e4[0] = -pt.get_X()/(double)nbpt; e4[1] = -pt.get_Y()/(double)nbpt; e4[2] = -pt.get_Z()/(double)nbpt;
250  e4.normalize();
251 
252  double angle2 = vpColVector::dotProd (e4, facenormal);
253  double my_angle = acos(angle2);
254 
255 // std::cout << angle2 << "/" << vpMath::deg(my_angle) << std::endl;
256 
257  if( my_angle < alpha ){
258  isvisible = true;
259  isappearing = false;
260  return true;
261  }
262 
263  isvisible = false;
264  isappearing = false;
265  return false;
266 }
267 
268 std::vector<vpImagePoint>
270 {
271  std::vector<vpImagePoint> roi;
272  for (unsigned int i = 0; i < nbpt; i ++){
273  vpImagePoint ip;
274  vpMeterPixelConversion::convertPoint(_cam, p[i].get_x(), p[i].get_y(), ip);
275  roi.push_back(ip);
276  }
277  return roi;
278 }
279 
280 //###################################
281 // Static functions
282 //###################################
283 
284 void
285 vpMbtPolygon::getMinMaxRoi(const std::vector<vpImagePoint> &roi, int & i_min, int &i_max, int &j_min, int &j_max)
286 {
287  // i_min_d = std::numeric_limits<double>::max(); // create an error under Windows. To fix it we have to add #undef max
288  double i_min_d = (double) INT_MAX;
289  double i_max_d = 0;
290  double j_min_d = (double) INT_MAX;
291  double j_max_d = 0;
292 
293  for (unsigned int i = 0; i < roi.size(); i += 1){
294  if(i_min_d > roi[i].get_i())
295  i_min_d = roi[i].get_i();
296 
297  if(roi[i].get_i() < 0)
298  i_min_d = 1;
299 
300  if((roi[i].get_i() > 0) && (i_max_d < roi[i].get_i()))
301  i_max_d = roi[i].get_i();
302 
303  if(j_min_d > roi[i].get_j())
304  j_min_d = roi[i].get_j();
305 
306  if(roi[i].get_j() < 0)
307  j_min_d = 1;//border
308 
309  if((roi[i].get_j() > 0) && j_max_d < roi[i].get_j())
310  j_max_d = roi[i].get_j();
311  }
312  i_min = static_cast<int> (i_min_d);
313  i_max = static_cast<int> (i_max_d);
314  j_min = static_cast<int> (j_min_d);
315  j_max = static_cast<int> (j_max_d);
316 }
317 
325 bool
326 vpMbtPolygon::roiInsideImage(const vpImage<unsigned char>& I, const std::vector<vpImagePoint>& corners)
327 {
328  for(unsigned int i=0; i<corners.size(); ++i){
329  if((corners[i].get_i() < 0) || (corners[i].get_j() < 0) ||
330  (corners[i].get_i() > I.getHeight()) || (corners[i].get_j() > I.getWidth())){
331  return false;
332  }
333  }
334  return true;
335 }
336 
337 
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
void changeFrame(const vpHomogeneousMatrix &cMo)
bool isVisible() const
Definition: vpMbtPolygon.h:110
unsigned int getWidth() const
Definition: vpImage.h:154
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
virtual ~vpMbtPolygon()
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 ...
vpPoint & getPoint(const unsigned int _index)
error that can be emited by ViSP classes.
Definition: vpException.h:75
unsigned int nbpt
Number of points used to define the polygon.
Definition: vpMbtPolygon.h:73
void set_X(const double X)
Set the point X coordinate in the camera frame.
Definition: vpPoint.h:176
Class that defines what is a point.
Definition: vpPoint.h:65
void addPoint(const unsigned int n, const vpPoint &P)
void set_Z(const double Z)
Set the point Z coordinate in the camera frame.
Definition: vpPoint.h:180
Generic class defining intrinsic camera parameters.
std::vector< vpImagePoint > getRoi(const vpCameraParameters &_cam)
void set_Y(const double Y)
Set the point Y coordinate in the camera frame.
Definition: vpPoint.h:178
double get_Y() const
Get the point Y coordinate in the camera frame.
Definition: vpPoint.h:120
double get_Z() const
Get the point Z coordinate in the camera frame.
Definition: vpPoint.h:122
bool isappearing
flag to specify whether the face is appearing or not
Definition: vpMbtPolygon.h:77
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
static double dotProd(const vpColVector &a, const vpColVector &b)
Dot Product.
static void getMinMaxRoi(const std::vector< vpImagePoint > &roi, int &i_min, int &i_max, int &j_min, int &j_max)
unsigned int getHeight() const
Definition: vpImage.h:145
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
static bool roiInsideImage(const vpImage< unsigned char > &I, const std::vector< vpImagePoint > &corners)
static vpColVector crossProd(const vpColVector &a, const vpColVector &b)
normalise the vector
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &_cP)
Definition: vpPoint.cpp:150
virtual void setNbPoint(const unsigned int nb)
bool isvisible
flag to specify whether the face is visible or not
Definition: vpMbtPolygon.h:75
vpColVector & normalize()
normalise the vector
double get_X() const
Get the point X coordinate in the camera frame.
Definition: vpPoint.h:118
vpPoint * p
corners in the object frame
Definition: vpMbtPolygon.h:79