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);
419 unsigned int memory_range = me->
getRange();
423 bool beginPtAdded =
false;
425 double angle = atan2(begin[1].get_i(), begin[1].get_j());
430 for (
int i = 0; i < 3; i++) {
439 P.
track(I, me,
false);
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++) {
477 P.
track(I, me,
false);
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)) {
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) {
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)) {
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) {
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)) {
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();
844 unsigned int range_tmp = me->
getRange();
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);
897 pix.
track(I, me,
false);
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);
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)
static double sqrDistance(const vpMeSite &S1, const vpMeSite &S2)
Provide simple list management.
Point removed because too near image borders.
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'...
Class to define RGB 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
static void flush(const vpImage< unsigned char > &I)
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.
Point used by the tracker.
int outOfImage(int i, int j, int half, int row, int cols)
static double sqrDistance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
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)
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, unsigned int gaussianFilterSize, double thresholdCanny, unsigned int apertureSobel)
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)
int getPointsToTrack() const
vpMatrix * getMask() const
static int round(double x)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
void set_ij(double ii, double jj)
Used to indicate that a parameter is not initialized.
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 ...
void setRange(const unsigned int &r)
double getSampleStep() const
void track(const vpImage< unsigned char > &im, const vpMe *me, bool test_contraste=true)
vpMeSite::vpMeSiteDisplayType selectDisplay
static int() sign(double x)
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve...
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