48 #include <visp/vpMeTracker.h>
49 #include <visp/vpMe.h>
50 #include <visp/vpMeSite.h>
51 #include <visp/vpMeNurbs.h>
52 #include <visp/vpRobust.h>
53 #include <visp/vpTrackingException.h>
54 #include <visp/vpImagePoint.h>
55 #include <visp/vpMath.h>
56 #include <visp/vpRect.h>
57 #include <visp/vpImageTools.h>
58 #include <visp/vpImageConvert.h>
62 #ifdef VISP_HAVE_OPENCV
63 # if (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
65 # include <opencv2/imgproc/imgproc_c.h>
74 computeDelta(
double deltai,
double deltaj)
77 delta = atan2(deltai,deltaj) ;
79 while (delta > M_PI) { delta -= M_PI ; }
80 while (delta < 0) { delta += M_PI ; }
87 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
89 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
90 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
98 vpMe* me,
double &angle,
double &convlt)
104 for (
int i = 0; i < 180; i++)
111 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
122 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
123 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
124 unsigned int ihalfa ;
132 conv += me->
getMask()[index_mask][a][b] *
143 while (angle > M_PI) { angle -= M_PI ; }
144 while (angle < 0) { angle += M_PI ; }
160 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
162 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
169 if (dist <= 16 && dist < dist_1)
181 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
186 ip_edges_list->
front();
188 while (!ip_edges_list->
outside())
196 ip_edges_list->
next();
204 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
207 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
225 nbControlPoints = 20;
228 enableCannyDetection =
false;
240 nbControlPoints = menurbs.nbControlPoints;
241 beginPtFound = menurbs.beginPtFound;
242 endPtFound = menurbs.endPtFound;
243 enableCannyDetection = menurbs.enableCannyDetection;
244 cannyTh1 = menurbs.cannyTh1;
245 cannyTh2 = menurbs.cannyTh2;
265 std::list<vpImagePoint> ptList;
274 ptList.push_back(pt);
280 if (ptList.size() > 3)
286 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
301 std::list<vpImagePoint> listStd;
303 listStd.push_back(ptList.
value());
323 const std::list<vpImagePoint> &ptList)
355 if (pt!=NULL)
delete[] pt;
357 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
363 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
371 if (pt!=NULL)
delete[] pt;
384 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
407 std::list<vpMeSite>::iterator it=
list.begin();
412 while (u < 1 && it!=
list.end())
416 while (d <= d_1 && u<1)
425 if (der != NULL)
delete[] der;
430 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
436 if (der != NULL)
delete[] der;
469 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
473 unsigned int memory_range = me->
getRange() ;
477 bool beginPtAdded =
false;
479 double angle = atan2(begin[1].get_i(),begin[1].get_j());
484 for (
int i=0 ; i < 3 ; i++)
511 if (!beginPtAdded) beginPtFound++;
513 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
516 bool endPtAdded =
false;
517 angle = atan2(end[1].get_i(),end[1].get_j());
522 for (
int i=0 ; i < 3 ; i++)
547 if (!endPtAdded) endPtFound++;
554 if(begin != NULL)
delete[] begin;
555 if(end != NULL)
delete[] end;
570 #ifdef VISP_HAVE_OPENCV
578 #ifdef VISP_HAVE_OPENCV
583 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
586 begin = nurbs.computeCurveDersPoint(0.0,1);
588 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
589 vpRect rect(topLeft,32,32);
599 while (inRectangle(lastPtInSubIm,rect) && u < 1)
602 lastPtInSubIm = nurbs.computeCurvePoint(u);
607 lastPtInSubIm = nurbs.computeCurvePoint(u);
613 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
614 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
620 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
622 std::list<vpImagePoint> ip_edges_list;
626 double fi = firstBorder.
get_i();
627 double fj = firstBorder.
get_j();
631 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
633 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
635 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
637 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
638 computeFreemanChainElement(Isub, firstBorder , dir);
639 unsigned int firstDir = dir;
640 ip_edges_list.push_back( firstBorder );
645 computeFreemanParameters(dir, dBorder);
646 border = border + dBorder;
649 ip_edges_list.push_back( border );
651 computeFreemanChainElement(Isub, border , dir);
652 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
655 if (findCenterPoint(&ip_edges_list))
657 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
660 if (inRectangle(iP,rect))
661 it = list.erase(it) ;
666 std::list<vpMeSite>::iterator itList=list.begin();
670 std::list<vpMeSite> addedPt;
671 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
680 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
687 findAngle(I, iPtemp, me, delta, convlt);
691 list.insert(itList, pix);
693 addedPt.push_front(pix);
699 unsigned int memory_range = me->
getRange();
701 std::list<vpMeSite>::iterator itList2=list.begin();
702 for (
int j = 0; j < nbr; j++)
712 if (begin != NULL)
delete[] begin;
716 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
719 end = nurbs.computeCurveDersPoint(1.0,1);
722 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
723 vpRect rect(topLeft,32,32);
733 while (inRectangle(lastPtInSubIm,rect) && u > 0)
736 lastPtInSubIm = nurbs.computeCurvePoint(u);
741 lastPtInSubIm = nurbs.computeCurvePoint(u);
747 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
748 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
754 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
756 std::list<vpImagePoint> ip_edges_list;
760 double fi = firstBorder.
get_i();
761 double fj = firstBorder.
get_j();
765 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
767 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
769 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
771 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
774 computeFreemanChainElement(Isub, firstBorder , dir);
775 unsigned int firstDir = dir;
776 ip_edges_list.push_back( firstBorder );
781 computeFreemanParameters(dir, dBorder);
782 border = border + dBorder;
785 ip_edges_list.push_back( border );
787 computeFreemanChainElement(Isub, border , dir);
788 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
791 if (findCenterPoint(&ip_edges_list))
799 if (inRectangle(iP,rect))
801 list.erase(list.end()) ;
808 std::list<vpMeSite>::iterator itList = list.end();
812 std::list<vpMeSite> addedPt;
813 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
822 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
829 findAngle(I, iPtemp, me, delta, convlt);
833 addedPt.push_back(pix);
839 unsigned int memory_range = me->
getRange();
841 std::list<vpMeSite>::iterator itList2 = list.end();
842 for (
int j = 0; j < nbr; j++)
852 if (end != NULL)
delete[] end;
856 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
877 if ((
double)n < 0.7*nbPt)
901 std::list<vpMeSite>::iterator it=
list.begin();
902 std::list<vpMeSite>::iterator itNext=
list.begin();
905 unsigned int range_tmp = me->
getRange();
923 double dmin1_1 = 1e6;
924 double dmin2_1 = 1e6;
946 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
947 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon()))
961 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
963 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
965 pix.
track(I,me,
false);
968 list.insert(it, pix);
997 while(!
list.nextOutside())
1007 list.modify(s_next);
1008 if (!
list.nextOutside())
list.next();
1014 std::list<vpMeSite>::const_iterator it=
list.begin();
1015 std::list<vpMeSite>::iterator itNext=
list.begin();
1017 for(;itNext!=
list.end();){
1027 if(itNext!=
list.end()){
1065 if(enableCannyDetection)
1079 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1127 unsigned int &element)
1131 if (hasGoodLevel( I, iP )) {
1133 computeFreemanParameters((element + 2) %8, diP);
1135 if (hasGoodLevel( I, iPtemp )) {
1136 element = (element + 2) % 8;
1139 computeFreemanParameters((element + 1) %8, diP);
1142 if ( hasGoodLevel( I, iPtemp )) {
1143 element = (element + 1) % 8;
1146 computeFreemanParameters(element, diP);
1149 if ( hasGoodLevel( I, iPtemp )) {
1153 computeFreemanParameters((element + 7) %8, diP);
1156 if ( hasGoodLevel( I, iPtemp )) {
1157 element = (element + 7) %8;
1160 computeFreemanParameters((element + 6) %8, diP);
1163 if ( hasGoodLevel( I, iPtemp )) {
1164 element = (element + 6) %8 ;
1167 computeFreemanParameters((element + 5) %8, diP);
1170 if ( hasGoodLevel( I, iPtemp )) {
1171 element = (element + 5) %8 ;
1174 computeFreemanParameters((element + 4) %8, diP);
1177 if ( hasGoodLevel( I, iPtemp )) {
1178 element = (element + 4) %8 ;
1181 computeFreemanParameters((element + 3) %8, diP);
1184 if ( hasGoodLevel( I, iPtemp )) {
1185 element = (element + 3) %8 ;
1222 if( !isInImage( I, iP ) )
1248 return (iP.
get_i() >= 0
1271 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1331 return (iP.
get_i() < height - 20
1332 && iP.
get_j() < width - 20
1334 && iP.
get_j() > 20);
unsigned int getRange() const
unsigned int getMaskSize() const
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
unsigned int getWidth() const
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
unsigned int numberOfSignal()
static vpImagePoint computeCurvePoint(double l_u, unsigned int l_i, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
Provide simple list management.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Class to define colors available for display functionnalities.
int outOfImage(int i, int j, int half, int rows, int cols)
error that can be emited by ViSP classes.
static void globalCurveInterp(std::vector< vpImagePoint > &l_crossingPoints, unsigned int l_p, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
Contains predetermined masks for sites and holds moving edges tracking parameters.
static const vpColor green
static void flush(const vpImage< unsigned char > &I)
static int round(const double x)
void next(void)
position the current element on the next one
static Type abs(const Type &x)
#define vpDEBUG_ENABLE(niv)
vpMeSiteState getState() const
static Type maximum(const Type &a, const Type &b)
static const vpColor orange
std::list< vpMeSite > list
unsigned int getAngleStep() const
void set_ij(const double i, const double j)
static double sqr(double x)
void front(void)
Position the current element on the first element of the list.
type & value(void)
return the value of the current element
virtual void displayCross(const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)=0
void setDisplay(vpMeSiteDisplayType select)
void track(const vpImage< unsigned char > &I)
Track sampled pixels.
Contains abstract elements for a Distance to Feature type feature.
virtual void displayRectangle(const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)=0
static double sqrDistance(const vpMeSite S1, const vpMeSite S2)
void setState(const vpMeSiteState &flag)
static void globalCurveApprox(std::vector< vpImagePoint > &l_crossingPoints, unsigned int l_p, unsigned int l_n, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static double rad(double deg)
int getPointsToTrack() const
vpMatrix * getMask() const
static double sqrDistance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void track(const vpImage< unsigned char > &im, const vpMe *me, const bool test_contraste=true)
void initTracking(const vpImage< unsigned char > &I)
unsigned int getHeight() const
Defines a rectangle in the plane.
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void setRange(const unsigned int &r)
double getSampleStep() const
static int sign(double x)
vpMeSite::vpMeSiteDisplayType selectDisplay
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
virtual void displayPoint(const vpImagePoint &ip, const vpColor &color)=0
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static vpImagePoint * computeCurveDersPoint(double l_u, unsigned int l_i, unsigned int l_p, unsigned int l_der, std::vector< double > &l_knots, std::vector< vpImagePoint > &l_controlPoints, std::vector< double > &l_weights)
static const vpColor blue