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)
310 double delta = computeDelta(pt[1].get_i(), pt[1].get_j());
316 pix.
init(pt[0].get_i(), pt[0].get_j(), delta);
336 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();) {
355 std::list<vpMeSite>::iterator it =
list.begin();
360 while (u < 1 && it !=
list.end()) {
363 while (d <= d_1 && u < 1) {
377 s.
alpha = computeDelta(der[1].get_i(), der[1].get_j());
410 if (d > threshold ) {
414 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign);
418 unsigned int memory_range = me->
getRange();
422 bool beginPtAdded =
false;
424 double angle = atan2(begin[1].get_i(), begin[1].get_j());
429 for (
int i = 0; i < 3; i++) {
438 P.
track(I, me,
false);
458 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
461 bool endPtAdded =
false;
462 angle = atan2(end[1].get_i(), end[1].get_j());
467 for (
int i = 0; i < 3; i++) {
476 P.
track(I, me,
false);
512 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000)) 518 #if (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION < 0x030000)) 523 if (beginPtFound >= 3 && farFromImageEdge(I, firstPoint)) {
527 vpImagePoint topLeft(begin[0].get_i() - 15, begin[0].get_j() - 15);
528 vpRect rect(topLeft, 32, 32);
536 double step = 0.0001;
539 while (inRectangle(lastPtInSubIm, rect) && u < 1) {
548 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 554 IplImage *dst = cvCreateImage(cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1);
555 cvCanny(Ip, dst, cannyTh1, cannyTh2, 3);
562 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
564 std::list<vpImagePoint> ip_edges_list;
567 double fi = firstBorder.
get_i();
568 double fj = firstBorder.
get_j();
572 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
575 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
578 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
581 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
583 computeFreemanChainElement(Isub, firstBorder, dir);
584 unsigned int firstDir = dir;
585 ip_edges_list.push_back(firstBorder);
589 computeFreemanParameters(dir, dBorder);
590 border = border + dBorder;
593 ip_edges_list.push_back(border);
595 computeFreemanChainElement(Isub, border, dir);
596 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
599 if (findCenterPoint(&ip_edges_list)) {
600 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();
604 if (inRectangle(iP, rect))
610 std::list<vpMeSite>::iterator itList =
list.begin();
614 std::list<vpMeSite> addedPt;
615 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
624 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
630 findAngle(I, iPtemp, me, delta, convlt);
634 list.insert(itList, pix);
636 addedPt.push_front(pix);
642 unsigned int memory_range = me->
getRange();
644 std::list<vpMeSite>::iterator itList2 =
list.begin();
645 for (
int j = 0; j < nbr; j++) {
647 s.
track(I, me,
false);
658 if (endPtFound >= 3 && farFromImageEdge(I, lastPoint)) {
663 vpImagePoint topLeft(end[0].get_i() - 15, end[0].get_j() - 15);
664 vpRect rect(topLeft, 32, 32);
672 double step = 0.0001;
675 while (inRectangle(lastPtInSubIm, rect) && u > 0) {
684 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 690 IplImage *dst = cvCreateImage(cvSize((
int)Isub.
getWidth(), (int)Isub.
getHeight()), 8, 1);
691 cvCanny(Ip, dst, cannyTh1, cannyTh2, 3);
698 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
700 std::list<vpImagePoint> ip_edges_list;
703 double fi = firstBorder.
get_i();
704 double fj = firstBorder.
get_j();
708 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
711 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
714 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
717 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
720 computeFreemanChainElement(Isub, firstBorder, dir);
721 unsigned int firstDir = dir;
722 ip_edges_list.push_back(firstBorder);
726 computeFreemanParameters(dir, dBorder);
727 border = border + dBorder;
730 ip_edges_list.push_back(border);
732 computeFreemanChainElement(Isub, border, dir);
733 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
736 if (findCenterPoint(&ip_edges_list)) {
743 if (inRectangle(iP, rect)) {
750 std::list<vpMeSite>::iterator itList =
list.end();
755 std::list<vpMeSite> addedPt;
756 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
765 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
771 findAngle(I, iPtemp, me, delta, convlt);
775 addedPt.push_back(pix);
781 unsigned int memory_range = me->
getRange();
783 std::list<vpMeSite>::iterator itList2 =
list.end();
785 for (
int j = 0; j < nbr; j++) {
787 me_s.
track(I, me,
false);
798 vpTRACE(
"To use the canny detection, OpenCV has to be installed.");
817 if ((
double)n < 0.7 * nbPt) {
839 std::list<vpMeSite>::iterator it =
list.begin();
840 std::list<vpMeSite>::iterator itNext =
list.begin();
843 unsigned int range_tmp = me->
getRange();
859 double dmin1_1 = 1e6;
860 double dmin2_1 = 1e6;
866 if (dmin1 < dmin1_1) {
871 if (dmin2 < dmin2_1) {
879 if ((std::fabs(u - 1.0) > std::fabs(
vpMath::maximum(u, 1.0)) * std::numeric_limits<double>::epsilon()) ||
880 (std::fabs(uend - 1.0) > std::fabs(
vpMath::maximum(uend, 1.0)) * std::numeric_limits<double>::epsilon())) {
892 double delta = computeDelta(iP[1].get_i(), iP[1].get_j());
894 pix.
init(iP[0].get_i(), iP[0].get_j(), delta);
896 pix.
track(I, me,
false);
898 list.insert(it, pix);
925 while(!
list.nextOutside())
936 if (!
list.nextOutside())
list.next();
942 std::list<vpMeSite>::const_iterator it =
list.begin();
943 std::list<vpMeSite>::iterator itNext =
list.begin();
945 for (; itNext !=
list.end();) {
955 if (itNext !=
list.end()) {
982 if (
list.size() == 1)
993 if (enableCannyDetection)
1006 if (std::fabs(u) > std::numeric_limits<double>::epsilon())
1049 if (hasGoodLevel(I, iP)) {
1051 computeFreemanParameters((element + 2) % 8, diP);
1053 if (hasGoodLevel(I, iPtemp)) {
1054 element = (element + 2) % 8;
1056 computeFreemanParameters((element + 1) % 8, diP);
1059 if (hasGoodLevel(I, iPtemp)) {
1060 element = (element + 1) % 8;
1062 computeFreemanParameters(element, diP);
1065 if (hasGoodLevel(I, iPtemp)) {
1068 computeFreemanParameters((element + 7) % 8, diP);
1071 if (hasGoodLevel(I, iPtemp)) {
1072 element = (element + 7) % 8;
1074 computeFreemanParameters((element + 6) % 8, diP);
1077 if (hasGoodLevel(I, iPtemp)) {
1078 element = (element + 6) % 8;
1080 computeFreemanParameters((element + 5) % 8, diP);
1083 if (hasGoodLevel(I, iPtemp)) {
1084 element = (element + 5) % 8;
1086 computeFreemanParameters((element + 4) % 8, diP);
1089 if (hasGoodLevel(I, iPtemp)) {
1090 element = (element + 4) % 8;
1092 computeFreemanParameters((element + 3) % 8, diP);
1095 if (hasGoodLevel(I, iPtemp)) {
1096 element = (element + 3) % 8;
1129 if (!isInImage(I, iP))
1171 void vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1230 return (iP.
get_i() < height - 20 && iP.
get_j() < width - 20 && iP.
get_i() > 20 && iP.
get_j() > 20);
vpMeSiteState getState() const
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
#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)
static double sqrDistance(const vpMeSite &S1, const vpMeSite &S2)
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.
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
vpMatrix * getMask() const
static void flush(const vpImage< unsigned char > &I)
static int round(const double x)
unsigned int getMaskSize() const
void next(void)
position the current element on the next one
static Type abs(const Type &x)
static Type maximum(const Type &a, const Type &b)
static const vpColor orange
std::list< vpMeSite > list
Error that can be emited by the vpTracker class and its derivates.
double getSampleStep() const
int outOfImage(int i, int j, int half, int row, int cols)
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)
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)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
unsigned int getHeight() 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)
Defines a rectangle in the plane.
int getPointsToTrack() const
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)
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
void setRange(const unsigned int &r)
static int() sign(double x)
vpMeSite::vpMeSiteDisplayType selectDisplay
unsigned int getWidth() const
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
unsigned int getRange() const
unsigned int getAngleStep() const
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