36#ifndef DOXYGEN_SHOULD_SKIP_THIS
38#include <visp3/mbt/vpMbtMeEllipse.h>
40#include <visp3/core/vpDebug.h>
41#include <visp3/core/vpImagePoint.h>
42#include <visp3/core/vpRobust.h>
43#include <visp3/core/vpTrackingException.h>
44#include <visp3/me/vpMe.h>
58vpMbtMeEllipse::vpMbtMeEllipse(
const vpMbtMeEllipse &me_ellipse) :
vpMeEllipse(me_ellipse) { }
62vpMbtMeEllipse::~vpMbtMeEllipse() { }
81 bool display,
unsigned int length,
unsigned int thickness)
86 double offset =
static_cast<double>(std::floor(SobelX.
getRows() / 2.0f));
87 int height =
static_cast<int>(I.
getHeight());
88 int width =
static_cast<int>(I.
getWidth());
90 double max_iImg = height - 1.;
91 double max_jImg = width - 1.;
96 for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end(); ++it) {
97 double iSite = it->ifloat;
98 double jSite = it->jfloat;
102 double theta = computeTheta(
vpImagePoint(iSite, jSite));
104 vecSite[0] = cos(theta);
105 vecSite[1] = sin(theta);
108 double gradientX = 0;
109 double gradientY = 0;
111 for (
unsigned int i = 0; i < SobelX.
getRows(); i++) {
112 double iImg = iSite + (i - offset);
113 for (
unsigned int j = 0; j < SobelX.
getCols(); j++) {
114 double jImg = jSite + (j - offset);
126 gradientX += SobelX[i][j] * I((
unsigned int)iImg, (
unsigned int)jImg);
130 for (
unsigned int i = 0; i < SobelY.
getRows(); i++) {
131 double iImg = iSite + (i - offset);
132 for (
unsigned int j = 0; j < SobelY.
getCols(); j++) {
133 double jImg = jSite + (j - offset);
145 gradientY += SobelY[i][j] * I((
unsigned int)iImg, (
unsigned int)jImg);
149 double angle = atan2(gradientY, gradientX);
155 vecGrad[0] = cos(angle);
156 vecGrad[1] = sin(angle);
159 double angle1 = acos(vecSite * vecGrad);
160 double angle2 = acos(vecSite * (-vecGrad));
164 static_cast<int>(it->get_j() + length * sin(theta)),
vpColor::blue,
165 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
166 if (angle1 < angle2) {
168 static_cast<int>(it->get_j() + length * sin(angle)),
vpColor::red,
169 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
173 static_cast<int>(it->get_i() + length * cos(angle + M_PI)),
174 static_cast<int>(it->get_j() + length * sin(angle + M_PI)),
vpColor::red,
175 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
179 sumErrorRad += (std::min)(angle1, angle2);
187 double n11_p,
double n02_p,
bool doNotTrack,
vpImagePoint *pt1,
190 if (pt1 != NULL && pt2 != NULL) {
195 m_uc = center_p.
get_u();
196 m_vc = center_p.
get_v();
205 alpha1 = computeAngleOnEllipse(*pt1);
206 alpha2 = computeAngleOnEllipse(*pt2);
207 if ((alpha2 <= alpha1) || (std::fabs(alpha2 - alpha1) < m_arcEpsilon)) {
208 alpha2 += 2.0 * M_PI;
219 computePointOnEllipse(alpha1, ip);
223 iPc.set_uv(m_uc, m_vc);
225 sample(I, doNotTrack);
245 if (m_mask != NULL) {
247 m_expectedDensity =
static_cast<unsigned int>(list.size());
259 double n11_p,
double n02_p)
261 m_uc = center_p.
get_u();
262 m_vc = center_p.
get_v();
293 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
297 unsigned int n = numberOfSignal();
298 if ((
double)n < 0.9 * m_expectedDensity) {
326 int nbrows =
static_cast<int>(I.
getHeight());
327 int nbcols =
static_cast<int>(I.
getWidth());
329 if (std::fabs(me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
330 std::cout <<
"In vpMeEllipse::sample: ";
331 std::cout <<
"function called with sample step = 0, set to 10 dg";
332 me->setSampleStep(10.0);
336 m_expectedDensity =
static_cast<unsigned int>(floor((alpha2 - alpha1) / incr));
339 double ang = alpha1 + ((alpha2 - alpha1) -
static_cast<double>(m_expectedDensity) * incr) / 2.0;
341 for (
unsigned int i = 0; i < m_expectedDensity; i++) {
343 computePointOnEllipse(ang, iP);
347 double theta = computeTheta(iP);
354 angle.push_back(ang);
367void vpMbtMeEllipse::suppressPoints()
370 for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end();) {
unsigned int getCols() const
unsigned int getRows() const
Implementation of column vector and the associated operations.
static const vpColor blue
static void displayArrow(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)
error that can be emitted by ViSP classes.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
static double rad(double deg)
static int round(double x)
Implementation of a matrix and operations on matrices.
Class that tracks an ellipse using moving edges.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
@ NO_SUPPRESSION
Point used by the tracker.
void setDisplay(vpMeSiteDisplayType select)
vpMeSiteState getState() const
void setState(const vpMeSiteState &flag)
void initTracking(const vpImage< unsigned char > &I)
void track(const vpImage< unsigned char > &I)
Error that can be emitted by the vpTracker class and its derivatives.
@ initializationError
Tracker initialization error.