39 #include <visp3/core/vpPolygon.h> 40 #include <visp3/mbt/vpMbtDistanceKltCylinder.h> 41 #include <visp3/mbt/vpMbtDistanceKltPoints.h> 43 #if defined(VISP_HAVE_MODULE_KLT) && (defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020100)) 45 #if defined(VISP_HAVE_CLIPPER) 46 #include <clipper.hpp> 49 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin) 50 #include <TargetConditionals.h> 58 : c0Mo(), p1Ext(), p2Ext(), cylinder(), circle1(), circle2(), initPoints(), initPoints3D(), curPoints(),
59 curPointsInd(), nbPointsCur(0), nbPointsInit(0), minNbPoint(4), enoughPoints(false), cam(),
60 isTrackedKltCylinder(true), listIndicesCylinderBBox(), hiddenface(NULL), useScanLine(false)
114 initPoints = std::map<int, vpImagePoint>();
115 initPoints3D = std::map<int, vpPoint>();
116 curPoints = std::map<int, vpImagePoint>();
117 curPointsInd = std::map<int, int>();
119 for (
unsigned int i = 0; i < static_cast<unsigned int>(_tracker.
getNbFeatures()); i++) {
122 _tracker.
getFeature((
int)i,
id, x_tmp, y_tmp);
127 if ((
unsigned int)y_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getHeight() &&
128 (
unsigned int)x_tmp < hiddenface->getMbScanLineRenderer().getPrimitiveIDs().getWidth()) {
137 std::vector<vpImagePoint> roi;
150 double xm = 0, ym = 0;
152 double Z = computeZ(xm, ym);
157 curPointsInd[(int)
id] = (
int)i;
161 curPointsInd[id] = (int)i;
169 initPoints3D[(int)
id] = p;
171 initPoints3D[id] = p;
179 if (nbPointsCur >= minNbPoint)
182 enoughPoints =
false;
201 curPoints = std::map<int, vpImagePoint>();
202 curPointsInd = std::map<int, int>();
204 for (
unsigned int i = 0; i < static_cast<unsigned int>(_tracker.
getNbFeatures()); i++) {
206 if (isTrackedFeature((
int)
id)) {
208 curPoints[(int)
id] =
vpImagePoint(static_cast<double>(y),
static_cast<double>(x));
209 curPointsInd[(int)
id] = (
int)i;
211 curPoints[id] =
vpImagePoint(static_cast<double>(y), static_cast<double>(x));
212 curPointsInd[id] = (int)i;
218 if (nbPointsCur >= minNbPoint)
221 enoughPoints =
false;
236 std::map<int, vpImagePoint> tmp;
237 std::map<int, int> tmp2;
238 unsigned int nbSupp = 0;
242 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
243 for (; iter != curPoints.end(); ++iter) {
244 if (_w[k] > threshold_outlier && _w[k + 1] > threshold_outlier) {
246 tmp[iter->first] =
vpImagePoint(iter->second.get_i(), iter->second.get_j());
247 tmp2[iter->first] = curPointsInd[iter->first];
251 initPoints.erase(iter->first);
258 curPoints = std::map<int, vpImagePoint>();
259 curPointsInd = std::map<int, int>();
263 if (nbPointsCur >= minNbPoint)
266 enoughPoints =
false;
284 unsigned int index_ = 0;
288 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
289 for (; iter != curPoints.end(); ++iter) {
291 double i_cur(iter->second.get_i()), j_cur(iter->second.get_j());
293 double x_cur(0), y_cur(0);
300 double x0_transform(p0.
get_x()), y0_transform(p0.
get_y());
302 double Z = computeZ(x_cur, y_cur);
304 if (
vpMath::isNaN(Z) || Z < std::numeric_limits<double>::epsilon()) {
310 _J[2 * index_][0] = 0;
311 _J[2 * index_][1] = 0;
312 _J[2 * index_][2] = 0;
313 _J[2 * index_][3] = 0;
314 _J[2 * index_][4] = 0;
315 _J[2 * index_][5] = 0;
317 _J[2 * index_ + 1][0] = 0;
318 _J[2 * index_ + 1][1] = 0;
319 _J[2 * index_ + 1][2] = 0;
320 _J[2 * index_ + 1][3] = 0;
321 _J[2 * index_ + 1][4] = 0;
322 _J[2 * index_ + 1][5] = 0;
324 _R[2 * index_] = (x0_transform - x_cur);
325 _R[2 * index_ + 1] = (y0_transform - y_cur);
328 double invZ = 1.0 / Z;
330 _J[2 * index_][0] = -invZ;
331 _J[2 * index_][1] = 0;
332 _J[2 * index_][2] = x_cur * invZ;
333 _J[2 * index_][3] = x_cur * y_cur;
334 _J[2 * index_][4] = -(1 + x_cur * x_cur);
335 _J[2 * index_][5] = y_cur;
337 _J[2 * index_ + 1][0] = 0;
338 _J[2 * index_ + 1][1] = -invZ;
339 _J[2 * index_ + 1][2] = y_cur * invZ;
340 _J[2 * index_ + 1][3] = (1 + y_cur * y_cur);
341 _J[2 * index_ + 1][4] = -y_cur * x_cur;
342 _J[2 * index_ + 1][5] = -x_cur;
344 _R[2 * index_] = (x0_transform - x_cur);
345 _R[2 * index_ + 1] = (y0_transform - y_cur);
358 bool vpMbtDistanceKltCylinder::isTrackedFeature(
int _id)
360 std::map<int, vpImagePoint>::iterator iter = initPoints.find(_id);
361 if (iter != initPoints.end())
377 #
if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
382 unsigned char nb,
unsigned int shiftBorder)
384 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 385 int width = mask.cols;
386 int height = mask.rows;
388 int width = mask->width;
389 int height = mask->height;
395 int i_min, i_max, j_min, j_max;
396 std::vector<vpImagePoint> roi;
399 double shiftBorder_d = (double)shiftBorder;
400 #if defined(VISP_HAVE_CLIPPER) 401 std::vector<vpImagePoint> roi_offset;
403 ClipperLib::Path path;
404 for (std::vector<vpImagePoint>::const_iterator it = roi.begin(); it != roi.end(); ++it) {
405 path.push_back(ClipperLib::IntPoint((ClipperLib::cInt)it->get_u(), (ClipperLib::cInt)it->get_v()));
408 ClipperLib::Paths solution;
409 ClipperLib::ClipperOffset co;
410 co.AddPath(path, ClipperLib::jtRound, ClipperLib::etClosedPolygon);
411 co.Execute(solution, -shiftBorder_d);
414 if (!solution.empty()) {
415 size_t index_max = 0;
417 if (solution.size() > 1) {
421 for (
size_t i = 0; i < solution.size(); i++) {
422 std::vector<vpImagePoint> corners;
424 for (
size_t j = 0; j < solution[i].size(); j++) {
425 corners.push_back(
vpImagePoint((
double)(solution[i][j].Y), (
double)(solution[i][j].X)));
429 if (polygon_area.
getArea() > max_area) {
430 max_area = polygon_area.
getArea();
436 for (
size_t i = 0; i < solution[index_max].size(); i++) {
437 roi_offset.push_back(
vpImagePoint((
double)(solution[index_max][i].Y), (
double)(solution[index_max][i].X)));
447 #if defined(VISP_HAVE_CLIPPER) 454 if (i_min > height) {
457 if (i_max > height) {
467 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408) 468 for (
int i = i_min; i < i_max; i++) {
469 double i_d = (double)i;
471 for (
int j = j_min; j < j_max; j++) {
472 double j_d = (double)j;
474 #if defined(VISP_HAVE_CLIPPER) 477 mask.ptr<uchar>(i)[j] = nb;
480 if (shiftBorder != 0) {
486 mask.at<
unsigned char>(i, j) = nb;
490 mask.at<
unsigned char>(i, j) = nb;
497 unsigned char *ptrData = (
unsigned char *)mask->imageData + i_min * mask->widthStep + j_min;
498 for (
int i = i_min; i < i_max; i++) {
499 double i_d = (double)i;
500 for (
int j = j_min; j < j_max; j++) {
501 double j_d = (double)j;
502 if (shiftBorder != 0) {
520 ptrData += mask->widthStep - j_max + j_min;
534 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
535 for (; iter != curPoints.end(); ++iter) {
538 iP.
set_i(static_cast<double>(iter->second.get_i()));
539 iP.
set_j(static_cast<double>(iter->second.get_j()));
545 std::stringstream ss;
558 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
559 for (; iter != curPoints.end(); ++iter) {
562 iP.
set_i(static_cast<double>(iter->second.get_i()));
563 iP.
set_j(static_cast<double>(iter->second.get_j()));
569 std::stringstream ss;
577 unsigned int thickness,
const bool )
581 for (
size_t i = 0; i < models.size(); i++) {
590 unsigned int thickness,
const bool )
594 for (
size_t i = 0; i < models.size(); i++) {
609 std::vector<std::vector<double> > features;
611 std::map<int, vpImagePoint>::const_iterator iter = curPoints.begin();
612 for (; iter != curPoints.end(); ++iter) {
615 iP.
set_i(static_cast<double>(iter->second.get_i()));
616 iP.
set_j(static_cast<double>(iter->second.get_j()));
622 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 623 std::vector<double> params = {1,
628 static_cast<double>(id)};
630 std::vector<double> params;
632 params.push_back(iP.
get_i());
633 params.push_back(iP.
get_j());
634 params.push_back(iP2.
get_i());
635 params.push_back(iP2.
get_j());
636 params.push_back(static_cast<double>(
id));
638 features.push_back(params);
655 std::vector<std::vector<double> > models;
667 std::cout <<
"Problem projection circle 1";
672 std::cout <<
"Problem projection circle 2";
685 double i11, i12, i21, i22, j11, j12, j21, j22;
700 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11) 701 std::vector<double> params1 = {0,
706 models.push_back(params1);
708 std::vector<double> params2 = {0,
714 std::vector<double> params1, params2;
715 params1.push_back(0);
716 params1.push_back(ip11.
get_i());
717 params1.push_back(ip11.
get_j());
718 params1.push_back(ip12.
get_i());
719 params1.push_back(ip12.
get_j());
721 params2.push_back(0);
722 params2.push_back(ip21.
get_i());
723 params2.push_back(ip21.
get_j());
724 params2.push_back(ip22.
get_i());
725 params2.push_back(ip22.
get_j());
727 models.push_back(params1);
728 models.push_back(params2);
738 double vpMbtDistanceKltCylinder::computeZ(
const double &x,
const double &y)
751 #elif !defined(VISP_BUILD_SHARED_LIBS) 754 void dummy_vpMbtDistanceKltCylinder(){};
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const
Implementation of a matrix and operations on matrices.
void displayPrimitive(const vpImage< unsigned char > &_I)
void setWorldCoordinates(double oX, double oY, double oZ)
unsigned int computeNbDetectedCurrent(const vpKltOpencv &_tracker)
void removeOutliers(const vpColVector &weight, const double &threshold_outlier)
Implementation of an homogeneous matrix and operations on such kind of matrices.
void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam, const vpColor &col, unsigned int thickness=1, bool displayFullModel=false)
std::vector< int > listIndicesCylinderBBox
Pointer to the polygon that define a face.
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const
Class to define RGB colors available for display functionnalities.
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
double get_oY() const
Get the point oY coordinate in the object frame.
vpMbScanLine & getMbScanLineRenderer()
double computeZ(double x, double y) const
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
void init(const vpKltOpencv &_tracker, const vpHomogeneousMatrix &cMo)
double get_y() const
Get the point y coordinate in the image plane.
static void getMinMaxRoi(const std::vector< vpImagePoint > &roi, int &i_min, int &i_max, int &j_min, int &j_max)
vpMbtDistanceKltCylinder()
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
bool isInside(const vpImagePoint &iP, const PointInPolygonMethod &method=PnPolyRayCasting) const
virtual ~vpMbtDistanceKltCylinder()
Defines a generic 2D polygon.
void computeInteractionMatrixAndResidu(const vpHomogeneousMatrix &cMc0, vpColVector &_R, vpMatrix &_J)
static void computeIntersectionPoint(const vpCircle &circle, const vpCameraParameters &cam, const double &rho, const double &theta, double &i, double &j)
Generic class defining intrinsic camera parameters.
double get_oZ() const
Get the point oZ coordinate in the object frame.
std::vector< PolygonType * > & getPolygon()
double get_x() const
Get the point x coordinate in the image plane.
static bool isNaN(double value)
bool useScanLine
Use scanline rendering.
void buildFrom(const vpPoint &p1, const vpPoint &p2, const double &r)
vpMbHiddenFaces< vpMbtPolygon > * hiddenface
Pointer to the list of faces.
static void convertLine(const vpCameraParameters &cam, const double &rho_m, const double &theta_m, double &rho_p, double &theta_p)
static int round(double x)
double get_oX() const
Get the point oX coordinate in the object frame.
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)
Implementation of column vector and the associated operations.
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.
std::vector< std::vector< double > > getModelForDisplay(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void setWorldCoordinates(const vpColVector &oP)
void updateMask(cv::Mat &mask, unsigned char _nb=255, unsigned int _shiftBorder=0)
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1, bool segment=true)
std::vector< std::vector< double > > getFeaturesForDisplay()
void buildFrom(const std::vector< vpImagePoint > &corners)
void setWorldCoordinates(const vpColVector &oP)