Visual Servoing Platform  version 3.0.0
vpMbtPolygon.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Make the complete tracking of an object by using its CAD model
32  *
33  * Authors:
34  * Nicolas Melchior
35  * Romain Tallonneau
36  * Eric Marchand
37  * Aurelien Yol
38  *
39  *****************************************************************************/
40 
41 #include <limits.h>
42 
43 #include <visp3/core/vpConfig.h>
49 #include <visp3/mbt/vpMbtPolygon.h>
50 #include <visp3/core/vpPolygon.h>
51 
56  : index(-1), isvisible(false), isappearing(false),
57  useLod(false), minLineLengthThresh(50.0), minPolygonAreaThresh(2500.0), name(""),
58  hasOrientation(true)
59 {
60 }
61 
63  : vpPolygon3D(mbtp), index(mbtp.index), isvisible(mbtp.isvisible), isappearing(mbtp.isappearing),
64  useLod(mbtp.useLod), minLineLengthThresh(mbtp.minLineLengthThresh), minPolygonAreaThresh(mbtp.minPolygonAreaThresh), name(mbtp.name),
65  hasOrientation(mbtp.hasOrientation)
66 {
67  //*this = mbtp; // Should not be called by copy contructor to avoid multiple assignements.
68 }
69 
71 {
73  index = mbtp.index;
74  isvisible = mbtp.isvisible;
75  isappearing = mbtp.isappearing;
76  useLod = mbtp.useLod;
79  name = mbtp.name;
81 
82  return (*this);
83 }
84 
89 {
90 }
91 
107 bool
108 vpMbtPolygon::isVisible(const vpHomogeneousMatrix &cMo, const double alpha, const bool &modulo,
109  const vpCameraParameters &cam, const vpImage<unsigned char> &I)
110 {
111  // std::cout << "Computing angle from MBT Face (cMo, alpha)" << std::endl;
112 
113  changeFrame(cMo);
114 
115  if(nbpt <= 2) {
116  //Level of detail (LOD)
117  if(useLod) {
118  vpCameraParameters c = cam;
119  if(clippingFlag > 3) { // Contains at least one FOV constraint
120  c.computeFov(I.getWidth(), I.getHeight());
121  }
123  std::vector<vpImagePoint> roiImagePoints;
124  getRoiClipped(c, roiImagePoints);
125 
126  if (roiImagePoints.size() == 2) {
127  double x1 = roiImagePoints[0].get_u();
128  double y1 = roiImagePoints[0].get_v();
129  double x2 = roiImagePoints[1].get_u();
130  double y2 = roiImagePoints[1].get_v();
131  double length = std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
132 // std::cout << "Index=" << index << " ; Line length=" << length << " ; clippingFlag=" << clippingFlag << std::endl;
133 // vpTRACE("index=%d lenght=%f minLineLengthThresh=%f", index, length, minLineLengthThresh);
134 
135  if (length < minLineLengthThresh) {
136  isvisible = false;
137  isappearing = false;
138  return false;
139  }
140  }
141  }
142 
143  /* a line is always visible when LOD is not used */
144  isvisible = true;
145  isappearing = false;
146  return true ;
147  }
148 
149  // If the polygon has no orientation, the angle check visibility is always valid.
150  // Feature mainly used for cylinders.
151  if(!hasOrientation)
152  {
153  isvisible = true;
154  isappearing = false;
155  return true;
156  }
157 
158  //Check visibility from normal
159  //Newell's Method for calculating the normal of an arbitrary 3D polygon
160  //https://www.opengl.org/wiki/Calculating_a_Surface_Normal
161  vpColVector faceNormal(3);
162  vpColVector currentVertex, nextVertex;
163  for(unsigned int i = 0; i<nbpt; i++) {
164  currentVertex = p[i].cP;
165  nextVertex = p[(i+1) % nbpt].cP;
166 
167  faceNormal[0] += (currentVertex[1] - nextVertex[1]) * (currentVertex[2] + nextVertex[2]);
168  faceNormal[1] += (currentVertex[2] - nextVertex[2]) * (currentVertex[0] + nextVertex[0]);
169  faceNormal[2] += (currentVertex[0] - nextVertex[0]) * (currentVertex[1] + nextVertex[1]);
170  }
171  faceNormal.normalize();
172 
173  vpColVector e4(3) ;
174  vpPoint pt;
175  for (unsigned int i = 0; i < nbpt; i += 1){
176  pt.set_X(pt.get_X() + p[i].get_X());
177  pt.set_Y(pt.get_Y() + p[i].get_Y());
178  pt.set_Z(pt.get_Z() + p[i].get_Z());
179  }
180  e4[0] = -pt.get_X() / (double)nbpt;
181  e4[1] = -pt.get_Y() / (double)nbpt;
182  e4[2] = -pt.get_Z() / (double)nbpt;
183  e4.normalize();
184 
185  double angle = acos(vpColVector::dotProd(e4, faceNormal));
186 
187 // vpCTRACE << angle << "/" << vpMath::deg(angle) << "/" << vpMath::deg(alpha) << std::endl;
188 
189  if( angle < alpha || (modulo && (M_PI - angle) < alpha)) {
190  isvisible = true;
191  isappearing = false;
192 
193  if (useLod) {
194  vpCameraParameters c = cam;
195  if(clippingFlag > 3) { // Contains at least one FOV constraint
196  c.computeFov(I.getWidth(), I.getHeight());
197  }
199  std::vector<vpImagePoint> roiImagePoints;
200  getRoiClipped(c, roiImagePoints);
201 
202  vpPolygon roiPolygon(roiImagePoints);
203  double area = roiPolygon.getArea();
204 // std::cout << "After normal test ; Index=" << index << " ; area=" << area << " ; clippingFlag="
205 // << clippingFlag << std::endl;
206  if (area < minPolygonAreaThresh) {
207  isappearing = false;
208  isvisible = false;
209  return false;
210  }
211  }
212 
213  return true;
214  }
215 
216  if (angle < alpha+vpMath::rad(1) ){
217  isappearing = true;
218  }
219  else if (modulo && (M_PI - angle) < alpha+vpMath::rad(1) ){
220  isappearing = true;
221  }
222  else {
223  isappearing = false;
224  }
225 
226  isvisible = false ;
227  return false ;
228 }
229 
230 //###################################
231 // Static functions
232 //###################################
233 
279 void
280 vpMbtPolygon::setLod(const bool use_lod)
281 {
282  this->useLod = use_lod;
283 }
284 
285 
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
Implements a 3D polygon with render functionnalities like clipping.
Definition: vpPolygon3D.h:59
bool isVisible() const
Definition: vpMbtPolygon.h:107
std::string name
Name of the polygon.
Definition: vpMbtPolygon.h:80
unsigned int getWidth() const
Definition: vpImage.h:161
Implementation of an homogeneous matrix and operations on such kind of matrices.
virtual ~vpMbtPolygon()
bool hasOrientation
Boolean that specify if the polygon has an orientation or not (mainly used for cylinders) ...
Definition: vpMbtPolygon.h:82
int index
Index of the polygon. Cannot be unsigned int because default value is -1.
Definition: vpMbtPolygon.h:68
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:81
vpMbtPolygon & operator=(const vpMbtPolygon &mbtp)
void set_X(const double X)
Set the point X coordinate in the camera frame.
Definition: vpPoint.cpp:478
Class that defines what is a point.
Definition: vpPoint.h:59
vpColVector cP
Definition: vpTracker.h:77
Defines a generic 2D polygon.
Definition: vpPolygon.h:98
void changeFrame(const vpHomogeneousMatrix &cMo)
vpColVector & normalize()
void set_Z(const double Z)
Set the point Z coordinate in the camera frame.
Definition: vpPoint.cpp:482
double minLineLengthThresh
Threshold for minimum line length in pixel to consider if the line is visible or not in LOD case...
Definition: vpMbtPolygon.h:76
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:64
void computePolygonClipped(const vpCameraParameters &cam=vpCameraParameters())
Generic class defining intrinsic camera parameters.
void set_Y(const double Y)
Set the point Y coordinate in the camera frame.
Definition: vpPoint.cpp:480
double getArea() const
Definition: vpPolygon.h:144
double minPolygonAreaThresh
Threshold for minimum polygon area in pixel to consider if the polygon is visible or not in LOD case...
Definition: vpMbtPolygon.h:78
vpPolygon3D & operator=(const vpPolygon3D &mbtp)
Definition: vpPolygon3D.cpp:70
double get_Y() const
Get the point Y coordinate in the camera frame.
Definition: vpPoint.cpp:440
static double rad(double deg)
Definition: vpMath.h:104
double get_Z() const
Get the point Z coordinate in the camera frame.
Definition: vpPoint.cpp:442
unsigned int nbpt
Number of points used to define the polygon.
Definition: vpPolygon3D.h:77
bool isappearing
flag to specify whether the face is appearing or not
Definition: vpMbtPolygon.h:72
bool useLod
Flag to specify if the visibility of the polygon depends also of the current level of detail (LOD) ...
Definition: vpMbtPolygon.h:74
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
void setLod(const bool use_lod)
static double dotProd(const vpColVector &a, const vpColVector &b)
unsigned int getHeight() const
Definition: vpImage.h:152
unsigned int clippingFlag
Clipping flag.
Definition: vpPolygon3D.h:85
bool isvisible
flag to specify whether the face is visible or not
Definition: vpMbtPolygon.h:70
double get_X() const
Get the point X coordinate in the camera frame.
Definition: vpPoint.cpp:438
void computeFov(const unsigned int &w, const unsigned int &h)