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++)
116 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
129 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
130 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
135 unsigned int ihalfa = ihalf+a ;
138 conv += me->
getMask()[index_mask][a][b] *
149 while (angle > M_PI) { angle -= M_PI ; }
150 while (angle < 0) { angle += M_PI ; }
165 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
167 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
174 if (dist <= 16 && dist < dist_1)
186 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
191 ip_edges_list->
front();
192 while (!ip_edges_list->
outside())
200 ip_edges_list->
next();
208 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
210 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
227 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
228 cannyTh1(100.), cannyTh2(200.)
237 nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false),
238 cannyTh1(100.), cannyTh2(200.)
242 nbControlPoints = menurbs.nbControlPoints;
243 beginPtFound = menurbs.beginPtFound;
244 endPtFound = menurbs.endPtFound;
245 enableCannyDetection = menurbs.enableCannyDetection;
246 cannyTh1 = menurbs.cannyTh1;
247 cannyTh2 = menurbs.cannyTh2;
267 std::list<vpImagePoint> ptList;
276 ptList.push_back(pt);
282 if (ptList.size() > 3)
297 const std::list<vpImagePoint> &ptList)
329 if (pt!=NULL)
delete[] pt;
331 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
337 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
345 if (pt!=NULL)
delete[] pt;
358 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
381 std::list<vpMeSite>::iterator it=
list.begin();
386 while (u < 1 && it!=
list.end())
390 while (d <= d_1 && u<1)
399 if (der != NULL)
delete[] der;
404 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
410 if (der != NULL)
delete[] der;
443 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
447 unsigned int memory_range = me->
getRange() ;
451 bool beginPtAdded =
false;
453 double angle = atan2(begin[1].get_i(),begin[1].get_j());
458 for (
int i=0 ; i < 3 ; i++)
485 if (!beginPtAdded) beginPtFound++;
487 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
490 bool endPtAdded =
false;
491 angle = atan2(end[1].get_i(),end[1].get_j());
496 for (
int i=0 ; i < 3 ; i++)
521 if (!endPtAdded) endPtFound++;
544 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
552 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
557 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
560 begin = nurbs.computeCurveDersPoint(0.0,1);
562 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
563 vpRect rect(topLeft,32,32);
573 while (inRectangle(lastPtInSubIm,rect) && u < 1)
576 lastPtInSubIm = nurbs.computeCurvePoint(u);
581 lastPtInSubIm = nurbs.computeCurvePoint(u);
583 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
589 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
590 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
597 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
599 std::list<vpImagePoint> ip_edges_list;
603 double fi = firstBorder.
get_i();
604 double fj = firstBorder.
get_j();
608 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
610 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
612 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
614 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
615 computeFreemanChainElement(Isub, firstBorder , dir);
616 unsigned int firstDir = dir;
617 ip_edges_list.push_back( firstBorder );
622 computeFreemanParameters(dir, dBorder);
623 border = border + dBorder;
626 ip_edges_list.push_back( border );
628 computeFreemanChainElement(Isub, border , dir);
629 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
632 if (findCenterPoint(&ip_edges_list))
634 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
637 if (inRectangle(iP,rect))
638 it = list.erase(it) ;
643 std::list<vpMeSite>::iterator itList=list.begin();
647 std::list<vpMeSite> addedPt;
648 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
657 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
664 findAngle(I, iPtemp, me, delta, convlt);
668 list.insert(itList, pix);
670 addedPt.push_front(pix);
676 unsigned int memory_range = me->
getRange();
678 std::list<vpMeSite>::iterator itList2=list.begin();
679 for (
int j = 0; j < nbr; j++)
693 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
696 end = nurbs.computeCurveDersPoint(1.0,1);
699 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
700 vpRect rect(topLeft,32,32);
710 while (inRectangle(lastPtInSubIm,rect) && u > 0)
713 lastPtInSubIm = nurbs.computeCurvePoint(u);
718 lastPtInSubIm = nurbs.computeCurvePoint(u);
720 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
726 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
727 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
734 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
736 std::list<vpImagePoint> ip_edges_list;
740 double fi = firstBorder.
get_i();
741 double fj = firstBorder.
get_j();
745 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
747 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
749 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
751 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
754 computeFreemanChainElement(Isub, firstBorder , dir);
755 unsigned int firstDir = dir;
756 ip_edges_list.push_back( firstBorder );
761 computeFreemanParameters(dir, dBorder);
762 border = border + dBorder;
765 ip_edges_list.push_back( border );
767 computeFreemanChainElement(Isub, border , dir);
768 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
771 if (findCenterPoint(&ip_edges_list))
779 if (inRectangle(iP,rect))
781 list.erase(list.end()) ;
788 std::list<vpMeSite>::iterator itList = list.end();
793 std::list<vpMeSite> addedPt;
794 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
803 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
810 findAngle(I, iPtemp, me, delta, convlt);
814 addedPt.push_back(pix);
820 unsigned int memory_range = me->
getRange();
822 std::list<vpMeSite>::iterator itList2 = list.end();
824 for (
int j = 0; j < nbr; j++)
827 me_s.
track(I,me,
false);
838 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
859 if ((
double)n < 0.7*nbPt)
883 std::list<vpMeSite>::iterator it=
list.begin();
884 std::list<vpMeSite>::iterator itNext=
list.begin();
887 unsigned int range_tmp = me->
getRange();
905 double dmin1_1 = 1e6;
906 double dmin2_1 = 1e6;
928 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
929 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(uend, 1.0))*std::numeric_limits<double>::epsilon()))
943 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
945 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
947 pix.
track(I,me,
false);
950 list.insert(it, pix);
979 while(!
list.nextOutside())
990 if (!
list.nextOutside())
list.next();
996 std::list<vpMeSite>::const_iterator it=
list.begin();
997 std::list<vpMeSite>::iterator itNext=
list.begin();
999 for(;itNext!=
list.end();){
1009 if(itNext!=
list.end()){
1039 if (
list.size() == 1)
1050 if(enableCannyDetection)
1064 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1112 unsigned int &element)
1116 if (hasGoodLevel( I, iP )) {
1118 computeFreemanParameters((element + 2) %8, diP);
1120 if (hasGoodLevel( I, iPtemp )) {
1121 element = (element + 2) % 8;
1124 computeFreemanParameters((element + 1) %8, diP);
1127 if ( hasGoodLevel( I, iPtemp )) {
1128 element = (element + 1) % 8;
1131 computeFreemanParameters(element, diP);
1134 if ( hasGoodLevel( I, iPtemp )) {
1138 computeFreemanParameters((element + 7) %8, diP);
1141 if ( hasGoodLevel( I, iPtemp )) {
1142 element = (element + 7) %8;
1145 computeFreemanParameters((element + 6) %8, diP);
1148 if ( hasGoodLevel( I, iPtemp )) {
1149 element = (element + 6) %8 ;
1152 computeFreemanParameters((element + 5) %8, diP);
1155 if ( hasGoodLevel( I, iPtemp )) {
1156 element = (element + 5) %8 ;
1159 computeFreemanParameters((element + 4) %8, diP);
1162 if ( hasGoodLevel( I, iPtemp )) {
1163 element = (element + 4) %8 ;
1166 computeFreemanParameters((element + 3) %8, diP);
1169 if ( hasGoodLevel( I, iPtemp )) {
1170 element = (element + 3) %8 ;
1207 if( !isInImage( I, iP ) )
1233 return (iP.
get_i() >= 0
1256 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1316 return (iP.
get_i() < height - 20
1317 && iP.
get_j() < width - 20
1319 && iP.
get_j() > 20);
unsigned int getRange() const
unsigned int getMaskSize() const
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
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 void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
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
void setDisplay(vpMeSiteDisplayType select)
void track(const vpImage< unsigned char > &I)
Track sampled pixels.
Contains abstract elements for a Distance to Feature type feature.
static void displayRectangle(const vpImage< unsigned char > &I, const vpImagePoint &topLeft, unsigned int width, unsigned int height, const vpColor &color, bool fill=false, unsigned int thickness=1)
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 void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
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.
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...
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