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>
59 #include <visp/vpImageFilter.h>
63 #ifdef VISP_HAVE_OPENCV
64 # if (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
66 # include <opencv2/imgproc/imgproc_c.h>
72 double computeDelta(
double deltai,
double deltaj);
74 vpMe* me,
double &angle,
double &convlt);
76 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list);
77 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
84 computeDelta(
double deltai,
double deltaj)
87 delta = atan2(deltai,deltaj) ;
89 while (delta > M_PI) { delta -= M_PI ; }
90 while (delta < 0) { delta += M_PI ; }
97 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
99 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
100 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
108 vpMe* me,
double &angle,
double &convlt)
114 for (
int i = 0; i < 180; i++)
121 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
132 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
133 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
134 unsigned int ihalfa ;
142 conv += me->
getMask()[index_mask][a][b] *
153 while (angle > M_PI) { angle -= M_PI ; }
154 while (angle < 0) { angle += M_PI ; }
170 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
172 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
179 if (dist <= 16 && dist < dist_1)
191 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
196 ip_edges_list->
front();
198 while (!ip_edges_list->
outside())
206 ip_edges_list->
next();
214 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
217 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
234 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
235 cannyTh1(100.), cannyTh2(200.)
244 nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
245 cannyTh1(100.), cannyTh2(200.)
249 nbControlPoints = menurbs.nbControlPoints;
250 beginPtFound = menurbs.beginPtFound;
251 endPtFound = menurbs.endPtFound;
252 enableCannyDetection = menurbs.enableCannyDetection;
253 cannyTh1 = menurbs.cannyTh1;
254 cannyTh2 = menurbs.cannyTh2;
274 std::list<vpImagePoint> ptList;
283 ptList.push_back(pt);
289 if (ptList.size() > 3)
295 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
310 std::list<vpImagePoint> listStd;
312 listStd.push_back(ptList.
value());
332 const std::list<vpImagePoint> &ptList)
364 if (pt!=NULL)
delete[] pt;
366 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
372 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
380 if (pt!=NULL)
delete[] pt;
393 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
416 std::list<vpMeSite>::iterator it=
list.begin();
421 while (u < 1 && it!=
list.end())
425 while (d <= d_1 && u<1)
434 if (der != NULL)
delete[] der;
439 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
445 if (der != NULL)
delete[] der;
478 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
482 unsigned int memory_range = me->
getRange() ;
486 bool beginPtAdded =
false;
488 double angle = atan2(begin[1].get_i(),begin[1].get_j());
493 for (
int i=0 ; i < 3 ; i++)
520 if (!beginPtAdded) beginPtFound++;
522 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
525 bool endPtAdded =
false;
526 angle = atan2(end[1].get_i(),end[1].get_j());
531 for (
int i=0 ; i < 3 ; i++)
556 if (!endPtAdded) endPtFound++;
579 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
587 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
592 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
595 begin = nurbs.computeCurveDersPoint(0.0,1);
597 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
598 vpRect rect(topLeft,32,32);
608 while (inRectangle(lastPtInSubIm,rect) && u < 1)
611 lastPtInSubIm = nurbs.computeCurvePoint(u);
616 lastPtInSubIm = nurbs.computeCurvePoint(u);
618 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
624 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
625 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
632 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
634 std::list<vpImagePoint> ip_edges_list;
638 double fi = firstBorder.
get_i();
639 double fj = firstBorder.
get_j();
643 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
645 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
647 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
649 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
650 computeFreemanChainElement(Isub, firstBorder , dir);
651 unsigned int firstDir = dir;
652 ip_edges_list.push_back( firstBorder );
657 computeFreemanParameters(dir, dBorder);
658 border = border + dBorder;
661 ip_edges_list.push_back( border );
663 computeFreemanChainElement(Isub, border , dir);
664 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
667 if (findCenterPoint(&ip_edges_list))
669 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
672 if (inRectangle(iP,rect))
673 it = list.erase(it) ;
678 std::list<vpMeSite>::iterator itList=list.begin();
682 std::list<vpMeSite> addedPt;
683 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
692 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
699 findAngle(I, iPtemp, me, delta, convlt);
703 list.insert(itList, pix);
705 addedPt.push_front(pix);
711 unsigned int memory_range = me->
getRange();
713 std::list<vpMeSite>::iterator itList2=list.begin();
714 for (
int j = 0; j < nbr; j++)
728 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
731 end = nurbs.computeCurveDersPoint(1.0,1);
734 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
735 vpRect rect(topLeft,32,32);
745 while (inRectangle(lastPtInSubIm,rect) && u > 0)
748 lastPtInSubIm = nurbs.computeCurvePoint(u);
753 lastPtInSubIm = nurbs.computeCurvePoint(u);
755 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
761 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
762 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
769 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
771 std::list<vpImagePoint> ip_edges_list;
775 double fi = firstBorder.
get_i();
776 double fj = firstBorder.
get_j();
780 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
782 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
784 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
786 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
789 computeFreemanChainElement(Isub, firstBorder , dir);
790 unsigned int firstDir = dir;
791 ip_edges_list.push_back( firstBorder );
796 computeFreemanParameters(dir, dBorder);
797 border = border + dBorder;
800 ip_edges_list.push_back( border );
802 computeFreemanChainElement(Isub, border , dir);
803 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
806 if (findCenterPoint(&ip_edges_list))
814 if (inRectangle(iP,rect))
816 list.erase(list.end()) ;
823 std::list<vpMeSite>::iterator itList = list.end();
828 std::list<vpMeSite> addedPt;
829 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
838 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
845 findAngle(I, iPtemp, me, delta, convlt);
849 addedPt.push_back(pix);
855 unsigned int memory_range = me->
getRange();
857 std::list<vpMeSite>::iterator itList2 = list.end();
859 for (
int j = 0; j < nbr; j++)
862 me_s.
track(I,me,
false);
873 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
894 if ((
double)n < 0.7*nbPt)
918 std::list<vpMeSite>::iterator it=
list.begin();
919 std::list<vpMeSite>::iterator itNext=
list.begin();
922 unsigned int range_tmp = me->
getRange();
940 double dmin1_1 = 1e6;
941 double dmin2_1 = 1e6;
963 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
964 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(uend, 1.0))*std::numeric_limits<double>::epsilon()))
978 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
980 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
982 pix.
track(I,me,
false);
985 list.insert(it, pix);
1014 while(!
list.nextOutside())
1024 list.modify(s_next);
1025 if (!
list.nextOutside())
list.next();
1031 std::list<vpMeSite>::const_iterator it=
list.begin();
1032 std::list<vpMeSite>::iterator itNext=
list.begin();
1034 for(;itNext!=
list.end();){
1044 if(itNext!=
list.end()){
1082 if(enableCannyDetection)
1096 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1144 unsigned int &element)
1148 if (hasGoodLevel( I, iP )) {
1150 computeFreemanParameters((element + 2) %8, diP);
1152 if (hasGoodLevel( I, iPtemp )) {
1153 element = (element + 2) % 8;
1156 computeFreemanParameters((element + 1) %8, diP);
1159 if ( hasGoodLevel( I, iPtemp )) {
1160 element = (element + 1) % 8;
1163 computeFreemanParameters(element, diP);
1166 if ( hasGoodLevel( I, iPtemp )) {
1170 computeFreemanParameters((element + 7) %8, diP);
1173 if ( hasGoodLevel( I, iPtemp )) {
1174 element = (element + 7) %8;
1177 computeFreemanParameters((element + 6) %8, diP);
1180 if ( hasGoodLevel( I, iPtemp )) {
1181 element = (element + 6) %8 ;
1184 computeFreemanParameters((element + 5) %8, diP);
1187 if ( hasGoodLevel( I, iPtemp )) {
1188 element = (element + 5) %8 ;
1191 computeFreemanParameters((element + 4) %8, diP);
1194 if ( hasGoodLevel( I, iPtemp )) {
1195 element = (element + 4) %8 ;
1198 computeFreemanParameters((element + 3) %8, diP);
1201 if ( hasGoodLevel( I, iPtemp )) {
1202 element = (element + 3) %8 ;
1239 if( !isInImage( I, iP ) )
1265 return (iP.
get_i() >= 0
1288 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1348 return (iP.
get_i() < height - 20
1349 && iP.
get_j() < width - 20
1351 && 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 ...
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