36#include <visp3/core/vpConfig.h>
44#include <visp3/core/vpMeterPixelConversion.h>
45#include <visp3/core/vpPlane.h>
46#include <visp3/mbt/vpMbtDistanceLine.h>
47#include <visp3/visual_features/vpFeatureBuilder.h>
63 : name(), index(0), cam(), me(nullptr), isTrackedLine(true), isTrackedLineWithVisibility(true), wmean(1), featureline(),
64 poly(),
useScanLine(false),
meline(),
line(nullptr),
p1(nullptr),
p2(nullptr),
L(),
error(),
nbFeature(),
nbFeatureTotal(0),
76 for (
unsigned int i = 0; i <
meline.size(); i++)
111 a[0] = P.
get_oX() -
Q.get_oX();
112 a[1] = P.
get_oY() -
Q.get_oY();
113 a[2] = P.
get_oZ() -
Q.get_oZ();
116 b[0] = P.
get_oX() -
R.get_oX();
117 b[1] = P.
get_oY() -
R.get_oY();
118 b[2] = P.
get_oZ() -
R.get_oZ();
129 double norm = sqrt(A * A + B * B + C * C);
130 plane.
setA(A / norm);
131 plane.
setB(B / norm);
132 plane.
setC(C / norm);
133 plane.
setD(D / norm);
153 buildPlane(P1, P2, P3, plane1);
154 buildPlane(P1, P2, P4, plane2);
170 if (
line ==
nullptr) {
175 poly.addPoint(0, _p1);
176 poly.addPoint(1, _p2);
184 V1[0] =
p1->get_oX();
185 V1[1] =
p1->get_oY();
186 V1[2] =
p1->get_oZ();
187 V2[0] =
p2->get_oX();
188 V2[1] =
p2->get_oY();
189 V2[2] =
p2->get_oZ();
192 if (std::fabs((V1 - V2).sumSquare()) > std::numeric_limits<double>::epsilon()) {
194 V3[0] = double(rand_gen.
next() % 1000) / 100;
195 V3[1] = double(rand_gen.
next() % 1000) / 100;
196 V3[2] = double(rand_gen.
next() % 1000) / 100;
203 vpPoint P3(V3[0], V3[1], V3[2]);
204 vpPoint P4(V4[0], V4[1], V4[2]);
208 vpPoint P3(V1[0], V1[1], V1[2]);
209 vpPoint P4(V2[0], V2[1], V2[2]);
234 unsigned int ind = 0;
242 isTrackedLine =
false;
245 isTrackedLine =
true;
249 if (!isTrackedLine) {
250 isTrackedLineWithVisibility =
false;
263 if (!isTrackedLine) {
264 isTrackedLineWithVisibility =
false;
268 unsigned int ind = 0;
269 isTrackedLineWithVisibility =
false;
272 isTrackedLineWithVisibility =
true;
288 for (
unsigned int i = 0; i <
meline.size(); i++)
289 if (
meline[i] !=
nullptr) {
314 for (
unsigned int i = 0; i <
meline.size(); i++) {
324 p1->changeFrame(cMo);
325 p2->changeFrame(cMo);
327 if (poly.getClipping() > 3)
328 cam.computeFov(I.getWidth(), I.getHeight());
330 poly.computePolygonClipped(cam);
332 if (poly.polyClipped.size() == 2) {
334 std::vector<std::pair<vpPoint, vpPoint> > linesLst;
337 hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst);
340 linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
343 if (linesLst.size() == 0) {
347 line->changeFrame(cMo);
359 while (theta > M_PI) {
362 while (theta < -M_PI) {
366 if (theta < -M_PI / 2.0)
367 theta = -theta - 3 * M_PI / 2.0;
369 theta = M_PI / 2.0 - theta;
371 for (
unsigned int i = 0; i < linesLst.size(); i++) {
374 linesLst[i].first.project();
375 linesLst[i].second.project();
380 unsigned int initRange_;
382 initRange_ = defaultRange;
385 initRange_ =
static_cast<unsigned int>(initRange);
387 int oldInitRange = me->getInitRange();
388 me->setInitRange(initRange_);
389 vpMbtMeLine *melinePt =
new vpMbtMeLine;
390 melinePt->setMask(*mask);
395 melinePt->jmin =
static_cast<int>(ip1.
get_j()) - marge;
396 melinePt->jmax =
static_cast<int>(ip2.
get_j()) + marge;
399 melinePt->jmin =
static_cast<int>(ip2.
get_j()) - marge;
400 melinePt->jmax =
static_cast<int>(ip1.
get_j()) + marge;
403 melinePt->imin =
static_cast<int>(ip1.
get_i()) - marge;
404 melinePt->imax =
static_cast<int>(ip2.
get_i()) + marge;
407 melinePt->imin =
static_cast<int>(ip2.
get_i()) - marge;
408 melinePt->imax =
static_cast<int>(ip1.
get_i()) + marge;
412 melinePt->initTracking(I, ip1, ip2, rho, theta, doNotTrack);
413 me->setInitRange(oldInitRange);
414 meline.push_back(melinePt);
415 nbFeature.push_back(
static_cast<unsigned int>(melinePt->getMeList().size()));
419 me->setInitRange(oldInitRange);
441 int oldInitRange = me->getInitRange();
442 me->setInitRange(defaultRange);
447 for (
size_t i = 0; i <
meline.size(); i++) {
449 nbFeature.push_back(
static_cast<unsigned int>(
meline[i]->getMeList().size()));
454 for (
size_t i = 0; i <
meline.size(); i++) {
466 me->setInitRange(oldInitRange);
477 int oldInitRange = me->getInitRange();
479 p1->changeFrame(cMo);
480 p2->changeFrame(cMo);
482 if (poly.getClipping() > 3)
483 cam.computeFov(I.getWidth(), I.getHeight());
485 poly.computePolygonClipped(cam);
487 if (poly.polyClipped.size() == 2) {
489 std::vector<std::pair<vpPoint, vpPoint> > linesLst;
492 hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst);
495 linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
498 if (linesLst.size() !=
meline.size() || linesLst.size() == 0) {
499 for (
size_t i = 0; i <
meline.size(); i++) {
511 line->changeFrame(cMo);
516 for (
size_t j = 0; j <
meline.size(); j++) {
532 while (theta > M_PI) {
535 while (theta < -M_PI) {
539 if (theta < -M_PI / 2.0)
540 theta = -theta - 3 * M_PI / 2.0;
542 theta = M_PI / 2.0 - theta;
545 for (
unsigned int i = 0; i < linesLst.size(); i++) {
548 linesLst[i].first.project();
549 linesLst[i].second.project();
556 meline[i]->jmin =
static_cast<int>(ip1.
get_j()) - marge;
557 meline[i]->jmax =
static_cast<int>(ip2.
get_j()) + marge;
560 meline[i]->jmin =
static_cast<int>(ip2.
get_j()) - marge;
561 meline[i]->jmax =
static_cast<int>(ip1.
get_j()) + marge;
564 meline[i]->imin =
static_cast<int>(ip1.
get_i()) - marge;
565 meline[i]->imax =
static_cast<int>(ip2.
get_i()) + marge;
568 meline[i]->imin =
static_cast<int>(ip2.
get_i()) - marge;
569 meline[i]->imax =
static_cast<int>(ip1.
get_i()) + marge;
571 me->setInitRange(defaultRange);
572 meline[i]->updateParameters(I, ip1, ip2, rho, theta);
573 nbFeature[i] =
static_cast<unsigned int>(
meline[i]->getMeList().size());
578 for (
size_t j = 0; j <
meline.size(); j++) {
592 for (
size_t i = 0; i <
meline.size(); i++) {
602 me->setInitRange(oldInitRange);
619 for (
size_t i = 0; i <
meline.size(); i++) {
647 bool displayFullModel)
649 std::vector<std::vector<double> > models =
652 for (
size_t i = 0; i < models.size(); i++) {
672 bool displayFullModel)
674 std::vector<std::vector<double> > models =
677 for (
size_t i = 0; i < models.size(); i++) {
700 for (
size_t i = 0; i <
meline.size(); i++) {
701 if (
meline[i] !=
nullptr) {
709 for (
size_t i = 0; i <
meline.size(); i++) {
710 if (
meline[i] !=
nullptr) {
722 std::vector<std::vector<double> > features;
724 for (
size_t i = 0; i <
meline.size(); i++) {
725 vpMbtMeLine *me_l =
meline[i];
726 if (me_l !=
nullptr) {
727 for (std::list<vpMeSite>::const_iterator it = me_l->getMeList().begin(); it != me_l->getMeList().end(); ++it) {
729#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
730 std::vector<double> params = { 0,
733 static_cast<double>(p_me_l.
getState()) };
735 std::vector<double> params;
739 params.push_back(
static_cast<double>(p_me_l.
getState()));
742 features.push_back(params);
764 bool displayFullModel)
766 std::vector<std::vector<double> > models;
768 if ((
isvisible && isTrackedLine) || displayFullModel) {
769 p1->changeFrame(cMo);
770 p2->changeFrame(cMo);
774 if (poly.getClipping() > 3)
777 poly.computePolygonClipped(c);
779 if (poly.polyClipped.size() == 2 &&
787 std::vector<std::pair<vpPoint, vpPoint> > linesLst;
789 hiddenface->computeScanLineQuery(poly.polyClipped[0].first, poly.polyClipped[1].first, linesLst,
true);
792 linesLst.push_back(std::make_pair(poly.polyClipped[0].first, poly.polyClipped[1].first));
795 for (
unsigned int i = 0; i < linesLst.size(); i++) {
796 linesLst[i].first.project();
797 linesLst[i].second.project();
802#if (VISP_CXX_STANDARD > VISP_CXX_STANDARD_98)
803 std::vector<double> params = { 0,
809 std::vector<double> params;
811 params.push_back(ip1.
get_i());
812 params.push_back(ip1.
get_j());
813 params.push_back(ip2.
get_i());
814 params.push_back(ip2.
get_j());
817 models.push_back(params);
835 for (
size_t i = 0; i <
meline.size(); i++) {
838 std::list<vpMeSite> &me_site_list =
meline[i]->getMeList();
839 me_site_list.clear();
854 line->changeFrame(cMo);
859 double rho = featureline.getRho();
860 double theta = featureline.getTheta();
862 double co = cos(theta);
863 double si = sin(theta);
865 double mx = 1.0 / cam.get_px();
866 double my = 1.0 / cam.get_py();
867 double xc = cam.get_u0();
868 double yc = cam.get_v0();
871 vpMatrix H = featureline.interaction();
876 for (
size_t i = 0; i <
meline.size(); i++) {
877 for (std::list<vpMeSite>::const_iterator it =
meline[i]->getMeList().begin();
878 it !=
meline[i]->getMeList().end(); ++it) {
879 x =
static_cast<double>(it->m_j);
880 y =
static_cast<double>(it->m_i);
885 alpha_ = x * si - y * co;
888 double *Ltheta = H[1];
890 for (
unsigned int k = 0; k < 6; k++) {
891 L[j][k] = (Lrho[k] + alpha_ * Ltheta[k]);
893 error[j] = rho - (x * co + y * si);
902 for (
size_t i = 0; i <
meline.size(); i++) {
903 for (std::list<vpMeSite>::const_iterator it =
meline[i]->getMeList().begin();
904 it !=
meline[i]->getMeList().end(); ++it) {
905 for (
unsigned int k = 0; k < 6; k++) {
927 if (threshold > I.getWidth() || threshold > I.getHeight()) {
932 for (
size_t i = 0; i <
meline.size(); i++) {
933 for (std::list<vpMeSite>::const_iterator it =
meline[i]->getMeList().begin(); it !=
meline[i]->getMeList().end();
938 if (i_ < 0 || j_ < 0) {
942 if ((
static_cast<unsigned int>(i_) >(I.getHeight() - threshold)) ||
static_cast<unsigned int>(i_) < threshold ||
943 (
static_cast<unsigned int>(j_) > (I.getWidth() - threshold)) ||
static_cast<unsigned int>(j_) < threshold) {
Generic class defining intrinsic camera parameters.
void computeFov(const unsigned int &w, const unsigned int &h)
Implementation of column vector and the associated operations.
static vpColVector cross(const vpColVector &a, const vpColVector &b)
Class to define RGB colors available for display functionalities.
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
static void create(vpFeaturePoint &s, const vpCameraParameters &cam, const vpDot &d)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
Class that defines a 3D line in the object frame and allows forward projection of the line in the cam...
Implementation of a matrix and operations on matrices.
void setMovingEdge(vpMe *Me)
std::vector< unsigned int > nbFeature
The number of moving edges.
void displayMovingEdges(const vpImage< unsigned char > &I)
std::vector< bool > Lindex_polygon_tracked
void updateMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo)
bool isvisible
Indicates if the line is visible or not.
bool initMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, bool doNotTrack, const vpImage< bool > *mask=nullptr, const int &initRange=0)
void computeInteractionMatrixError(const vpHomogeneousMatrix &cMo)
vpPoint * p2
The second extremity.
vpLine * line
The 3D line.
void initInteractionMatrixError()
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
std::list< int > Lindex_polygon
Index of the faces which contain the line.
void buildFrom(vpPoint &_p1, vpPoint &_p2, vpUniRand &rand_gen)
unsigned int nbFeatureTotal
The number of moving edges.
bool Reinit
Indicates if the line has to be reinitialized.
std::string getName() const
vpColVector error
The error vector.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
bool closeToImageBorder(const vpImage< unsigned char > &I, const unsigned int threshold)
std::vector< std::vector< double > > getModelForDisplay(unsigned int width, unsigned int height, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, bool displayFullModel=false)
virtual ~vpMbtDistanceLine()
std::vector< std::vector< double > > getFeaturesForDisplay()
bool useScanLine
Use scanline rendering.
vpPoint * p1
The first extremity.
std::vector< vpMbtMeLine * > meline
The moving edge container.
vpMatrix L
The interaction matrix.
void reinitMovingEdge(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpImage< bool > *mask=nullptr)
void setTracked(const std::string &name, const bool &track)
void addPolygon(const int &index)
void trackMovingEdge(const vpImage< unsigned char > &I)
Performs search in a given direction(normal) for a given distance(pixels) for a given 'site'....
vpMeSiteState getState() const
double get_ifloat() const
double get_jfloat() const
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
This class defines the container for a plane geometrical structure.
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
double get_oX() const
Get the point oX coordinate in the object frame.
double get_oZ() const
Get the point oZ coordinate in the object frame.
double get_oY() const
Get the point oY coordinate in the object frame.
Class for generating random numbers with uniform probability density.
const unsigned int defaultRange