44 #include <visp3/me/vpMeTracker.h>
45 #include <visp3/me/vpMe.h>
46 #include <visp3/me/vpMeSite.h>
47 #include <visp3/me/vpMeNurbs.h>
48 #include <visp3/core/vpRobust.h>
49 #include <visp3/core/vpTrackingException.h>
50 #include <visp3/core/vpImagePoint.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpRect.h>
53 #include <visp3/core/vpImageTools.h>
54 #include <visp3/core/vpImageConvert.h>
55 #include <visp3/core/vpImageFilter.h>
59 #ifdef VISP_HAVE_OPENCV
60 # if (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
62 # include <opencv2/imgproc/imgproc_c.h>
68 double computeDelta(
double deltai,
double deltaj);
70 vpMe* me,
double &angle,
double &convlt);
72 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list);
73 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
80 computeDelta(
double deltai,
double deltaj)
83 delta = atan2(deltai,deltaj) ;
85 while (delta > M_PI) { delta -= M_PI ; }
86 while (delta < 0) { delta += M_PI ; }
93 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
95 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
96 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
104 vpMe* me,
double &angle,
double &convlt)
110 for (
int i = 0; i < 180; i++)
117 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
128 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
129 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
130 unsigned int ihalfa ;
138 conv += me->
getMask()[index_mask][a][b] *
149 while (angle > M_PI) { angle -= M_PI ; }
150 while (angle < 0) { angle += M_PI ; }
166 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
168 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
175 if (dist <= 16 && dist < dist_1)
187 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
192 ip_edges_list->
front();
194 while (!ip_edges_list->
outside())
202 ip_edges_list->
next();
210 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
213 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
230 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
231 cannyTh1(100.), cannyTh2(200.)
240 nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
241 cannyTh1(100.), cannyTh2(200.)
245 nbControlPoints = menurbs.nbControlPoints;
246 beginPtFound = menurbs.beginPtFound;
247 endPtFound = menurbs.endPtFound;
248 enableCannyDetection = menurbs.enableCannyDetection;
249 cannyTh1 = menurbs.cannyTh1;
250 cannyTh2 = menurbs.cannyTh2;
270 std::list<vpImagePoint> ptList;
279 ptList.push_back(pt);
285 if (ptList.size() > 3)
300 const std::list<vpImagePoint> &ptList)
332 if (pt!=NULL)
delete[] pt;
334 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
340 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
348 if (pt!=NULL)
delete[] pt;
361 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
384 std::list<vpMeSite>::iterator it=
list.begin();
389 while (u < 1 && it!=
list.end())
393 while (d <= d_1 && u<1)
402 if (der != NULL)
delete[] der;
407 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
413 if (der != NULL)
delete[] der;
446 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
450 unsigned int memory_range = me->
getRange() ;
454 bool beginPtAdded =
false;
456 double angle = atan2(begin[1].get_i(),begin[1].get_j());
461 for (
int i=0 ; i < 3 ; i++)
488 if (!beginPtAdded) beginPtFound++;
490 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
493 bool endPtAdded =
false;
494 angle = atan2(end[1].get_i(),end[1].get_j());
499 for (
int i=0 ; i < 3 ; i++)
524 if (!endPtAdded) endPtFound++;
547 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
555 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
560 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
563 begin = nurbs.computeCurveDersPoint(0.0,1);
565 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
566 vpRect rect(topLeft,32,32);
576 while (inRectangle(lastPtInSubIm,rect) && u < 1)
579 lastPtInSubIm = nurbs.computeCurvePoint(u);
584 lastPtInSubIm = nurbs.computeCurvePoint(u);
586 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
592 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
593 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
600 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
602 std::list<vpImagePoint> ip_edges_list;
606 double fi = firstBorder.
get_i();
607 double fj = firstBorder.
get_j();
611 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
613 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
615 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
617 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
618 computeFreemanChainElement(Isub, firstBorder , dir);
619 unsigned int firstDir = dir;
620 ip_edges_list.push_back( firstBorder );
625 computeFreemanParameters(dir, dBorder);
626 border = border + dBorder;
629 ip_edges_list.push_back( border );
631 computeFreemanChainElement(Isub, border , dir);
632 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
635 if (findCenterPoint(&ip_edges_list))
637 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
640 if (inRectangle(iP,rect))
641 it = list.erase(it) ;
646 std::list<vpMeSite>::iterator itList=list.begin();
650 std::list<vpMeSite> addedPt;
651 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
660 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
667 findAngle(I, iPtemp, me, delta, convlt);
671 list.insert(itList, pix);
673 addedPt.push_front(pix);
679 unsigned int memory_range = me->
getRange();
681 std::list<vpMeSite>::iterator itList2=list.begin();
682 for (
int j = 0; j < nbr; j++)
696 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
699 end = nurbs.computeCurveDersPoint(1.0,1);
702 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
703 vpRect rect(topLeft,32,32);
713 while (inRectangle(lastPtInSubIm,rect) && u > 0)
716 lastPtInSubIm = nurbs.computeCurvePoint(u);
721 lastPtInSubIm = nurbs.computeCurvePoint(u);
723 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
729 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
730 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
737 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
739 std::list<vpImagePoint> ip_edges_list;
743 double fi = firstBorder.
get_i();
744 double fj = firstBorder.
get_j();
748 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
750 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
752 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
754 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
757 computeFreemanChainElement(Isub, firstBorder , dir);
758 unsigned int firstDir = dir;
759 ip_edges_list.push_back( firstBorder );
764 computeFreemanParameters(dir, dBorder);
765 border = border + dBorder;
768 ip_edges_list.push_back( border );
770 computeFreemanChainElement(Isub, border , dir);
771 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
774 if (findCenterPoint(&ip_edges_list))
782 if (inRectangle(iP,rect))
784 list.erase(list.end()) ;
791 std::list<vpMeSite>::iterator itList = list.end();
796 std::list<vpMeSite> addedPt;
797 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
806 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
813 findAngle(I, iPtemp, me, delta, convlt);
817 addedPt.push_back(pix);
823 unsigned int memory_range = me->
getRange();
825 std::list<vpMeSite>::iterator itList2 = list.end();
827 for (
int j = 0; j < nbr; j++)
830 me_s.
track(I,me,
false);
841 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
862 if ((
double)n < 0.7*nbPt)
886 std::list<vpMeSite>::iterator it=
list.begin();
887 std::list<vpMeSite>::iterator itNext=
list.begin();
890 unsigned int range_tmp = me->
getRange();
908 double dmin1_1 = 1e6;
909 double dmin2_1 = 1e6;
931 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
932 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(uend, 1.0))*std::numeric_limits<double>::epsilon()))
946 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
948 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
950 pix.
track(I,me,
false);
953 list.insert(it, pix);
982 while(!
list.nextOutside())
993 if (!
list.nextOutside())
list.next();
999 std::list<vpMeSite>::const_iterator it=
list.begin();
1000 std::list<vpMeSite>::iterator itNext=
list.begin();
1002 for(;itNext!=
list.end();){
1012 if(itNext!=
list.end()){
1042 if (
list.size() == 1)
1053 if(enableCannyDetection)
1067 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1115 unsigned int &element)
1119 if (hasGoodLevel( I, iP )) {
1121 computeFreemanParameters((element + 2) %8, diP);
1123 if (hasGoodLevel( I, iPtemp )) {
1124 element = (element + 2) % 8;
1127 computeFreemanParameters((element + 1) %8, diP);
1130 if ( hasGoodLevel( I, iPtemp )) {
1131 element = (element + 1) % 8;
1134 computeFreemanParameters(element, diP);
1137 if ( hasGoodLevel( I, iPtemp )) {
1141 computeFreemanParameters((element + 7) %8, diP);
1144 if ( hasGoodLevel( I, iPtemp )) {
1145 element = (element + 7) %8;
1148 computeFreemanParameters((element + 6) %8, diP);
1151 if ( hasGoodLevel( I, iPtemp )) {
1152 element = (element + 6) %8 ;
1155 computeFreemanParameters((element + 5) %8, diP);
1158 if ( hasGoodLevel( I, iPtemp )) {
1159 element = (element + 5) %8 ;
1162 computeFreemanParameters((element + 4) %8, diP);
1165 if ( hasGoodLevel( I, iPtemp )) {
1166 element = (element + 4) %8 ;
1169 computeFreemanParameters((element + 3) %8, diP);
1172 if ( hasGoodLevel( I, iPtemp )) {
1173 element = (element + 3) %8 ;
1210 if( !isInImage( I, iP ) )
1236 return (iP.
get_i() >= 0
1259 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1319 return (iP.
get_i() < height - 20
1320 && iP.
get_j() < width - 20
1322 && 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
#define vpDEBUG_ENABLE(level)
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)
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)
vpMeSiteState getState() const
static Type maximum(const Type &a, const Type &b)
static const vpColor orange
std::list< vpMeSite > list
unsigned int getAngleStep() const
Error that can be emited by the vpTracker class and its derivates.
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 ...
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, const unsigned int gaussianFilterSize, const double thresholdCanny, const unsigned int apertureSobel)
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)
void set_ij(const double ii, const double jj)
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