51 #include <visp/vpMeTracker.h>
52 #include <visp/vpMe.h>
53 #include <visp/vpMeSite.h>
54 #include <visp/vpMeNurbs.h>
55 #include <visp/vpRobust.h>
56 #include <visp/vpTrackingException.h>
57 #include <visp/vpImagePoint.h>
58 #include <visp/vpMath.h>
59 #include <visp/vpRect.h>
60 #include <visp/vpImageTools.h>
61 #include <visp/vpImageConvert.h>
65 #ifdef VISP_HAVE_OPENCV
66 # if (VISP_HAVE_OPENCV_VERSION >= 0x020101) // Require opencv >= 2.1.1
68 # include <opencv2/imgproc/imgproc_c.h>
77 computeDelta(
double deltai,
double deltaj)
80 delta = atan2(deltai,deltaj) ;
82 while (delta > M_PI) { delta -= M_PI ; }
83 while (delta < 0) { delta += M_PI ; }
90 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
92 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
93 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
101 vpMe* me,
double &angle,
double &convlt)
107 for (
int i = 0; i < 180; i++)
114 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
125 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
126 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
127 unsigned int ihalfa ;
135 conv += me->
getMask()[index_mask][a][b] *
146 while (angle > M_PI) { angle -= M_PI ; }
147 while (angle < 0) { angle += M_PI ; }
163 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
165 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
172 if (dist <= 16 && dist < dist_1)
184 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
189 ip_edges_list->
front();
191 while (!ip_edges_list->
outside())
199 ip_edges_list->
next();
207 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){
228 nbControlPoints = 20;
231 enableCannyDetection =
false;
243 nbControlPoints = menurbs.nbControlPoints;
244 beginPtFound = menurbs.beginPtFound;
245 endPtFound = menurbs.endPtFound;
246 enableCannyDetection = menurbs.enableCannyDetection;
247 cannyTh1 = menurbs.cannyTh1;
248 cannyTh2 = menurbs.cannyTh2;
268 std::list<vpImagePoint> ptList;
277 ptList.push_back(pt);
283 if (ptList.size() > 3)
289 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
304 std::list<vpImagePoint> listStd;
306 listStd.push_back(ptList.
value());
326 const std::list<vpImagePoint> &ptList)
358 if (pt!=NULL)
delete[] pt;
360 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
366 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
374 if (pt!=NULL)
delete[] pt;
387 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
410 std::list<vpMeSite>::iterator it=
list.begin();
415 while (u < 1 && it!=
list.end())
419 while (d <= d_1 && u<1)
428 if (der != NULL)
delete[] der;
433 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
439 if (der != NULL)
delete[] der;
472 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
476 unsigned int memory_range = me->
getRange() ;
480 bool beginPtAdded =
false;
482 double angle = atan2(begin[1].get_i(),begin[1].get_j());
487 for (
int i=0 ; i < 3 ; i++)
514 if (!beginPtAdded) beginPtFound++;
516 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
519 bool endPtAdded =
false;
520 angle = atan2(end[1].get_i(),end[1].get_j());
525 for (
int i=0 ; i < 3 ; i++)
550 if (!endPtAdded) endPtFound++;
557 if(begin != NULL)
delete[] begin;
558 if(end != NULL)
delete[] end;
573 #ifdef VISP_HAVE_OPENCV
581 #ifdef VISP_HAVE_OPENCV
586 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
589 begin = nurbs.computeCurveDersPoint(0.0,1);
591 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
592 vpRect rect(topLeft,32,32);
602 while (inRectangle(lastPtInSubIm,rect) && u < 1)
605 lastPtInSubIm = nurbs.computeCurvePoint(u);
610 lastPtInSubIm = nurbs.computeCurvePoint(u);
616 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
617 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
623 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
625 std::list<vpImagePoint> ip_edges_list;
629 double fi = firstBorder.
get_i();
630 double fj = firstBorder.
get_j();
634 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
636 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
638 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
640 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
641 computeFreemanChainElement(Isub, firstBorder , dir);
642 unsigned int firstDir = dir;
643 ip_edges_list.push_back( firstBorder );
648 computeFreemanParameters(dir, dBorder);
649 border = border + dBorder;
652 ip_edges_list.push_back( border );
654 computeFreemanChainElement(Isub, border , dir);
655 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
658 if (findCenterPoint(&ip_edges_list))
660 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
663 if (inRectangle(iP,rect))
664 it = list.erase(it) ;
669 std::list<vpMeSite>::iterator itList=list.begin();
673 std::list<vpMeSite> addedPt;
674 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
683 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
690 findAngle(I, iPtemp, me, delta, convlt);
694 list.insert(itList, pix);
696 addedPt.push_front(pix);
702 unsigned int memory_range = me->
getRange();
704 std::list<vpMeSite>::iterator itList2=list.begin();
705 for (
int j = 0; j < nbr; j++)
715 if (begin != NULL)
delete[] begin;
719 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
722 end = nurbs.computeCurveDersPoint(1.0,1);
725 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
726 vpRect rect(topLeft,32,32);
736 while (inRectangle(lastPtInSubIm,rect) && u > 0)
739 lastPtInSubIm = nurbs.computeCurvePoint(u);
744 lastPtInSubIm = nurbs.computeCurvePoint(u);
750 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
751 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
757 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
759 std::list<vpImagePoint> ip_edges_list;
763 double fi = firstBorder.
get_i();
764 double fj = firstBorder.
get_j();
768 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
770 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
772 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
774 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
777 computeFreemanChainElement(Isub, firstBorder , dir);
778 unsigned int firstDir = dir;
779 ip_edges_list.push_back( firstBorder );
784 computeFreemanParameters(dir, dBorder);
785 border = border + dBorder;
788 ip_edges_list.push_back( border );
790 computeFreemanChainElement(Isub, border , dir);
791 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
794 if (findCenterPoint(&ip_edges_list))
802 if (inRectangle(iP,rect))
804 list.erase(list.end()) ;
811 std::list<vpMeSite>::iterator itList = list.end();
815 std::list<vpMeSite> addedPt;
816 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
825 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
832 findAngle(I, iPtemp, me, delta, convlt);
836 addedPt.push_back(pix);
842 unsigned int memory_range = me->
getRange();
844 std::list<vpMeSite>::iterator itList2 = list.end();
845 for (
int j = 0; j < nbr; j++)
855 if (end != NULL)
delete[] end;
859 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
880 if ((
double)n < 0.7*nbPt)
904 std::list<vpMeSite>::iterator it=
list.begin();
905 std::list<vpMeSite>::iterator itNext=
list.begin();
908 unsigned int range_tmp = me->
getRange();
926 double dmin1_1 = 1e6;
927 double dmin2_1 = 1e6;
949 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
950 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon()))
964 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
966 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
968 pix.
track(I,me,
false);
971 list.insert(it, pix);
1000 while(!
list.nextOutside())
1010 list.modify(s_next);
1011 if (!
list.nextOutside())
list.next();
1017 std::list<vpMeSite>::const_iterator it=
list.begin();
1018 std::list<vpMeSite>::iterator itNext=
list.begin();
1020 for(;itNext!=
list.end();){
1030 if(itNext!=
list.end()){
1068 if(enableCannyDetection)
1082 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1130 unsigned int &element)
1134 if (hasGoodLevel( I, iP )) {
1136 computeFreemanParameters((element + 2) %8, diP);
1138 if (hasGoodLevel( I, iPtemp )) {
1139 element = (element + 2) % 8;
1142 computeFreemanParameters((element + 1) %8, diP);
1145 if ( hasGoodLevel( I, iPtemp )) {
1146 element = (element + 1) % 8;
1149 computeFreemanParameters(element, diP);
1152 if ( hasGoodLevel( I, iPtemp )) {
1156 computeFreemanParameters((element + 7) %8, diP);
1159 if ( hasGoodLevel( I, iPtemp )) {
1160 element = (element + 7) %8;
1163 computeFreemanParameters((element + 6) %8, diP);
1166 if ( hasGoodLevel( I, iPtemp )) {
1167 element = (element + 6) %8 ;
1170 computeFreemanParameters((element + 5) %8, diP);
1173 if ( hasGoodLevel( I, iPtemp )) {
1174 element = (element + 5) %8 ;
1177 computeFreemanParameters((element + 4) %8, diP);
1180 if ( hasGoodLevel( I, iPtemp )) {
1181 element = (element + 4) %8 ;
1184 computeFreemanParameters((element + 3) %8, diP);
1187 if ( hasGoodLevel( I, iPtemp )) {
1188 element = (element + 3) %8 ;
1225 if( !isInImage( I, iP ) )
1251 return (iP.
get_i() >= 0
1274 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1334 return (iP.
get_i() < height - 20
1335 && iP.
get_j() < width - 20
1337 && 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)
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