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>
71 double computeDelta(
double deltai,
double deltaj);
73 vpMe* me,
double &angle,
double &convlt);
75 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list);
76 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
83 computeDelta(
double deltai,
double deltaj)
86 delta = atan2(deltai,deltaj) ;
88 while (delta > M_PI) { delta -= M_PI ; }
89 while (delta < 0) { delta += M_PI ; }
96 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
98 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
99 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
107 vpMe* me,
double &angle,
double &convlt)
113 for (
int i = 0; i < 180; i++)
120 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
131 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
132 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
133 unsigned int ihalfa ;
141 conv += me->
getMask()[index_mask][a][b] *
152 while (angle > M_PI) { angle -= M_PI ; }
153 while (angle < 0) { angle += M_PI ; }
169 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
171 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
178 if (dist <= 16 && dist < dist_1)
190 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
195 ip_edges_list->
front();
197 while (!ip_edges_list->
outside())
205 ip_edges_list->
next();
213 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
216 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
233 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
234 cannyTh1(100.), cannyTh2(200.)
243 nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
244 cannyTh1(100.), cannyTh2(200.)
248 nbControlPoints = menurbs.nbControlPoints;
249 beginPtFound = menurbs.beginPtFound;
250 endPtFound = menurbs.endPtFound;
251 enableCannyDetection = menurbs.enableCannyDetection;
252 cannyTh1 = menurbs.cannyTh1;
253 cannyTh2 = menurbs.cannyTh2;
273 std::list<vpImagePoint> ptList;
282 ptList.push_back(pt);
288 if (ptList.size() > 3)
294 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
309 std::list<vpImagePoint> listStd;
311 listStd.push_back(ptList.
value());
331 const std::list<vpImagePoint> &ptList)
363 if (pt!=NULL)
delete[] pt;
365 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
371 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
379 if (pt!=NULL)
delete[] pt;
392 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
415 std::list<vpMeSite>::iterator it=
list.begin();
420 while (u < 1 && it!=
list.end())
424 while (d <= d_1 && u<1)
433 if (der != NULL)
delete[] der;
438 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
444 if (der != NULL)
delete[] der;
477 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
481 unsigned int memory_range = me->
getRange() ;
485 bool beginPtAdded =
false;
487 double angle = atan2(begin[1].get_i(),begin[1].get_j());
492 for (
int i=0 ; i < 3 ; i++)
519 if (!beginPtAdded) beginPtFound++;
521 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
524 bool endPtAdded =
false;
525 angle = atan2(end[1].get_i(),end[1].get_j());
530 for (
int i=0 ; i < 3 ; i++)
555 if (!endPtAdded) endPtFound++;
578 #ifdef VISP_HAVE_OPENCV
586 #ifdef VISP_HAVE_OPENCV
591 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
594 begin = nurbs.computeCurveDersPoint(0.0,1);
596 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
597 vpRect rect(topLeft,32,32);
607 while (inRectangle(lastPtInSubIm,rect) && u < 1)
610 lastPtInSubIm = nurbs.computeCurvePoint(u);
615 lastPtInSubIm = nurbs.computeCurvePoint(u);
621 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
622 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
628 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
630 std::list<vpImagePoint> ip_edges_list;
634 double fi = firstBorder.
get_i();
635 double fj = firstBorder.
get_j();
639 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
641 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
643 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
645 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
646 computeFreemanChainElement(Isub, firstBorder , dir);
647 unsigned int firstDir = dir;
648 ip_edges_list.push_back( firstBorder );
653 computeFreemanParameters(dir, dBorder);
654 border = border + dBorder;
657 ip_edges_list.push_back( border );
659 computeFreemanChainElement(Isub, border , dir);
660 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
663 if (findCenterPoint(&ip_edges_list))
665 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
668 if (inRectangle(iP,rect))
669 it = list.erase(it) ;
674 std::list<vpMeSite>::iterator itList=list.begin();
678 std::list<vpMeSite> addedPt;
679 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
688 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
695 findAngle(I, iPtemp, me, delta, convlt);
699 list.insert(itList, pix);
701 addedPt.push_front(pix);
707 unsigned int memory_range = me->
getRange();
709 std::list<vpMeSite>::iterator itList2=list.begin();
710 for (
int j = 0; j < nbr; j++)
724 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
727 end = nurbs.computeCurveDersPoint(1.0,1);
730 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
731 vpRect rect(topLeft,32,32);
741 while (inRectangle(lastPtInSubIm,rect) && u > 0)
744 lastPtInSubIm = nurbs.computeCurvePoint(u);
749 lastPtInSubIm = nurbs.computeCurvePoint(u);
755 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
756 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
762 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
764 std::list<vpImagePoint> ip_edges_list;
768 double fi = firstBorder.
get_i();
769 double fj = firstBorder.
get_j();
773 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
775 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
777 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
779 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
782 computeFreemanChainElement(Isub, firstBorder , dir);
783 unsigned int firstDir = dir;
784 ip_edges_list.push_back( firstBorder );
789 computeFreemanParameters(dir, dBorder);
790 border = border + dBorder;
793 ip_edges_list.push_back( border );
795 computeFreemanChainElement(Isub, border , dir);
796 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
799 if (findCenterPoint(&ip_edges_list))
807 if (inRectangle(iP,rect))
809 list.erase(list.end()) ;
816 std::list<vpMeSite>::iterator itList = list.end();
821 std::list<vpMeSite> addedPt;
822 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
831 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
838 findAngle(I, iPtemp, me, delta, convlt);
842 addedPt.push_back(pix);
848 unsigned int memory_range = me->
getRange();
850 std::list<vpMeSite>::iterator itList2 = list.end();
852 for (
int j = 0; j < nbr; j++)
855 me_s.
track(I,me,
false);
866 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
887 if ((
double)n < 0.7*nbPt)
911 std::list<vpMeSite>::iterator it=
list.begin();
912 std::list<vpMeSite>::iterator itNext=
list.begin();
915 unsigned int range_tmp = me->
getRange();
933 double dmin1_1 = 1e6;
934 double dmin2_1 = 1e6;
956 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
957 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(uend, 1.0))*std::numeric_limits<double>::epsilon()))
971 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
973 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
975 pix.
track(I,me,
false);
978 list.insert(it, pix);
1007 while(!
list.nextOutside())
1017 list.modify(s_next);
1018 if (!
list.nextOutside())
list.next();
1024 std::list<vpMeSite>::const_iterator it=
list.begin();
1025 std::list<vpMeSite>::iterator itNext=
list.begin();
1027 for(;itNext!=
list.end();){
1037 if(itNext!=
list.end()){
1075 if(enableCannyDetection)
1089 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1137 unsigned int &element)
1141 if (hasGoodLevel( I, iP )) {
1143 computeFreemanParameters((element + 2) %8, diP);
1145 if (hasGoodLevel( I, iPtemp )) {
1146 element = (element + 2) % 8;
1149 computeFreemanParameters((element + 1) %8, diP);
1152 if ( hasGoodLevel( I, iPtemp )) {
1153 element = (element + 1) % 8;
1156 computeFreemanParameters(element, diP);
1159 if ( hasGoodLevel( I, iPtemp )) {
1163 computeFreemanParameters((element + 7) %8, diP);
1166 if ( hasGoodLevel( I, iPtemp )) {
1167 element = (element + 7) %8;
1170 computeFreemanParameters((element + 6) %8, diP);
1173 if ( hasGoodLevel( I, iPtemp )) {
1174 element = (element + 6) %8 ;
1177 computeFreemanParameters((element + 5) %8, diP);
1180 if ( hasGoodLevel( I, iPtemp )) {
1181 element = (element + 5) %8 ;
1184 computeFreemanParameters((element + 4) %8, diP);
1187 if ( hasGoodLevel( I, iPtemp )) {
1188 element = (element + 4) %8 ;
1191 computeFreemanParameters((element + 3) %8, diP);
1194 if ( hasGoodLevel( I, iPtemp )) {
1195 element = (element + 3) %8 ;
1232 if( !isInImage( I, iP ) )
1258 return (iP.
get_i() >= 0
1281 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1341 return (iP.
get_i() < height - 20
1342 && iP.
get_j() < width - 20
1344 && 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.
#define vpDEBUG_ENABLE(level)
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
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)
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