Visual Servoing Platform version 3.5.0
vpMbtPolygon.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Make the complete tracking of an object by using its CAD model
33 *
34 * Authors:
35 * Nicolas Melchior
36 * Romain Tallonneau
37 * Eric Marchand
38 * Aurelien Yol
39 *
40 *****************************************************************************/
41
42#include <limits.h>
43
44#include <visp3/core/vpConfig.h>
50#include <visp3/core/vpPolygon.h>
51#include <visp3/mbt/vpMbtPolygon.h>
52
57 : index(-1), isvisible(false), isappearing(false), useLod(false), minLineLengthThresh(50.0),
58 minPolygonAreaThresh(2500.0), name(""), hasOrientation(true)
59{
60}
61
63 : vpPolygon3D(mbtp), index(mbtp.index), isvisible(mbtp.isvisible), isappearing(mbtp.isappearing), useLod(mbtp.useLod),
64 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
68 // assignements.
69}
70
72{
74 index = mbtp.index;
75 isvisible = mbtp.isvisible;
77 useLod = mbtp.useLod;
80 name = mbtp.name;
82
83 return (*this);
84}
85
90
107bool vpMbtPolygon::isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo,
108 const vpCameraParameters &cam, unsigned int width, unsigned int height)
109{
110 // std::cout << "Computing angle from MBT Face (cMo, alpha)" << std::endl;
111
112 changeFrame(cMo);
113
114 if (nbpt <= 2) {
115 // Level of detail (LOD)
116 if (useLod) {
117 vpCameraParameters c = cam;
118 if (clippingFlag > 3) { // Contains at least one FOV constraint
119 c.computeFov(width, height);
120 }
122 std::vector<vpImagePoint> roiImagePoints;
123 getRoiClipped(c, roiImagePoints);
124
125 if (roiImagePoints.size() == 2) {
126 double x1 = roiImagePoints[0].get_u();
127 double y1 = roiImagePoints[0].get_v();
128 double x2 = roiImagePoints[1].get_u();
129 double y2 = roiImagePoints[1].get_v();
130 double length = std::sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
131 // std::cout << "Index=" << index << " ; Line length=" <<
132 // length << " ; clippingFlag=" << clippingFlag << std::endl;
133 // vpTRACE("index=%d lenght=%f minLineLengthThresh=%f", index,
134 // length, minLineLengthThresh);
135
136 if (length < minLineLengthThresh) {
137 isvisible = false;
138 isappearing = false;
139 return false;
140 }
141 }
142 }
143
144 /* a line is always visible when LOD is not used */
145 isvisible = true;
146 isappearing = false;
147 return true;
148 }
149
150 // If the polygon has no orientation, the angle check visibility is always
151 // valid. Feature mainly used for cylinders.
152 if (!hasOrientation) {
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) << "/" <<
188 // vpMath::deg(alpha) << std::endl;
189
190 if (angle < alpha || (modulo && (M_PI - angle) < alpha)) {
191 isvisible = true;
192 isappearing = false;
193
194 if (useLod) {
195 vpCameraParameters c = cam;
196 if (clippingFlag > 3) { // Contains at least one FOV constraint
197 c.computeFov(width, height);
198 }
200 std::vector<vpImagePoint> roiImagePoints;
201 getRoiClipped(c, roiImagePoints);
202
203 vpPolygon roiPolygon(roiImagePoints);
204 double area = roiPolygon.getArea();
205 // std::cout << "After normal test ; Index=" << index << " ; area="
206 // << area << " ; clippingFlag="
207 // << clippingFlag << std::endl;
208 if (area < minPolygonAreaThresh) {
209 isappearing = false;
210 isvisible = false;
211 return false;
212 }
213 }
214
215 return true;
216 }
217
218 if (angle < alpha + vpMath::rad(1)) {
219 isappearing = true;
220 } else if (modulo && (M_PI - angle) < alpha + vpMath::rad(1)) {
221 isappearing = true;
222 } else {
223 isappearing = false;
224 }
225
226 isvisible = false;
227 return false;
228}
229
230//###################################
231// Static functions
232//###################################
233
277void vpMbtPolygon::setLod(bool use_lod) { this->useLod = use_lod; }
Generic class defining intrinsic camera parameters.
void computeFov(const unsigned int &w, const unsigned int &h)
Implementation of column vector and the associated operations.
Definition: vpColVector.h:131
static double dotProd(const vpColVector &a, const vpColVector &b)
vpColVector & normalize()
Implementation of an homogeneous matrix and operations on such kind of matrices.
static double rad(double deg)
Definition: vpMath.h:110
Implementation of a polygon of the model used by the model-based tracker.
Definition: vpMbtPolygon.h:67
bool isvisible
flag to specify whether the face is visible or not
Definition: vpMbtPolygon.h:73
bool hasOrientation
Definition: vpMbtPolygon.h:89
double minLineLengthThresh
Definition: vpMbtPolygon.h:81
void setLod(bool use_lod)
double minPolygonAreaThresh
Definition: vpMbtPolygon.h:84
virtual ~vpMbtPolygon()
bool isappearing
flag to specify whether the face is appearing or not
Definition: vpMbtPolygon.h:75
std::string name
Name of the polygon.
Definition: vpMbtPolygon.h:86
bool isVisible() const
Definition: vpMbtPolygon.h:115
vpMbtPolygon & operator=(const vpMbtPolygon &mbtp)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:82
double get_Y() const
Get the point cY coordinate in the camera frame.
Definition: vpPoint.cpp:454
void set_X(double cX)
Set the point cX coordinate in the camera frame.
Definition: vpPoint.cpp:493
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
Definition: vpPoint.cpp:495
double get_Z() const
Get the point cZ coordinate in the camera frame.
Definition: vpPoint.cpp:456
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
Definition: vpPoint.cpp:497
double get_X() const
Get the point cX coordinate in the camera frame.
Definition: vpPoint.cpp:452
Implements a 3D polygon with render functionnalities like clipping.
Definition: vpPolygon3D.h:60
void changeFrame(const vpHomogeneousMatrix &cMo)
unsigned int nbpt
Number of points used to define the polygon.
Definition: vpPolygon3D.h:76
vpPoint * p
corners in the object frame
Definition: vpPolygon3D.h:81
void computePolygonClipped(const vpCameraParameters &cam=vpCameraParameters())
unsigned int clippingFlag
Clipping flag.
Definition: vpPolygon3D.h:85
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
vpPolygon3D & operator=(const vpPolygon3D &mbtp)
Definition: vpPolygon3D.cpp:70
Defines a generic 2D polygon.
Definition: vpPolygon.h:104
double getArea() const
Definition: vpPolygon.h:161
vpColVector cP
Definition: vpTracker.h:77