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>
54 vpMbtMeEllipse::vpMbtMeEllipse() :
vpMeEllipse() { }
59 vpMbtMeEllipse::vpMbtMeEllipse(
const vpMbtMeEllipse &me_ellipse) :
vpMeEllipse(me_ellipse) { }
78 bool display,
unsigned int length,
unsigned int thickness)
83 double offset =
static_cast<double>(std::floor(SobelX.
getRows() / 2.0f));
84 int height =
static_cast<int>(I.
getHeight());
85 int width =
static_cast<int>(I.
getWidth());
87 double max_iImg = height - 1.;
88 double max_jImg = width - 1.;
93 for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end(); ++it) {
94 double iSite = it->m_ifloat;
95 double jSite = it->m_jfloat;
101 vecSite[0] = cos(theta);
102 vecSite[1] = sin(theta);
105 double gradientX = 0;
106 double gradientY = 0;
108 for (
unsigned int i = 0; i < SobelX.
getRows(); i++) {
109 double iImg = iSite + (i - offset);
110 for (
unsigned int j = 0; j < SobelX.
getCols(); j++) {
111 double jImg = jSite + (j - offset);
123 gradientX += SobelX[i][j] * I((
unsigned int)iImg, (
unsigned int)jImg);
127 for (
unsigned int i = 0; i < SobelY.
getRows(); i++) {
128 double iImg = iSite + (i - offset);
129 for (
unsigned int j = 0; j < SobelY.
getCols(); j++) {
130 double jImg = jSite + (j - offset);
142 gradientY += SobelY[i][j] * I((
unsigned int)iImg, (
unsigned int)jImg);
146 double angle = atan2(gradientY, gradientX);
152 vecGrad[0] = cos(angle);
153 vecGrad[1] = sin(angle);
156 double angle1 = acos(vecSite * vecGrad);
157 double angle2 = acos(vecSite * (-vecGrad));
161 static_cast<int>(it->get_j() + length * sin(theta)),
vpColor::blue,
162 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
163 if (angle1 < angle2) {
165 static_cast<int>(it->get_j() + length * sin(angle)),
vpColor::red,
166 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
170 static_cast<int>(it->get_i() + length * cos(angle + M_PI)),
171 static_cast<int>(it->get_j() + length * sin(angle + M_PI)),
vpColor::red,
172 length >= 20 ? length / 5 : 4, length >= 20 ? length / 10 : 2, thickness);
176 sumErrorRad += std::min<double>(angle1, angle2);
184 double n11_p,
double n02_p,
bool doNotTrack,
vpImagePoint *pt1,
187 if (pt1 !=
nullptr && pt2 !=
nullptr) {
192 m_uc = center_p.
get_u();
193 m_vc = center_p.
get_v();
202 m_alpha1 = computeAngleOnEllipse(*pt1);
203 m_alpha2 = computeAngleOnEllipse(*pt2);
204 if ((m_alpha2 <= m_alpha1) || (std::fabs(m_alpha2 - m_alpha1) < m_arcEpsilon)) {
205 m_alpha2 += 2.0 * M_PI;
213 m_alpha2 = 2.0 * M_PI;
216 computePointOnEllipse(m_alpha1, ip);
223 sample(I, doNotTrack);
243 if (m_mask !=
nullptr) {
245 m_expectedDensity =
static_cast<unsigned int>(m_meList.size());
257 double n11_p,
double n02_p)
259 m_uc = center_p.
get_u();
260 m_vc = center_p.
get_v();
291 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
295 unsigned int n = numberOfSignal();
296 if ((
double)n < 0.9 * m_expectedDensity) {
324 int nbrows =
static_cast<int>(I.
getHeight());
325 int nbcols =
static_cast<int>(I.
getWidth());
327 if (std::fabs(m_me->getSampleStep()) <= std::numeric_limits<double>::epsilon()) {
328 std::cout <<
"In vpMeEllipse::sample: ";
329 std::cout <<
"function called with sample step = 0, set to 10 dg";
330 m_me->setSampleStep(10.0);
334 m_expectedDensity =
static_cast<unsigned int>(floor((m_alpha2 - m_alpha1) / incr));
337 double ang = m_alpha1 + ((m_alpha2 - m_alpha1) -
static_cast<double>(m_expectedDensity) * incr) / 2.0;
339 for (
unsigned int i = 0; i < m_expectedDensity; i++) {
341 computePointOnEllipse(ang, iP);
345 double theta = computeTheta(iP);
351 m_meList.push_back(pix);
352 m_angleList.push_back(ang);
365 void vpMbtMeEllipse::suppressPoints()
368 for (std::list<vpMeSite>::iterator it = m_meList.begin(); it != m_meList.end();) {
371 it = m_meList.erase(it);
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 ...
void set_uv(double u, double v)
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 successfully tracked.
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.