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>
74 computeDelta(
double deltai,
double deltaj)
77 delta = atan2(deltai,deltaj) ;
79 while (delta > M_PI) { delta -= M_PI ; }
80 while (delta < 0) { delta += M_PI ; }
87 bool outOfImage(
vpImagePoint iP ,
int half ,
int rows ,
int cols)
89 return((iP.
get_i() < half + 1) || ( iP.
get_i() > (rows - half - 3) )
90 ||(iP.
get_j() < half + 1) || (iP.
get_j() > (cols - half - 3) )) ;
98 vpMe* me,
double &angle,
double &convlt)
104 for (
int i = 0; i < 180; i++)
111 if(outOfImage( iP , (
int)half + me->
getStrip() , Iheight, Iwidth))
122 unsigned int ihalf = (
unsigned int)(iP.
get_i()-half) ;
123 unsigned int jhalf = (
unsigned int)(iP.
get_j()-half) ;
124 unsigned int ihalfa ;
132 conv += me->
getMask()[index_mask][a][b] *
143 while (angle > M_PI) { angle -= M_PI ; }
144 while (angle < 0) { angle += M_PI ; }
160 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++)
162 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++)
169 if (dist <= 16 && dist < dist_1)
181 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
186 ip_edges_list->
front();
188 while (!ip_edges_list->
outside())
196 ip_edges_list->
next();
204 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
207 for(std::list<vpImagePoint>::const_iterator it=ip_edges_list->begin(); it!=ip_edges_list->end(); ++it){
225 nbControlPoints = 20;
228 enableCannyDetection =
false;
240 nbControlPoints = menurbs.nbControlPoints;
241 beginPtFound = menurbs.beginPtFound;
242 endPtFound = menurbs.endPtFound;
243 enableCannyDetection = menurbs.enableCannyDetection;
244 cannyTh1 = menurbs.cannyTh1;
245 cannyTh2 = menurbs.cannyTh2;
265 std::list<vpImagePoint> ptList;
274 ptList.push_back(pt);
280 if (ptList.size() > 3)
286 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
301 std::list<vpImagePoint> listStd;
303 listStd.push_back(ptList.
value());
323 const std::list<vpImagePoint> &ptList)
355 if (pt!=NULL)
delete[] pt;
357 double delta = computeDelta(pt[1].get_i(),pt[1].get_j());
363 pix.
init(pt[0].get_i(), pt[0].get_j(), delta) ;
371 if (pt!=NULL)
delete[] pt;
384 for(std::list<vpMeSite>::iterator it=
list.begin(); it!=
list.end(); ){
407 std::list<vpMeSite>::iterator it=
list.begin();
412 while (u < 1 && it!=
list.end())
416 while (d <= d_1 && u<1)
425 if (der != NULL)
delete[] der;
430 s.
alpha = computeDelta(der[1].get_i(),der[1].get_j());
436 if (der != NULL)
delete[] der;
469 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign) ;
473 unsigned int memory_range = me->
getRange() ;
477 bool beginPtAdded =
false;
479 double angle = atan2(begin[1].get_i(),begin[1].get_j());
484 for (
int i=0 ; i < 3 ; i++)
511 if (!beginPtAdded) beginPtFound++;
513 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
516 bool endPtAdded =
false;
517 angle = atan2(end[1].get_i(),end[1].get_j());
522 for (
int i=0 ; i < 3 ; i++)
547 if (!endPtAdded) endPtFound++;
554 if(begin != NULL)
delete[] begin;
555 if(end != NULL)
delete[] end;
570 #ifdef VISP_HAVE_OPENCV
578 #ifdef VISP_HAVE_OPENCV
583 if (beginPtFound >=3 && farFromImageEdge(I, firstPoint))
586 begin = nurbs.computeCurveDersPoint(0.0,1);
588 vpImagePoint topLeft(begin[0].get_i()-15,begin[0].get_j()-15);
589 vpRect rect(topLeft,32,32);
599 while (inRectangle(lastPtInSubIm,rect) && u < 1)
602 lastPtInSubIm = nurbs.computeCurvePoint(u);
607 lastPtInSubIm = nurbs.computeCurvePoint(u);
613 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
614 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
620 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
622 std::list<vpImagePoint> ip_edges_list;
626 double fi = firstBorder.
get_i();
627 double fj = firstBorder.
get_j();
631 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
633 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
635 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
637 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
638 computeFreemanChainElement(Isub, firstBorder , dir);
639 unsigned int firstDir = dir;
640 ip_edges_list.push_back( firstBorder );
645 computeFreemanParameters(dir, dBorder);
646 border = border + dBorder;
649 ip_edges_list.push_back( border );
651 computeFreemanChainElement(Isub, border , dir);
652 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
655 if (findCenterPoint(&ip_edges_list))
657 for(std::list<vpMeSite>::iterator it=list.begin(); it!=list.end(); ){
660 if (inRectangle(iP,rect))
661 it = list.erase(it) ;
666 std::list<vpMeSite>::iterator itList=list.begin();
670 std::list<vpMeSite> addedPt;
671 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
680 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
687 findAngle(I, iPtemp, me, delta, convlt);
691 list.insert(itList, pix);
693 addedPt.push_front(pix);
699 unsigned int memory_range = me->
getRange();
701 std::list<vpMeSite>::iterator itList2=list.begin();
702 for (
int j = 0; j < nbr; j++)
712 if (begin != NULL)
delete[] begin;
716 if(endPtFound >= 3 && farFromImageEdge(I, lastPoint))
719 end = nurbs.computeCurveDersPoint(1.0,1);
722 vpImagePoint topLeft(end[0].get_i()-15,end[0].get_j()-15);
723 vpRect rect(topLeft,32,32);
733 while (inRectangle(lastPtInSubIm,rect) && u > 0)
736 lastPtInSubIm = nurbs.computeCurvePoint(u);
741 lastPtInSubIm = nurbs.computeCurvePoint(u);
747 IplImage* dst = cvCreateImage( cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1 );
748 cvCanny( Ip, dst, cannyTh1, cannyTh2, 3 );
754 firstBorder = findFirstBorder(Isub, lastPtInSubIm-topLeft);
756 std::list<vpImagePoint> ip_edges_list;
760 double fi = firstBorder.
get_i();
761 double fj = firstBorder.
get_j();
765 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon()) dir = 4;
767 else if (std::fabs(fi-h) <= std::fabs(
vpMath::maximum(fi,h))*std::numeric_limits<double>::epsilon()) dir = 0;
769 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon()) dir = 2;
771 else if (std::fabs(fj-w) <= std::fabs(
vpMath::maximum(fj,w))*std::numeric_limits<double>::epsilon()) dir = 6;
774 computeFreemanChainElement(Isub, firstBorder , dir);
775 unsigned int firstDir = dir;
776 ip_edges_list.push_back( firstBorder );
781 computeFreemanParameters(dir, dBorder);
782 border = border + dBorder;
785 ip_edges_list.push_back( border );
787 computeFreemanChainElement(Isub, border , dir);
788 }
while( (border != firstBorder || dir != firstDir) && isInImage(Isub,border) );
791 if (findCenterPoint(&ip_edges_list))
799 if (inRectangle(iP,rect))
801 list.erase(list.end()) ;
808 std::list<vpMeSite>::iterator itList = list.end();
812 std::list<vpMeSite> addedPt;
813 for(std::list<vpImagePoint>::const_iterator itEdges=ip_edges_list.begin(); itEdges!=ip_edges_list.end(); ++itEdges){
822 for(std::list<vpMeSite>::const_iterator itAdd=addedPt.begin(); itAdd!=addedPt.end(); ++itAdd){
829 findAngle(I, iPtemp, me, delta, convlt);
833 addedPt.push_back(pix);
839 unsigned int memory_range = me->
getRange();
841 std::list<vpMeSite>::iterator itList2 = list.end();
842 for (
int j = 0; j < nbr; j++)
852 if (end != NULL)
delete[] end;
856 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
877 if ((
double)n < 0.7*nbPt)
901 std::list<vpMeSite>::iterator it=
list.begin();
902 std::list<vpMeSite>::iterator itNext=
list.begin();
905 unsigned int range_tmp = me->
getRange();
923 double dmin1_1 = 1e6;
924 double dmin2_1 = 1e6;
946 if( (std::fabs(u-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon())
947 || (std::fabs(uend-1.0) > std::fabs(
vpMath::maximum(u, 1.0))*std::numeric_limits<double>::epsilon()))
961 double delta = computeDelta(iP[1].get_i(),iP[1].get_j());
963 pix.
init(iP[0].get_i(), iP[0].get_j(), delta) ;
965 pix.
track(I,me,
false);
968 list.insert(it, pix);
997 while(!
list.nextOutside())
1007 list.modify(s_next);
1008 if (!
list.nextOutside())
list.next();
1014 std::list<vpMeSite>::const_iterator it=
list.begin();
1015 std::list<vpMeSite>::iterator itNext=
list.begin();
1017 for(;itNext!=
list.end();){
1027 if(itNext!=
list.end()){
1065 if(enableCannyDetection)
1079 if(std::fabs(u) > std::numeric_limits<double>::epsilon())
1127 unsigned int &element)
1131 if (hasGoodLevel( I, iP )) {
1133 computeFreemanParameters((element + 2) %8, diP);
1135 if (hasGoodLevel( I, iPtemp )) {
1136 element = (element + 2) % 8;
1139 computeFreemanParameters((element + 1) %8, diP);
1142 if ( hasGoodLevel( I, iPtemp )) {
1143 element = (element + 1) % 8;
1146 computeFreemanParameters(element, diP);
1149 if ( hasGoodLevel( I, iPtemp )) {
1153 computeFreemanParameters((element + 7) %8, diP);
1156 if ( hasGoodLevel( I, iPtemp )) {
1157 element = (element + 7) %8;
1160 computeFreemanParameters((element + 6) %8, diP);
1163 if ( hasGoodLevel( I, iPtemp )) {
1164 element = (element + 6) %8 ;
1167 computeFreemanParameters((element + 5) %8, diP);
1170 if ( hasGoodLevel( I, iPtemp )) {
1171 element = (element + 5) %8 ;
1174 computeFreemanParameters((element + 4) %8, diP);
1177 if ( hasGoodLevel( I, iPtemp )) {
1178 element = (element + 4) %8 ;
1181 computeFreemanParameters((element + 3) %8, diP);
1184 if ( hasGoodLevel( I, iPtemp )) {
1185 element = (element + 3) %8 ;
1222 if( !isInImage( I, iP ) )
1248 return (iP.
get_i() >= 0
1271 vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1331 return (iP.
get_i() < height - 20
1332 && iP.
get_j() < width - 20
1334 && iP.
get_j() > 20);