39 #include <visp3/vision/vpPlanarObjectDetector.h> 41 #if (VISP_HAVE_OPENCV_VERSION >= 0x020000) && \ 42 (VISP_HAVE_OPENCV_VERSION < 0x030000) // Require opencv >= 2.0.0 and < 3.0.0 44 #include <visp3/core/vpColor.h> 45 #include <visp3/core/vpDisplay.h> 46 #include <visp3/core/vpException.h> 47 #include <visp3/core/vpImageConvert.h> 48 #include <visp3/core/vpImagePoint.h> 49 #include <visp3/core/vpImageTools.h> 59 vpPlanarObjectDetector::vpPlanarObjectDetector()
60 : fern(), homography(), H(), dst_corners(), isCorrect(false), ref_corners(), modelROI(), currentImagePoints(),
61 refImagePoints(), minNbMatching(10)
73 vpPlanarObjectDetector::vpPlanarObjectDetector(
const std::string &_dataFile,
const std::string &_objectName)
74 : fern(), homography(), H(), dst_corners(), isCorrect(false), ref_corners(), modelROI(), currentImagePoints(),
75 refImagePoints(), minNbMatching(10)
77 load(_dataFile, _objectName);
83 void vpPlanarObjectDetector::init() {}
90 vpPlanarObjectDetector::~vpPlanarObjectDetector() {}
99 void vpPlanarObjectDetector::computeRoi(
vpImagePoint *ip,
const unsigned int nbpt)
105 std::vector<vpImagePoint> ptsx(nbpt);
106 std::vector<vpImagePoint> ptsy(nbpt);
107 for (
unsigned int i = 0; i < nbpt; i++) {
108 ptsx[i] = ptsy[i] = ip[i];
111 for (
unsigned int i = 0; i < nbpt; i++) {
112 for (
unsigned int j = 0; j < nbpt - 1; j++) {
113 if (ptsx[j].get_j() > ptsx[j + 1].get_j()) {
114 double tmp = ptsx[j + 1].
get_j();
115 ptsx[j + 1].set_j(ptsx[j].get_j());
120 for (
unsigned int i = 0; i < nbpt; i++) {
121 for (
unsigned int j = 0; j < nbpt - 1; j++) {
122 if (ptsy[j].get_i() > ptsy[j + 1].get_i()) {
123 double tmp = ptsy[j + 1].get_i();
124 ptsy[j + 1].set_i(ptsy[j].get_i());
145 modelROI.width = (int)_I.
getWidth();
148 initialiseRefCorners(modelROI);
150 return fern.buildReference(_I);
167 unsigned int _height,
unsigned int _width)
169 unsigned int res = fern.buildReference(_I, _iP, _height, _width);
170 modelROI.x = (int)_iP.
get_u();
171 modelROI.y = (int)_iP.
get_v();
172 modelROI.width = (int)_width;
173 modelROI.height = (int)_height;
175 initialiseRefCorners(modelROI);
192 unsigned int res = fern.buildReference(_I, _rectangle);
196 modelROI.x = (int)iP.
get_u();
197 modelROI.y = (int)iP.
get_v();
198 modelROI.width = (int)_rectangle.
getWidth();
199 modelROI.height = (int)_rectangle.
getHeight();
201 initialiseRefCorners(modelROI);
221 std::vector<cv::Point2f> refPts = fern.getRefPt();
222 std::vector<cv::Point2f> curPts = fern.getCurPt();
224 for (
unsigned int i = 0; i < refPts.size(); ++i) {
225 refPts[i].x += modelROI.x;
226 refPts[i].y += modelROI.y;
228 for (
unsigned int i = 0; i < curPts.size(); ++i) {
229 curPts[i].x += modelROI.x;
230 curPts[i].y += modelROI.y;
233 if (curPts.size() < 4) {
234 for (
unsigned int i = 0; i < 3; i += 1) {
235 for (
unsigned int j = 0; j < 3; j += 1) {
237 homography[i][j] = 1;
239 homography[i][j] = 0;
247 std::vector<unsigned char> mask;
248 H = cv::findHomography(cv::Mat(refPts), cv::Mat(curPts), mask, cv::RANSAC, 10);
251 const cv::Mat_<double> &H_tmp = H;
252 dst_corners.resize(4);
253 for (
unsigned int i = 0; i < 4; i++) {
254 cv::Point2f pt = ref_corners[i];
256 double w = 1. / (H_tmp(2, 0) * pt.x + H_tmp(2, 1) * pt.y + H_tmp(2, 2));
257 dst_corners[i] = cv::Point2f((
float)((H_tmp(0, 0) * pt.x + H_tmp(0, 1) * pt.y + H_tmp(0, 2)) * w),
258 (
float)((H_tmp(1, 0) * pt.x + H_tmp(1, 1) * pt.y + H_tmp(1, 2)) * w));
261 double *ptr = (
double *)H_tmp.data;
262 for (
unsigned int i = 0; i < 9; i++) {
263 this->homography[(
unsigned int)(i / 3)][i % 3] = *(ptr++);
270 currentImagePoints.resize(0);
271 refImagePoints.resize(0);
272 for (
unsigned int i = 0; i < mask.size(); i += 1) {
275 ip.
set_i(curPts[i].y);
276 ip.
set_j(curPts[i].x);
277 currentImagePoints.push_back(ip);
278 ip.
set_i(refPts[i].y);
279 ip.
set_j(refPts[i].x);
280 refImagePoints.push_back(ip);
284 if (currentImagePoints.size() < minNbMatching) {
305 const unsigned int height,
const unsigned int width)
308 vpTRACE(
"Bad size for the subimage");
316 return this->matchPoint(subImage);
335 return (this->matchPoint(I, iP, (
unsigned int)rectangle.
getHeight(), (
unsigned int)rectangle.
getWidth()));
350 for (
unsigned int i = 0; i < dst_corners.size(); i++) {
351 vpImagePoint ip1(dst_corners[i].y - modelROI.y, dst_corners[i].x - modelROI.x);
352 vpImagePoint ip2(dst_corners[(i + 1) % dst_corners.size()].y - modelROI.y,
353 dst_corners[(i + 1) % dst_corners.size()].x - modelROI.x);
358 for (
unsigned int i = 0; i < currentImagePoints.size(); ++i) {
359 vpImagePoint ip(currentImagePoints[i].get_i() - modelROI.y, currentImagePoints[i].get_j() - modelROI.x);
384 display(Icurrent, displayKpts);
387 for (
unsigned int i = 0; i < refImagePoints.size(); ++i) {
403 void vpPlanarObjectDetector::load(
const std::string &dataFilename,
const std::string &objName)
405 fern.load(dataFilename, objName);
406 modelROI = fern.getModelROI();
407 initialiseRefCorners(modelROI);
417 void vpPlanarObjectDetector::recordDetector(
const std::string &objectName,
const std::string &dataFile)
419 fern.record(objectName, dataFile);
427 std::vector<vpImagePoint> vpPlanarObjectDetector::getDetectedCorners()
const 430 std::vector<vpImagePoint> corners;
432 for (
unsigned int i = 0; i < dst_corners.size(); i++) {
433 ip.
set_uv(dst_corners[i].x, dst_corners[i].y);
434 corners.push_back(ip);
445 void vpPlanarObjectDetector::initialiseRefCorners(
const cv::Rect &_modelROI)
449 ip.y = (float)_modelROI.y;
450 ip.x = (
float)_modelROI.x;
451 ref_corners.push_back(ip);
453 ip.y = (float)(_modelROI.y + _modelROI.height);
454 ip.x = (float)_modelROI.x;
455 ref_corners.push_back(ip);
457 ip.y = (float)(_modelROI.y + _modelROI.height);
458 ip.x = (float)(_modelROI.x + _modelROI.width);
459 ref_corners.push_back(ip);
461 ip.y = (float)_modelROI.y;
462 ip.x = (
float)(_modelROI.x + _modelROI.width);
463 ref_corners.push_back(ip);
466 void vpPlanarObjectDetector::getReferencePoint(
unsigned int _i,
vpImagePoint &_imPoint)
468 if (_i >= refImagePoints.size()) {
471 _imPoint = refImagePoints[_i];
474 void vpPlanarObjectDetector::getMatchedPoints(
const unsigned int _index,
vpImagePoint &_referencePoint,
478 if (_index >= currentImagePoints.size()) {
482 _referencePoint = refImagePoints[_index];
483 _currentPoint = currentImagePoints[_index];
486 #elif !defined(VISP_BUILD_SHARED_LIBS) 489 void dummy_vpPlanarObjectDetector(){};
Used to indicate that a value is not in the allowed range.
unsigned int getWidth() const
error that can be emited by ViSP classes.
static const vpColor green
vpImagePoint getTopLeft() const
void set_i(const double ii)
void set_j(const double jj)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
unsigned int getHeight() const
void set_uv(const double u, const double v)
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 ...
static void displayLine(const vpImage< unsigned char > &I, const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)