38 #ifndef DOXYGEN_SHOULD_SKIP_THIS
40 #include <visp3/mbt/vpMbtMeEllipse.h>
42 #include <visp3/me/vpMe.h>
43 #include <visp3/core/vpRobust.h>
44 #include <visp3/core/vpTrackingException.h>
45 #include <visp3/core/vpDebug.h>
46 #include <visp3/core/vpImagePoint.h>
56 vpMbtMeEllipse::vpMbtMeEllipse()
57 : iPc(), a(0.), b(0.), e(0.),
58 ce(0.), se(0.), mu11(0.), mu20(0.), mu02(0.), thresholdWeight(0.), expecteddensity(0.)
65 vpMbtMeEllipse::vpMbtMeEllipse(
const vpMbtMeEllipse &meellipse)
66 :
vpMeTracker(meellipse), iPc(), a(0.), b(0.), e(0.),
67 ce(0.), se(0.), mu11(0.), mu20(0.), mu02(0.), thresholdWeight(0.), expecteddensity(0.)
77 mu11 = meellipse.mu11;
78 mu20 = meellipse.mu20;
79 mu02 = meellipse.mu02;
81 expecteddensity = meellipse.expecteddensity;
87 vpMbtMeEllipse::~vpMbtMeEllipse()
102 vpMbtMeEllipse::computeProjectionError(
const vpImage<unsigned char>& _I,
double &_sumErrorRad,
unsigned int &_nbFeatures)
195 double offset = std::floor(filterX.getRows() / 2.0f);
200 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ++it){
201 double iSite = it->ifloat;
202 double jSite = it->jfloat;
206 double theta = atan( (-mu02*jSite + mu02*iPc.get_j() + mu11*iSite - mu11*iPc.get_i())
207 / (mu20*iSite - mu11*jSite + mu11*iPc.get_j() - mu20*iPc.get_i()))
210 double deltaNormalized = theta;
211 while (deltaNormalized<0) deltaNormalized += M_PI;
212 while (deltaNormalized>M_PI) deltaNormalized -= M_PI;
215 vecSite[0] = cos(deltaNormalized);
216 vecSite[1] = sin(deltaNormalized);
219 double gradientX = 0;
220 double gradientY = 0;
222 for(
unsigned int i = 0; i<filterX.getRows() ; i++){
223 double iImg = iSite + (i - offset);
224 for (
unsigned int j = 0; j< filterX.getCols(); j++){
225 double jImg = jSite + (j-offset);
227 if(iImg < 0) iImg = 0.0;
228 if(jImg < 0) jImg = 0.0;
233 gradientX += filterX[i][j] * _I((
unsigned int)iImg, (
unsigned int)jImg);
237 for(
unsigned int i = 0; i<filterY.getRows() ; i++){
238 double iImg = iSite + (i - offset);
239 for (
unsigned int j = 0; j< filterY.getCols(); j++){
240 double jImg = jSite + (j-offset);
242 if(iImg < 0) iImg = 0.0;
243 if(jImg < 0) jImg = 0.0;
248 gradientY += filterY[i][j] * _I((
unsigned int)iImg, (
unsigned int)jImg);
252 double angle = atan2(gradientY,gradientX);
253 while (angle<0) angle += M_PI;
254 while (angle>M_PI) angle -= M_PI;
267 vecGrad[0] = cos(angle);
268 vecGrad[1] = sin(angle);
271 double angle1 = acos(vecSite * vecGrad);
272 double angle2 = acos(vecSite * (-vecGrad));
274 _sumErrorRad += std::min(angle1,angle2);
295 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
297 "Moving edges not initialized")) ;
304 if (std::fabs(me->getSampleStep()) <= std::numeric_limits<double>::epsilon())
306 std::cout <<
"In vpMbtMeEllipse::sample: " ;
307 std::cout <<
"function called with sample step = 0" ;
314 double t = (a-b)/(a+b);
316 int nb_points_to_track = (int)(circumference / me->getSampleStep());
317 double incr = 2*M_PI/nb_points_to_track;
326 for (
int pt=0; pt < nb_points_to_track; pt++)
328 double j = a *cos(k) ;
329 double i = b *sin(k) ;
331 double iP_j = iPc.get_j() + ce *j - se *i;
332 double iP_i = iPc.get_i() + se *j + ce *i;
341 double theta = atan( (-mu02*iP_j + mu02*iPc.get_j() + mu11*iP_i - mu11*iPc.get_i())
342 / (mu20*iP_i - mu11*iP_j + mu11*iPc.get_j() - mu20*iPc.get_i()))
346 pix.
init((
int)iP_i, (
int)iP_j, theta) ;
379 vpDERROR_TRACE(2,
"Tracking error: Moving edges not initialized");
381 "Moving edges not initialized")) ;
384 unsigned int n = numberOfSignal() ;
385 if ((
double)n<0.9*expecteddensity){
397 vpMbtMeEllipse::updateTheta()
400 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ++it){
407 double theta = atan( (-mu02*p_me.
jfloat + mu02*iPc.get_j() + mu11*p_me.
ifloat - mu11*iPc.get_i())
408 / (mu20*p_me.
ifloat - mu11*p_me.
jfloat + mu11*iPc.get_j() - mu20*iPc.get_i()))
420 vpMbtMeEllipse::suppressPoints()
423 for(std::list<vpMeSite>::iterator itList=list.begin(); itList!=list.end();){
426 itList = list.erase(itList);
449 double mu20_p,
double mu11_p,
double mu02_p)
456 if (std::fabs(mu11_p) > std::numeric_limits<double>::epsilon()) {
459 a = sqrt((mu20_p + mu02_p + val_p)/2);
460 b = sqrt((mu20_p + mu02_p - val_p)/2);
462 e = (mu02_p - mu20_p + val_p)/(2*mu11_p);
513 if (std::fabs(mu11_p) > std::numeric_limits<double>::epsilon()) {
516 a = sqrt((mu20_p + mu02_p + val_p)/2);
517 b = sqrt((mu20_p + mu02_p - val_p)/2);
519 e = (mu02_p - mu20_p + val_p)/(2*mu11_p);
539 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
Implementation of a matrix and operations on matrices.
static void displayEllipse(const vpImage< unsigned char > &I, const vpImagePoint ¢er, const double &coef1, const double &coef2, const double &coef3, bool use_centered_moments, const vpColor &color, unsigned int thickness=1)
unsigned int getWidth() const
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Class to define colors available for display functionnalities.
error that can be emited by ViSP classes.
static int round(const double x)
vpMeSiteState getState() const
void set_i(const double ii)
Error that can be emited by the vpTracker class and its derivates.
static double sqr(double x)
void setDisplay(vpMeSiteDisplayType select)
void track(const vpImage< unsigned char > &I)
Track sampled pixels.
Contains abstract elements for a Distance to Feature type feature.
void setState(const vpMeSiteState &flag)
void set_j(const double jj)
Implementation of column vector and the associated operations.
void initTracking(const vpImage< unsigned char > &I)
unsigned int getHeight() const
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...