42#include <visp3/core/vpImageConvert.h>
43#include <visp3/core/vpImageFilter.h>
44#include <visp3/core/vpImagePoint.h>
45#include <visp3/core/vpImageTools.h>
46#include <visp3/core/vpMath.h>
47#include <visp3/core/vpRect.h>
48#include <visp3/core/vpRobust.h>
49#include <visp3/core/vpTrackingException.h>
50#include <visp3/me/vpMe.h>
51#include <visp3/me/vpMeNurbs.h>
52#include <visp3/me/vpMeSite.h>
53#include <visp3/me/vpMeTracker.h>
54#if defined(HAVE_OPENCV_IMGPROC)
55#include <opencv2/imgproc/imgproc.hpp>
56#include <opencv2/imgproc/imgproc_c.h>
59double computeDelta(
double deltai,
double deltaj);
62bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list);
63#ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
69double computeDelta(
double deltai,
double deltaj)
72 delta = atan2(deltai, deltaj);
74 while (delta > M_PI) {
85static bool outOfImage(
const vpImagePoint &iP,
int half,
int rows,
int cols)
87 return ((iP.
get_i() < half + 1) || (iP.
get_i() > (rows - half - 3)) || (iP.
get_j() < half + 1) ||
88 (iP.
get_j() > (cols - half - 3)));
101 for (
int i = 0; i < 180; i++) {
106 if (outOfImage(iP, (
int)half + me->
getStrip(), Iheight, Iwidth)) {
117 unsigned int ihalf = (
unsigned int)(iP.
get_i() - half);
118 unsigned int jhalf = (
unsigned int)(iP.
get_j() - half);
122 unsigned int ihalfa = ihalf + a;
124 conv += me->
getMask()[index_mask][a][b] * I(ihalfa, jhalf + b);
133 while (angle > M_PI) {
154 for (
unsigned int i = 0; i <= Isub.
getHeight(); i++) {
155 for (
unsigned int j = 0; j <= Isub.
getWidth(); j++) {
157 if (Isub(i, j) > 0) {
159 if (dist <= 16 && dist < dist_1) {
170#ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
175 ip_edges_list->
front();
176 while (!ip_edges_list->
outside()) {
182 ip_edges_list->
next();
190bool findCenterPoint(std::list<vpImagePoint> *ip_edges_list)
192 for (std::list<vpImagePoint>::const_iterator it = ip_edges_list->begin(); it != ip_edges_list->end(); ++it) {
205 : nurbs(), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0), enableCannyDetection(false), cannyTh1(100.),
210 :
vpMeTracker(menurbs), nurbs(menurbs.nurbs), dist(0.), nbControlPoints(20), beginPtFound(0), endPtFound(0),
211 enableCannyDetection(false), cannyTh1(100.f), cannyTh2(200.f)
214 nbControlPoints = menurbs.nbControlPoints;
215 beginPtFound = menurbs.beginPtFound;
216 endPtFound = menurbs.endPtFound;
217 enableCannyDetection = menurbs.enableCannyDetection;
218 cannyTh1 = menurbs.cannyTh1;
219 cannyTh2 = menurbs.cannyTh2;
226 std::list<vpImagePoint> ptList;
233 ptList.push_back(pt);
240 if (ptList.size() > 3)
273 double delta = computeDelta(pt[1].get_i(), pt[1].get_j());
279 pix.
init(pt[0].get_i(), pt[0].get_j(), delta);
293 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();) {
309 std::list<vpMeSite>::iterator it =
list.begin();
314 while (u < 1 && it !=
list.end()) {
317 while (d <= d_1 && u < 1) {
331 s.
alpha = computeDelta(der[1].get_i(), der[1].get_j());
357 if (d > threshold ) {
361 P.
init(begin[0].get_i(), begin[0].get_j(), (
list.front()).alpha, 0, (
list.front()).mask_sign);
369 bool beginPtAdded =
false;
371 double angle = atan2(begin[1].get_i(), begin[1].get_j());
376 for (
int i = 0; i < 3; i++) {
406 P.
init(end[0].get_i(), end[0].get_j(), (
list.back()).alpha, 0, (
list.back()).mask_sign);
409 bool endPtAdded =
false;
410 angle = atan2(end[1].get_i(), end[1].get_j());
415 for (
int i = 0; i < 3; i++) {
457 if (beginPtFound >= 3 && farFromImageEdge(I, firstPoint)) {
461 vpImagePoint topLeft(begin[0].get_i() - 15, begin[0].get_j() - 15);
462 vpRect rect(topLeft, 32, 32);
470 double step = 0.0001;
473 while (inRectangle(lastPtInSubIm, rect) && u < 1) {
486 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
488 std::list<vpImagePoint> ip_edges_list;
491 double fi =
static_cast<double>(firstBorder.
get_i());
492 double fj =
static_cast<double>(firstBorder.
get_j());
496 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
499 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
502 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
505 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
507 computeFreemanChainElement(Isub, firstBorder, dir);
508 unsigned int firstDir = dir;
509 ip_edges_list.push_back(firstBorder);
513 computeFreemanParameters(dir, dBorder);
514 border = border + dBorder;
517 ip_edges_list.push_back(border);
519 computeFreemanChainElement(Isub, border, dir);
520 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
523 if (findCenterPoint(&ip_edges_list)) {
524 for (std::list<vpMeSite>::iterator it =
list.begin(); it !=
list.end();
528 if (inRectangle(iP, rect))
534 std::list<vpMeSite>::iterator itList =
list.begin();
537 unsigned int nbr = 0;
538 std::list<vpMeSite> addedPt;
539 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
548 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
554 findAngle(I, iPtemp,
me, delta, convlt);
558 list.insert(itList, pix);
560 addedPt.push_front(pix);
568 std::list<vpMeSite>::iterator itList2 =
list.begin();
569 for (
unsigned int j = 0; j < nbr; j++) {
582 if (endPtFound >= 3 && farFromImageEdge(I, lastPoint)) {
587 vpImagePoint topLeft(end[0].get_i() - 15, end[0].get_j() - 15);
588 vpRect rect(topLeft, 32, 32);
596 double step = 0.0001;
599 while (inRectangle(lastPtInSubIm, rect) && u > 0) {
612 firstBorder = findFirstBorder(Isub, lastPtInSubIm - topLeft);
614 std::list<vpImagePoint> ip_edges_list;
617 double fi = firstBorder.
get_i();
618 double fj = firstBorder.
get_j();
622 if (std::fabs(fi) <= std::numeric_limits<double>::epsilon())
625 else if (std::fabs(fi - h) <= std::fabs(
vpMath::maximum(fi, h)) * std::numeric_limits<double>::epsilon())
628 else if (std::fabs(fj) <= std::numeric_limits<double>::epsilon())
631 else if (std::fabs(fj - w) <= std::fabs(
vpMath::maximum(fj, w)) * std::numeric_limits<double>::epsilon())
634 computeFreemanChainElement(Isub, firstBorder, dir);
635 unsigned int firstDir = dir;
636 ip_edges_list.push_back(firstBorder);
640 computeFreemanParameters(dir, dBorder);
641 border = border + dBorder;
644 ip_edges_list.push_back(border);
646 computeFreemanChainElement(Isub, border, dir);
647 }
while ((border != firstBorder || dir != firstDir) && isInImage(Isub, border));
650 if (findCenterPoint(&ip_edges_list)) {
654 for (std::list<vpMeSite>::iterator it =
list.begin(); it!=
list.end(); ++it) {
657 if (inRectangle(iP, rect)) {
664 std::list<vpMeSite>::iterator itList =
list.end();
668 unsigned int nbr = 0;
669 std::list<vpMeSite> addedPt;
670 for (std::list<vpImagePoint>::const_iterator itEdges = ip_edges_list.begin(); itEdges != ip_edges_list.end();
679 for (std::list<vpMeSite>::const_iterator itAdd = addedPt.begin(); itAdd != addedPt.end(); ++itAdd) {
685 findAngle(I, iPtemp,
me, delta, convlt);
689 addedPt.push_back(pix);
697 std::list<vpMeSite>::iterator itList2 =
list.end();
699 for (
unsigned int j = 0; j < nbr; j++) {
718 if ((
double)n < 0.7 * nbPt) {
733 std::list<vpMeSite>::iterator it =
list.begin();
734 std::list<vpMeSite>::iterator itNext =
list.begin();
740 while (itNext !=
list.end() && n <= me->getPointsToTrack()) {
753 double dmin1_1 = 1e6;
754 double dmin2_1 = 1e6;
760 if (dmin1 < dmin1_1) {
765 if (dmin2 < dmin2_1) {
773 if ((std::fabs(u - 1.0) > std::fabs(
vpMath::maximum(u, 1.0)) * std::numeric_limits<double>::epsilon()) ||
774 (std::fabs(uend - 1.0) > std::fabs(
vpMath::maximum(uend, 1.0)) * std::numeric_limits<double>::epsilon())) {
786 double delta = computeDelta(iP[1].get_i(), iP[1].get_j());
788 pix.
init(iP[0].get_i(), iP[0].get_j(), delta);
792 list.insert(it, pix);
814 while (!
list.nextOutside()) {
823 if (!
list.nextOutside())
list.next();
829 std::list<vpMeSite>::const_iterator it =
list.begin();
830 std::list<vpMeSite>::iterator itNext =
list.begin();
832 for (; itNext !=
list.end();) {
842 if (itNext !=
list.end()) {
865 if (
list.size() == 1)
876 if (enableCannyDetection)
889 if (std::fabs(u) > std::numeric_limits<double>::epsilon())
925 if (hasGoodLevel(I, iP)) {
927 computeFreemanParameters((element + 2) % 8, diP);
929 if (hasGoodLevel(I, iPtemp)) {
930 element = (element + 2) % 8;
933 computeFreemanParameters((element + 1) % 8, diP);
936 if (hasGoodLevel(I, iPtemp)) {
937 element = (element + 1) % 8;
940 computeFreemanParameters(element, diP);
943 if (hasGoodLevel(I, iPtemp)) {
947 computeFreemanParameters((element + 7) % 8, diP);
950 if (hasGoodLevel(I, iPtemp)) {
951 element = (element + 7) % 8;
954 computeFreemanParameters((element + 6) % 8, diP);
957 if (hasGoodLevel(I, iPtemp)) {
958 element = (element + 6) % 8;
961 computeFreemanParameters((element + 5) % 8, diP);
964 if (hasGoodLevel(I, iPtemp)) {
965 element = (element + 5) % 8;
968 computeFreemanParameters((element + 4) % 8, diP);
971 if (hasGoodLevel(I, iPtemp)) {
972 element = (element + 4) % 8;
975 computeFreemanParameters((element + 3) % 8, diP);
978 if (hasGoodLevel(I, iPtemp)) {
979 element = (element + 3) % 8;
1014 if (!isInImage(I, iP))
1057void vpMeNurbs::computeFreemanParameters(
unsigned int element,
vpImagePoint &diP)
1116 return (iP.
get_i() < height - 20 && iP.
get_j() < width - 20 && iP.
get_i() > 20 && iP.
get_j() > 20);
Class to define RGB colors available for display functionalities.
static const vpColor orange
static const vpColor blue
static const vpColor green
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
static void displayPoint(const vpImage< unsigned char > &I, const vpImagePoint &ip, const vpColor &color, unsigned int thickness=1)
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)
error that can be emitted by ViSP classes.
@ notInitialized
Used to indicate that a parameter is not initialized.
@ divideByZeroError
Division by zero.
static void canny(const vpImage< unsigned char > &I, vpImage< unsigned char > &Ic, unsigned int gaussianFilterSize, float thresholdCanny, unsigned int apertureSobel)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
void set_ij(double ii, double jj)
static double sqrDistance(const vpImagePoint &iP1, const vpImagePoint &iP2)
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getHeight() const
Provide simple list management.
void next(void)
position the current element on the next one
void front(void)
Position the current element on the first element of the list.
bool outside(void) const
Test if the current element is outside the list (on the virtual element)
type & value(void)
return the value of the current element
static double rad(double deg)
static Type maximum(const Type &a, const Type &b)
static double sqr(double x)
static Type abs(const Type &x)
static int round(double x)
static int sign(double x)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
int j
Coordinates along j of a site.
@ TOO_NEAR
Point removed because too near image borders.
@ NO_SUPPRESSION
Point used by the tracker.
void setDisplay(vpMeSiteDisplayType select)
double ifloat
Floating coordinates along i of a site.
int i
Coordinate along i of a site.
double alpha
Angle of tangent at site.
double jfloat
Floating coordinates along j of a site.
vpMeSiteState getState() const
void track(const vpImage< unsigned char > &im, const vpMe *me, bool test_likelihood=true)
static double sqrDistance(const vpMeSite &S1, const vpMeSite &S2)
void setState(const vpMeSiteState &flag)
Contains abstract elements for a Distance to Feature type feature.
void initTracking(const vpImage< unsigned char > &I)
unsigned int numberOfSignal()
vpMeSite::vpMeSiteDisplayType selectDisplay
int outOfImage(int i, int j, int half, int row, int cols)
void track(const vpImage< unsigned char > &I)
std::list< vpMeSite > list
vpMe * me
Moving edges initialisation parameters.
void setRange(const unsigned int &r)
unsigned int getAngleStep() const
vpMatrix * getMask() const
int getPointsToTrack() const
unsigned int getMaskSize() const
double getSampleStep() const
unsigned int getRange() const
Class that provides tools to compute and manipulate a Non Uniform Rational B-Spline curve.
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 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 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 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)
Defines a rectangle in the plane.
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.
#define vpDEBUG_ENABLE(level)