40 #include <visp3/core/vpPolygon.h> 41 #include <visp3/mbt/vpMbtDistanceKltPoints.h> 42 #include <visp3/me/vpMeTracker.h> 44 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 46 #if defined(VISP_HAVE_CLIPPER) 47 #include <clipper.hpp> 50 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) 51 #include <TargetConditionals.h> 59 : H(), N(), N_cur(), invd0(1.), cRc0_0n(), initPoints(
std::map<int,
vpImagePoint>()),
60 curPoints(
std::map<int,
vpImagePoint>()), curPointsInd(
std::map<int, int>()), nbPointsCur(0), nbPointsInit(0),
61 minNbPoint(4), enoughPoints(false), dt(1.), d0(1.), cam(), isTrackedKltPoints(true), polygon(NULL),
62 hiddenface(NULL), useScanLine(false)
85 initPoints = std::map<int, vpImagePoint>();
86 curPoints = std::map<int, vpImagePoint>();
87 curPointsInd = std::map<int, int>();
88 std::vector<vpImagePoint> roi;
91 for (
unsigned int i = 0; i < static_cast<unsigned int>(_tracker.
getNbFeatures()); i++) {
101 if ((
unsigned int)y_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
102 (
unsigned int)x_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getWidth() &&
116 curPointsInd[(int)
id] = (
int)i;
120 curPointsInd[id] = (int)i;
125 nbPointsInit = (
unsigned int)initPoints.size();
126 nbPointsCur = (
unsigned int)curPoints.size();
128 if (nbPointsCur >= minNbPoint)
131 enoughPoints =
false;
137 N = plan.getNormal();
158 curPoints = std::map<int, vpImagePoint>();
159 curPointsInd = std::map<int, int>();
161 for (
unsigned int i = 0; i < static_cast<unsigned int>(_tracker.
getNbFeatures()); i++) {
163 if (isTrackedFeature((
int)
id) &&
vpMeTracker::inMask(mask, (
unsigned int) y, (
unsigned int) x)) {
165 curPoints[(int)
id] =
vpImagePoint(static_cast<double>(y),
static_cast<double>(x));
166 curPointsInd[(int)
id] = (
int)i;
168 curPoints[id] =
vpImagePoint(static_cast<double>(y), static_cast<double>(x));
169 curPointsInd[id] = (int)i;
174 nbPointsCur = (
unsigned int)curPoints.size();
176 if (nbPointsCur >= minNbPoint)
179 enoughPoints =
false;
196 unsigned int index_ = 0;
198 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
199 for (; iter != curPoints.end(); ++iter) {
201 double i_cur(iter->second.get_i()), j_cur(iter->second.get_j());
203 double x_cur(0), y_cur(0);
212 computeP_mu_t(x0, y0, x0_transform, y0_transform, H);
214 double invZ = compute_1_over_Z(x_cur, y_cur);
216 _J[2 * index_][0] = -invZ;
217 _J[2 * index_][1] = 0;
218 _J[2 * index_][2] = x_cur * invZ;
219 _J[2 * index_][3] = x_cur * y_cur;
220 _J[2 * index_][4] = -(1 + x_cur * x_cur);
221 _J[2 * index_][5] = y_cur;
223 _J[2 * index_ + 1][0] = 0;
224 _J[2 * index_ + 1][1] = -invZ;
225 _J[2 * index_ + 1][2] = y_cur * invZ;
226 _J[2 * index_ + 1][3] = (1 + y_cur * y_cur);
227 _J[2 * index_ + 1][4] = -y_cur * x_cur;
228 _J[2 * index_ + 1][5] = -x_cur;
230 _R[2 * index_] = (x0_transform - x_cur);
231 _R[2 * index_ + 1] = (y0_transform - y_cur);
236 double vpMbtDistanceKltPoints::compute_1_over_Z(
double x,
double y)
238 double num = cRc0_0n[0] * x + cRc0_0n[1] * y + cRc0_0n[2];
239 double den = -(d0 - dt);
255 inline void vpMbtDistanceKltPoints::computeP_mu_t(
double x_in,
double y_in,
double &x_out,
double &y_out,
258 double p_mu_t_2 = x_in * _cHc0[2][0] + y_in * _cHc0[2][1] + _cHc0[2][2];
260 if (fabs(p_mu_t_2) < std::numeric_limits<double>::epsilon()) {
266 x_out = (x_in * _cHc0[0][0] + y_in * _cHc0[0][1] + _cHc0[0][2]) / p_mu_t_2;
267 y_out = (x_in * _cHc0[1][0] + y_in * _cHc0[1][1] + _cHc0[1][2]) / p_mu_t_2;
293 vpGEMM(ctransc0, N, -invd0, cRc0, 1.0, cHc0, VP_GEMM_B_T);
316 for (
unsigned int i = 0; i < 3; i += 1) {
317 dt += ctransc0[i] * (N_cur[i]);
328 bool vpMbtDistanceKltPoints::isTrackedFeature(
int _id)
338 std::map<int, vpImagePoint>::iterator iter = initPoints.find(_id);
339 if (iter != initPoints.end())
355 #
if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
360 unsigned char nb,
unsigned int shiftBorder)
362 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 363 int width = mask.cols;
364 int height = mask.rows;
366 int width = mask->width;
367 int height = mask->height;
370 int i_min, i_max, j_min, j_max;
371 std::vector<vpImagePoint> roi;
374 double shiftBorder_d = (double)shiftBorder;
376 #if defined(VISP_HAVE_CLIPPER) 377 std::vector<vpImagePoint> roi_offset;
379 ClipperLib::Path path;
380 for (std::vector<vpImagePoint>::const_iterator it = roi.begin(); it != roi.end(); ++it) {
381 path.push_back(ClipperLib::IntPoint((ClipperLib::cInt)it->get_u(), (ClipperLib::cInt)it->get_v()));
384 ClipperLib::Paths solution;
385 ClipperLib::ClipperOffset co;
386 co.AddPath(path, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
387 co.Execute(solution, -shiftBorder_d);
390 if (!solution.empty()) {
391 size_t index_max = 0;
393 if (solution.size() > 1) {
397 for (
size_t i = 0; i < solution.size(); i++) {
398 std::vector<vpImagePoint> corners;
400 for (
size_t j = 0; j < solution[i].size(); j++) {
401 corners.push_back(
vpImagePoint((
double)(solution[i][j].Y), (
double)(solution[i][j].X)));
405 if (polygon_area.
getArea() > max_area) {
406 max_area = polygon_area.
getArea();
412 for (
size_t i = 0; i < solution[index_max].size(); i++) {
413 roi_offset.push_back(
vpImagePoint((
double)(solution[index_max][i].Y), (
double)(solution[index_max][i].X)));
423 #if defined(VISP_HAVE_CLIPPER) 430 if (i_min > height) {
433 if (i_max > height) {
443 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 444 for (
int i = i_min; i < i_max; i++) {
445 double i_d = (double)i;
447 for (
int j = j_min; j < j_max; j++) {
448 double j_d = (double)j;
450 #if defined(VISP_HAVE_CLIPPER) 453 mask.ptr<uchar>(i)[j] = nb;
456 if (shiftBorder != 0) {
461 mask.at<
unsigned char>(i, j) = nb;
465 mask.at<
unsigned char>(i, j) = nb;
472 unsigned char *ptrData = (
unsigned char *)mask->imageData + i_min * mask->widthStep + j_min;
473 for (
int i = i_min; i < i_max; i++) {
474 double i_d = (double)i;
475 for (
int j = j_min; j < j_max; j++) {
476 double j_d = (double)j;
477 if (shiftBorder != 0) {
494 ptrData += mask->widthStep - j_max + j_min;
509 std::map<int, vpImagePoint> tmp;
510 std::map<int, int> tmp2;
511 unsigned int nbSupp = 0;
515 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
516 for (; iter != curPoints.end(); ++iter) {
517 if (_w[k] > threshold_outlier && _w[k + 1] > threshold_outlier) {
519 tmp[iter->first] =
vpImagePoint(iter->second.get_i(), iter->second.get_j());
520 tmp2[iter->first] = curPointsInd[iter->first];
524 initPoints.erase(iter->first);
533 if (nbPointsCur >= minNbPoint)
536 enoughPoints =
false;
547 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
548 for (; iter != curPoints.end(); ++iter) {
551 iP.
set_i(static_cast<double>(iter->second.get_i()));
552 iP.
set_j(static_cast<double>(iter->second.get_j()));
558 std::stringstream ss;
571 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
572 for (; iter != curPoints.end(); ++iter) {
575 iP.
set_i(static_cast<double>(iter->second.get_i()));
576 iP.
set_j(static_cast<double>(iter->second.get_j()));
582 std::stringstream ss;
590 bool displayFullModel)
592 std::vector<std::vector<double> > models =
getModelForDisplay(camera, displayFullModel);
594 for (
size_t i = 0; i < models.size(); i++) {
604 bool displayFullModel)
606 std::vector<std::vector<double> > models =
getModelForDisplay(camera, displayFullModel);
608 for (
size_t i = 0; i < models.size(); i++) {
623 std::vector<std::vector<double> > features;
625 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
626 for (; iter != curPoints.end(); ++iter) {
629 iP.
set_i(static_cast<double>(iter->second.get_i()));
630 iP.
set_j(static_cast<double>(iter->second.get_j()));
636 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 637 std::vector<double> params = {1,
642 static_cast<double>(id)};
644 std::vector<double> params;
646 params.push_back(iP.
get_i());
647 params.push_back(iP.
get_j());
648 params.push_back(iP2.
get_i());
649 params.push_back(iP2.
get_j());
650 params.push_back(static_cast<double>(
id));
652 features.push_back(params);
667 bool displayFullModel)
669 std::vector<std::vector<double> > models;
672 std::vector<std::pair<vpPoint, unsigned int> > roi;
675 for (
unsigned int j = 0; j < roi.size(); j += 1) {
684 std::vector<std::pair<vpPoint, vpPoint> > linesLst;
689 linesLst.push_back(std::make_pair(roi[j].first, roi[(j + 1) % roi.size()].first));
691 for (
unsigned int i = 0; i < linesLst.size(); i++) {
692 linesLst[i].first.project();
693 linesLst[i].second.project();
697 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 698 std::vector<double> params = {0,
704 std::vector<double> params;
706 params.push_back(ip1.
get_i());
707 params.push_back(ip1.
get_j());
708 params.push_back(ip2.
get_i());
709 params.push_back(ip2.
get_j());
711 models.push_back(params);
720 #elif !defined(VISP_BUILD_SHARED_LIBS) 723 void dummy_vpMbtDistanceKltPoints(){};
Implementation of a matrix and operations on matrices.
void getRoiClipped(const vpCameraParameters &cam, std::vector< vpImagePoint > &roi)
std::vector< std::vector< double > > getFeaturesForDisplay()
void removeOutliers(const vpColVector &weight, const double &threshold_outlier)
Implementation of an homogeneous matrix and operations on such kind of matrices.
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Class to define RGB colors available for display functionnalities.
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
virtual ~vpMbtDistanceKltPoints()
error that can be emited by ViSP classes.
vpMbScanLine & getMbScanLineRenderer()
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
std::vector< std::vector< double > > getModelForDisplay(const vpCameraParameters &cam, bool displayFullModel=false)
static void getMinMaxRoi(const std::vector< vpImagePoint > &roi, int &i_min, int &i_max, int &j_min, int &j_max)
Implementation of a rotation matrix and operations on such kind of matrices.
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
Implementation of an homography and operations on homographies.
Defines a generic 2D polygon.
vpColVector & normalize()
vpPoint & getPoint(const unsigned int _index)
void displayPrimitive(const vpImage< unsigned char > &_I)
void getPolygonClipped(std::vector< std::pair< vpPoint, unsigned int > > &poly)
Generic class defining intrinsic camera parameters.
void extract(vpRotationMatrix &R) const
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
void init(const vpKltOpencv &_tracker, const vpImage< bool > *mask=NULL)
virtual bool isVisible(const vpHomogeneousMatrix &cMo, double alpha, const bool &modulo=false, const vpCameraParameters &cam=vpCameraParameters(), unsigned int width=0, unsigned int height=0)
void computeHomography(const vpHomogeneousMatrix &_cTc0, vpHomography &cHc0)
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)
void computeScanLineQuery(const vpPoint &a, const vpPoint &b, std::vector< std::pair< vpPoint, vpPoint > > &lines, const bool &displayResults=false)
Implementation of column vector and the associated operations.
static bool inMask(const vpImage< bool > *mask, unsigned int i, unsigned int j)
Wrapper for the KLT (Kanade-Lucas-Tomasi) feature tracker implemented in OpenCV. Thus to enable this ...
void getFeature(const int &index, long &id, float &x, float &y) const
int getNbFeatures() const
Get the number of current features.
vpMbtPolygon * polygon
Pointer to the polygon that define a face.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
This class defines the container for a plane geometrical structure.
unsigned int computeNbDetectedCurrent(const vpKltOpencv &_tracker, const vpImage< bool > *mask=NULL)
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
Class that consider the case of a translation vector.
void computeInteractionMatrixAndResidu(vpColVector &_R, vpMatrix &_J)
void buildFrom(const std::vector< vpImagePoint > &corners)
bool useScanLine
Use scanline rendering.
void updateMask(cv::Mat &mask, unsigned char _nb=255, unsigned int _shiftBorder=0)