47 #include <visp3/core/vpImageConvert.h>
48 #include <visp3/core/vpImageFilter.h>
49 #include <visp3/core/vpImagePoint.h>
50 #include <visp3/core/vpImageTools.h>
51 #include <visp3/core/vpMath.h>
52 #include <visp3/core/vpRect.h>
53 #include <visp3/core/vpRobust.h>
54 #include <visp3/core/vpTrackingException.h>
55 #include <visp3/me/vpMe.h>
56 #include <visp3/me/vpMeNurbs.h>
57 #include <visp3/me/vpMeSite.h>
58 #include <visp3/me/vpMeTracker.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);
71 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list);
72 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
78 double computeDelta(
double deltai,
double deltaj)
81 delta = atan2(deltai, deltaj);
83 while (delta > M_PI) {
94 static bool outOfImage(
const vpImagePoint &iP,
int half,
int rows,
int cols)
96 return ((iP.
get_i() < half + 1) || (iP.
get_i() > (rows - half - 3)) || (iP.
get_j() < half + 1) ||
97 (iP.
get_j() > (cols - half - 3)));
110 for (
int i = 0; i < 180; i++) {
115 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);
130 unsigned int ihalfa = ihalf + a;
132 conv += me->
getMask()[index_mask][a][b] * I(ihalfa, jhalf + b);
141 while (angle > M_PI) {
162 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++) {
163 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++) {
165 if (Isub(i, j) > 0) {
167 if (dist <= 16 && dist < dist_1) {
178 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
183 ip_edges_list->
front();
184 while (!ip_edges_list->
outside()) {
190 ip_edges_list->
next();
198 bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
200 for (std::list<vpImagePoint>::const_iterator it = ip_edges_list->begin(); it != ip_edges_list->end(); ++it) {
216 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false), cannyTh1(100.),
225 :
vpMeTracker(menurbs), nurbs(menurbs.nurbs), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0),
226 enableCannyDetection(false), cannyTh1(100.), cannyTh2(200.)
229 nbControlPoints = menurbs.nbControlPoints;
230 beginPtFound = menurbs.beginPtFound;
231 endPtFound = menurbs.endPtFound;
232 enableCannyDetection = menurbs.enableCannyDetection;
233 cannyTh1 = menurbs.cannyTh1;
234 cannyTh2 = menurbs.cannyTh2;
250 std::list<vpImagePoint> ptList;
257 ptList.push_back(pt);
264 if (ptList.size() > 3)
311 double delta = computeDelta(pt[1].get_i(), pt[1].get_j());
317 pix.
init(pt[0].get_i(), pt[0].get_j(), delta);
337 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();) {
356 std::list<vpMeSite>::iterator it =
list.begin();
361 while (u < 1 && it !=
list.end()) {
364 while (d <= d_1 && u < 1) {
378 s.
alpha = computeDelta(der[1].get_i(), der[1].get_j());
411 if (d > threshold ) {
415 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign);
423 bool beginPtAdded =
false;
425 double angle = atan2(begin[1].get_i(), begin[1].get_j());
430 for (
int i = 0; i < 3; i++) {
459 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
462 bool endPtAdded =
false;
463 angle = atan2(end[1].get_i(), end[1].get_j());
468 for (
int i = 0; i < 3; i++) {
513 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
519 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000))
524 if (beginPtFound >= 3 && farFromImageEdge(I, firstPoint)) {
526 begin = nurbs.computeCurveDersPoint(0.0, 1);
528 vpImagePoint topLeft(begin[0].get_i() - 15, begin[0].get_j() - 15);
529 vpRect rect(topLeft, 32, 32);
537 double step = 0.0001;
540 while (inRectangle(lastPtInSubIm, rect) && u < 1) {
542 lastPtInSubIm = nurbs.computeCurvePoint(u);
547 lastPtInSubIm = nurbs.computeCurvePoint(u);
549 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
555 IplImage *dst = cvCreateImage(cvSize((
int)Isub.
getWidth(), (
int)Isub.
getHeight()), 8, 1);
556 cvCanny(Ip, dst, cannyTh1, cannyTh2, 3);
563 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
565 std::list<vpImagePoint> ip_edges_list;
568 double fi = firstBorder.
get_i();
569 double fj = firstBorder.
get_j();
573 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
576 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
579 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
582 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
584 computeFreemanChainElement(Isub, firstBorder, dir);
585 unsigned int firstDir = dir;
586 ip_edges_list.push_back(firstBorder);
590 computeFreemanParameters(dir, dBorder);
591 border = border + dBorder;
594 ip_edges_list.push_back(border);
596 computeFreemanChainElement(Isub, border, dir);
597 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
600 if (findCenterPoint(&ip_edges_list)) {
601 for (std::list<vpMeSite>::iterator it = list.begin(); it != list.end();
605 if (inRectangle(iP, rect))
611 std::list<vpMeSite>::iterator itList = list.begin();
615 std::list<vpMeSite> addedPt;
616 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
625 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
631 findAngle(I, iPtemp, me, delta, convlt);
635 list.insert(itList, pix);
637 addedPt.push_front(pix);
643 unsigned int memory_range = me->
getRange();
645 std::list<vpMeSite>::iterator itList2 = list.begin();
646 for (
int j = 0; j < nbr; j++) {
648 s.
track(I, me,
false);
659 if (endPtFound >= 3 && farFromImageEdge(I, lastPoint)) {
661 end = nurbs.computeCurveDersPoint(1.0, 1);
664 vpImagePoint topLeft(end[0].get_i() - 15, end[0].get_j() - 15);
665 vpRect rect(topLeft, 32, 32);
673 double step = 0.0001;
676 while (inRectangle(lastPtInSubIm, rect) && u > 0) {
678 lastPtInSubIm = nurbs.computeCurvePoint(u);
683 lastPtInSubIm = nurbs.computeCurvePoint(u);
685 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
691 IplImage *dst = cvCreateImage(cvSize((
int)Isub.
getWidth(), (
int)Isub.
getHeight()), 8, 1);
692 cvCanny(Ip, dst, cannyTh1, cannyTh2, 3);
699 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
701 std::list<vpImagePoint> ip_edges_list;
704 double fi = firstBorder.
get_i();
705 double fj = firstBorder.
get_j();
709 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
712 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
715 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
718 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
721 computeFreemanChainElement(Isub, firstBorder, dir);
722 unsigned int firstDir = dir;
723 ip_edges_list.push_back(firstBorder);
727 computeFreemanParameters(dir, dBorder);
728 border = border + dBorder;
731 ip_edges_list.push_back(border);
733 computeFreemanChainElement(Isub, border, dir);
734 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
737 if (findCenterPoint(&ip_edges_list)) {
744 if (inRectangle(iP, rect)) {
745 list.erase(list.end());
751 std::list<vpMeSite>::iterator itList = list.end();
756 std::list<vpMeSite> addedPt;
757 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
766 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
772 findAngle(I, iPtemp, me, delta, convlt);
776 addedPt.push_back(pix);
782 unsigned int memory_range = me->
getRange();
784 std::list<vpMeSite>::iterator itList2 = list.end();
786 for (
int j = 0; j < nbr; j++) {
788 me_s.
track(I, me,
false);
799 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
818 if ((
double)n < 0.7 * nbPt) {
840 std::list<vpMeSite>::iterator it =
list.begin();
841 std::list<vpMeSite>::iterator itNext =
list.begin();
860 double dmin1_1 = 1e6;
861 double dmin2_1 = 1e6;
867 if (dmin1 < dmin1_1) {
872 if (dmin2 < dmin2_1) {
880 if ((std::fabs(u - 1.0) > std::fabs(
vpMath::maximum(u, 1.0)) * std::numeric_limits<double>::epsilon()) ||
881 (std::fabs(uend - 1.0) > std::fabs(
vpMath::maximum(uend, 1.0)) * std::numeric_limits<double>::epsilon())) {
893 double delta = computeDelta(iP[1].get_i(), iP[1].get_j());
895 pix.
init(iP[0].get_i(), iP[0].get_j(), delta);
899 list.insert(it, pix);
926 while(!
list.nextOutside())
937 if (!
list.nextOutside())
list.next();
943 std::list<vpMeSite>::const_iterator it =
list.begin();
944 std::list<vpMeSite>::iterator itNext =
list.begin();
946 for (; itNext !=
list.end();) {
956 if (itNext !=
list.end()) {
983 if (
list.size() == 1)
994 if (enableCannyDetection)
1007 if (std::fabs(u) > std::numeric_limits<double>::epsilon())
1050 if (hasGoodLevel(I, iP)) {
1052 computeFreemanParameters((element + 2) % 8, diP);
1054 if (hasGoodLevel(I, iPtemp)) {
1055 element = (element + 2) % 8;
1057 computeFreemanParameters((element + 1) % 8, diP);
1060 if (hasGoodLevel(I, iPtemp)) {
1061 element = (element + 1) % 8;
1063 computeFreemanParameters(element, diP);
1066 if (hasGoodLevel(I, iPtemp)) {
1069 computeFreemanParameters((element + 7) % 8, diP);
1072 if (hasGoodLevel(I, iPtemp)) {
1073 element = (element + 7) % 8;
1075 computeFreemanParameters((element + 6) % 8, diP);
1078 if (hasGoodLevel(I, iPtemp)) {
1079 element = (element + 6) % 8;
1081 computeFreemanParameters((element + 5) % 8, diP);
1084 if (hasGoodLevel(I, iPtemp)) {
1085 element = (element + 5) % 8;
1087 computeFreemanParameters((element + 4) % 8, diP);
1090 if (hasGoodLevel(I, iPtemp)) {
1091 element = (element + 4) % 8;
1093 computeFreemanParameters((element + 3) % 8, diP);
1096 if (hasGoodLevel(I, iPtemp)) {
1097 element = (element + 3) % 8;
1130 if (!isInImage(I, iP))
1172 void vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1231 return (iP.
get_i() < height - 20 && iP.
get_j() < width - 20 && iP.
get_i() > 20 && iP.
get_j() > 20);