31#include <visp3/rbt/vpRBSilhouetteControlPoint.h>
32#include <visp3/core/vpTrackingException.h>
33#include <visp3/visual_features/vpFeatureBuilder.h>
34#include <visp3/core/vpRobust.h>
36#define VISP_DEBUG_RB_CONTROL_POINT 0
37#define DEGENERATE_LINE_THRESHOLD 1e-7
51 m_candidates.resize(1);
55 m_isSilhouette =
false;
68 m_site = other.m_site;
69 m_numCandidates = other.m_numCandidates;
74 m_normal = other.m_normal;
75 m_normalO = other.m_normalO;
81 m_isSilhouette = other.m_isSilhouette;
84 thetaInit = other.thetaInit;
85 m_meMaskSign = other.m_meMaskSign;
86 m_lineFeature = other.m_lineFeature;
87 m_line = other.m_line;
88 m_valid = other.m_valid;
99 m_me = std::move(other.m_me);
100 m_site = std::move(other.m_site);
101 thetaInit = std::move(other.thetaInit);
102 m_numCandidates = std::move(other.m_numCandidates);
103 m_cam = std::move(other.m_cam);
104 icpoint = std::move(other.icpoint);
105 cpoint = std::move(other.cpoint);
106 cpointo = std::move(other.cpointo);
107 m_normal = std::move(other.m_normal);
108 m_normalO = std::move(other.m_normalO);
109 xs = std::move(other.xs);
110 ys = std::move(other.ys);
111 nxs = std::move(other.nxs);
112 nys = std::move(other.nys);
113 Zs = std::move(other.Zs);
114 m_isSilhouette = std::move(other.m_isSilhouette);
115 rho = std::move(other.rho);
116 theta = std::move(other.theta);
117 m_meMaskSign = std::move(other.m_meMaskSign);
118 m_lineFeature = std::move(other.m_lineFeature);
119 m_line = std::move(other.m_line);
120 m_valid = std::move(other.m_valid);
121 m_candidates = std::move(other.m_candidates);
130 if (m_site.m_convlt == 0) {
131 m_site.track(I, m_me,
false);
134 m_site.track(I, m_me,
false);
138 vpERROR_TRACE(
"caught a tracking exception, ignoring me point...");
150 m_site.trackMultipleHypotheses(I, *m_me,
false, m_candidates, m_numCandidates);
151 m_site = m_candidates[0];
155 vpERROR_TRACE(
"caught a tracking exception, ignoring me point...");
179 buildPlane(
cpoint, m_normal, plane);
185 if (abs(theta) > 1e-2) {
198 buildPlane(
cpointo, norm2, plane2);
199 buildPlane(
cpointo, m_normalO, plane1);
201 m_line.setWorldCoordinates(plane1.
getA(), plane1.
getB(), plane1.
getC(), plane1.
getD(),
217 double px = m_cam->get_px();
218 double py = m_cam->get_py();
219 int jc =
static_cast<int>(m_cam->get_u0());
220 int ic =
static_cast<int>(m_cam->get_v0());
226 rho = x*cos(theta)+y*sin(theta);
227 cpoint.setWorldCoordinates(x*Z, y*Z, Z);
231 m_normal = R * normo;
235 m_valid = !isLineDegenerate();
243 m_isSilhouette =
true;
249 double px = m_cam->get_px();
250 double py = m_cam->get_py();
251 int jc =
static_cast<int>(m_cam->get_u0());
252 int ic =
static_cast<int>(m_cam->get_v0());
264 cpoint.setWorldCoordinates(x * Z, y * Z, Z);
268 m_normal = R * normo;
270#if VISP_DEBUG_RB_CONTROL_POINT
271 if (std::isnan(m_line.getTheta())) {
272 std::cerr <<
"Line in camera frame = " << m_line.cP << std::endl;
277 m_valid = isLineDegenerate();
285 double px = m_cam->get_px();
286 double py = m_cam->get_py();
287 double uc = m_cam->get_u0();
288 double vc = m_cam->get_v0();
300 const double px = m_cam->get_px();
301 const double py = m_cam->get_py();
302 const double uc = m_cam->get_u0();
303 const double vc = m_cam->get_v0();
304 const double v = py *
cpointo.get_y() + vc;
305 const double u = px *
cpointo.get_x() + uc;
310 m_normal = cRo * m_normalO;
313 if (acos(cameraRayObject * m_normal) <
vpMath::rad(75.0)) {
319 m_line.changeFrame(cMo);
325 m_valid = !isLineDegenerate() && !std::isnan(m_line.getTheta());
328 theta = m_lineFeature.getTheta();
329#if VISP_DEBUG_RB_CONTROL_POINT
330 if (std::isnan(theta)) {
334 if (fabs(theta - thetaInit) < M_PI / 2.0) {
348 m_site.
init(
static_cast<double>(
icpoint.get_i()),
static_cast<double>(
icpoint.get_j()), theta, cvlt, m_meMaskSign);
349 if (m_me !=
nullptr) {
350 const double marginRatio = m_me->getThresholdMarginRatio();
351 const double convolution = m_site.convolution(I, m_me);
352 m_site.init(
static_cast<double>(
icpoint.get_i()),
static_cast<double>(
icpoint.get_j()), theta, convolution, m_meMaskSign);
353 const double contrastThreshold = fabs(convolution) * marginRatio;
354 m_site.setContrastThreshold(contrastThreshold, *m_me);
366 m_line.changeFrame(cMo);
369 if (!isLineDegenerate()) {
373 double rho0 = m_lineFeature.getRho();
374 double theta0 = m_lineFeature.getTheta();
375#if VISP_DEBUG_RB_CONTROL_POINT
376 if (std::isnan(theta0)) {
377 std::cerr <<
"Line in camera frame = " << m_line.cP.t() << std::endl;
378 std::cerr <<
"Line in object frame = " << m_line.oP.t() << std::endl;
379 m_lineFeature.print();
383 double co = cos(theta0);
384 double si = sin(theta0);
386 double mx = 1.0 / m_cam->get_px();
387 double my = 1.0 / m_cam->get_py();
388 double xc = m_cam->get_u0();
389 double yc = m_cam->get_v0();
392 H = m_lineFeature.interaction();
393 double x =
static_cast<double>(m_site.m_j), y =
static_cast<double>(m_site.m_i);
398 const double alpha = x*si - y*co;
401 double *Ltheta = H[1];
403 for (
unsigned int k = 0; k < 6; k++) {
404 L[i][k] = (Lrho[k] + alpha*Ltheta[k]);
406 e[i] = rho0 - (x*co + y*si);
412 for (
unsigned int k = 0; k < 6; k++) {
422 m_line.changeFrame(cMo);
425 if (!isLineDegenerate()) {
429 const double rho0 = m_lineFeature.getRho();
430 const double theta0 = m_lineFeature.getTheta();
431#if VISP_DEBUG_RB_CONTROL_POINT
432 if (std::isnan(theta0)) {
437 const double co = cos(theta0);
438 const double si = sin(theta0);
440 const double mx = 1.0 / m_cam->get_px();
441 const double my = 1.0 / m_cam->get_py();
442 const double xc = m_cam->get_u0();
443 const double yc = m_cam->get_v0();
444 const vpMatrix &H = m_lineFeature.interaction();
446 double errormin = std::numeric_limits<double>::max();
448 const std::vector<vpMeSite> &cs = m_candidates;
449 xmin = (m_site.m_j - xc) * mx;
450 ymin = (m_site.m_i - yc) * my;
451 for (
unsigned int l = 0; l < m_numCandidates; l++)
456 const double x = (Pk.
m_j - xc) * mx;
457 const double y = (Pk.
m_i - yc) * my;
458 const double err = fabs(rho0 - (x * co + y * si));
459 if (err <= errormin) {
468 e[i] = rho0 - (xmin * co + ymin * si);
469 const double alpha = xmin * si - ymin * co;
471 const double *Lrho = H[0];
472 const double *Ltheta = H[1];
474 for (
unsigned int k = 0; k < 6; k++) {
475 L[i][k] = (Lrho[k] + alpha * Ltheta[k]);
480 for (
unsigned int k = 0; k < 6; k++) {
490 std::vector<float> maskValues(searchSize * 2 + 1);
491 double c = cos(theta);
492 double s = sin(theta);
494 for (
int n = -searchSize + 1; n < searchSize; ++n) {
495 unsigned int ii =
static_cast<unsigned int>(round(
icpoint.get_i() + s * n));
496 unsigned int jj =
static_cast<unsigned int>(round(
icpoint.get_j() + c * n));
498 maskValues[index] = mask[ii][jj];
502 double maxGrad = 0.0;
504 for (
unsigned i = 1; i < maskValues.size() - 1; ++i) {
505 double grad = abs(maskValues[i + 1] - maskValues[i - 1]);
506 if (grad > maxGrad) {
515 double cs = cos(theta) *
static_cast<double>(searchSize);
516 double ss = sin(theta) *
static_cast<double>(searchSize);
518 std::array<std::pair<int, int>, 2> extremities = {
519 std::make_pair(
static_cast<int>(round(
icpoint.get_i() + ss)),
static_cast<int>(round(
icpoint.get_j() + cs))),
520 std::make_pair(
static_cast<int>(round(
icpoint.get_i() - ss)),
static_cast<int>(round(
icpoint.get_j() - cs)))
523 int width =
static_cast<int>(w);
524 int height =
static_cast<int>(h);
525 for (
unsigned int e = 0; e < 2; ++e) {
526 int i = extremities[e].first;
527 int j = extremities[e].second;
528 if (i < 0 || i >= height || j < 0 || j >= width) {
536bool vpRBSilhouetteControlPoint::isLineDegenerate()
const
539 a = m_line.
cP[4] * m_line.
cP[3] - m_line.
cP[0] * m_line.
cP[7];
540 b = m_line.
cP[5] * m_line.
cP[3] - m_line.
cP[1] * m_line.
cP[7];
542 return d <= DEGENERATE_LINE_THRESHOLD;
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
vpColVector & normalize()
void init(const vpColVector &v, unsigned int r, unsigned int nrows)
static vpColVector cross(const vpColVector &a, const vpColVector &b)
error that can be emitted by ViSP classes.
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void extract(vpRotationMatrix &R) const
Definition of the vpImage class member functions.
static double rad(double deg)
Implementation of a matrix and operations on matrices.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
@ THRESHOLD
Point not tracked due to the likelihood that is below the threshold, but retained in the ME list.
@ NO_SUPPRESSION
Point successfully tracked.
vpMeSiteState getState() const
int m_j
Integer coordinates along j of a site.
int m_i
Integer coordinate along i of a site.
This class defines the container for a plane geometrical structure.
vpPlane & init(const vpPoint &P, const vpColVector &normal, const vpPlaneFrame &frame=camera_frame)
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
bool isSilhouette() const
void buildSilhouettePoint(int n, int m, const double &Z, double orient, const vpColVector &normo, const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &oMc, const vpCameraParameters &cam)
double getMaxMaskGradientAlongLine(const vpImage< float > &mask, int searchSize) const
vpRBSilhouetteControlPoint & operator=(const vpRBSilhouetteControlPoint &meTracker)
void trackMultipleHypotheses(const vpImage< unsigned char > &I)
Track the moving edge and retain the best numCandidates hypotheses.
vpRBSilhouetteControlPoint()
void computeMeInteractionMatrixError(const vpHomogeneousMatrix &cMo, unsigned int i, vpMatrix &L, vpColVector &e)
void track(const vpImage< unsigned char > &I)
Track the moving edge at this point retaining only the hypothesis with the highest likelihood.
bool tooCloseToBorder(unsigned int h, unsigned int w, int searchSize) const
void initControlPoint(const vpImage< unsigned char > &I, double cvlt)
void update(const vpHomogeneousMatrix &_cMo)
void updateSilhouettePoint(const vpHomogeneousMatrix &_cMo, const vpRotationMatrix &cRo)
void buildPoint(int n, int m, const double &Z, double orient, const vpColVector &normo, const vpHomogeneousMatrix &cMo, const vpHomogeneousMatrix &oMc, const vpCameraParameters &cam, const vpMe &me, bool isSilhouette)
void computeMeInteractionMatrixErrorMH(const vpHomogeneousMatrix &cMo, unsigned int i, vpMatrix &L, vpColVector &e)
Implementation of a rotation matrix and operations on such kind of matrices.
Error that can be emitted by the vpTracker class and its derivatives.