40 #include <visp3/core/vpConfig.h>
42 #if (VISP_HAVE_OPENCV_VERSION >= 0x020000) && \
43 (VISP_HAVE_OPENCV_VERSION < 0x030000) // Require opencv >= 2.0.0 and < 3.0.0
45 #include <visp3/core/vpColor.h>
46 #include <visp3/core/vpDisplay.h>
47 #include <visp3/core/vpImageConvert.h>
48 #include <visp3/core/vpImageTools.h>
49 #include <visp3/vision/vpFernClassifier.h>
55 vpFernClassifier::vpFernClassifier()
57 gen(0, 256, 5, true, 0.6, 1.5, -CV_PI / 2, CV_PI / 2, -CV_PI / 2, CV_PI / 2), hasLearn(false), threshold(20),
58 nbView(2000), dist(2), nbClassfier(100), ClassifierSize(11), nbOctave(2), patchSize(32), radius(7), nbPoints(200),
59 blurImage(true), radiusBlur(7), sigmaBlur(1), nbMinPoint(10),
60 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
65 objKeypoints(), modelROI_Ref(), modelROI(), modelPoints(), imgKeypoints(), refPt(), curPt()
80 vpFernClassifier::vpFernClassifier(
const std::string &_dataFile,
const std::string &_objectName)
82 gen(0, 256, 5, true, 0.6, 1.5, -CV_PI / 2, CV_PI / 2, -CV_PI / 2, CV_PI / 2), hasLearn(false), threshold(20),
83 nbView(2000), dist(2), nbClassfier(100), ClassifierSize(11), nbOctave(2), patchSize(32), radius(7), nbPoints(200),
84 blurImage(true), radiusBlur(7), sigmaBlur(1), nbMinPoint(10),
85 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
90 objKeypoints(), modelROI_Ref(), modelROI(), modelPoints(), imgKeypoints(), refPt(), curPt()
92 this->
load(_dataFile, _objectName);
99 vpFernClassifier::~vpFernClassifier()
101 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
102 if (curImg != NULL) {
103 if (curImg->width % 8 == 0) {
104 curImg->imageData = NULL;
105 cvReleaseImageHeader(&curImg);
107 cvReleaseImage(&curImg);
120 void vpFernClassifier::init()
126 #if (VISP_HAVE_OPENCV_VERSION < 0x020408)
144 void vpFernClassifier::train()
147 cv::LDetector d(radius, threshold, nbOctave, nbView, patchSize, dist);
150 cv::Mat obj = (cv::Mat)curImg;
152 if (this->getBlurSetting()) {
153 cv::GaussianBlur(obj, obj, cv::Size(getBlurSize(), getBlurSize()), getBlurSigma(), getBlurSigma());
157 std::vector<cv::Mat> objpyr;
158 cv::buildPyramid(obj, objpyr, d.nOctaves - 1);
161 d.getMostStable2D(obj, objKeypoints, 100, gen);
166 modelROI = cv::Rect(0, 0, objpyr[0].cols, objpyr[0].rows);
167 ldetector.getMostStable2D(objpyr[0], modelPoints, 100, gen);
169 fernClassifier.trainFromSingleView(objpyr[0], modelPoints, patchSize, (
int)modelPoints.size(), 100, 11, 10000,
170 cv::FernClassifier::COMPRESSION_NONE, gen);
173 referenceImagePointsList.resize(0);
174 for (
unsigned int i = 0; i < modelPoints.size(); i += 1) {
175 vpImagePoint ip(modelPoints[i].pt.y + modelROI_Ref.y, modelPoints[i].pt.x + modelROI_Ref.x);
176 referenceImagePointsList.push_back(ip);
202 _reference_computed =
true;
203 return (
unsigned int)objKeypoints.size();
225 const unsigned int _height,
const unsigned int _width)
228 vpTRACE(
"Bad size for the subimage");
234 this->setImage(subImage);
238 modelROI_Ref.x = (int)_iP.
get_u();
239 modelROI_Ref.y = (int)_iP.
get_v();
240 modelROI_Ref.width = (int)_width;
241 modelROI_Ref.height = (int)_height;
245 return (
unsigned int)objKeypoints.size();
269 return (this->buildReference(_I, iP, (
unsigned int)_rectangle.
getHeight(), (
unsigned int)_rectangle.
getWidth()));
295 cv::Mat img = this->curImg;
297 if (this->getBlurSetting()) {
298 cv::GaussianBlur(img, img, cv::Size(this->getBlurSize(), this->getBlurSize()), this->getBlurSigma(),
299 this->getBlurSigma());
302 std::vector<cv::Mat> imgPyr;
303 cv::buildPyramid(img, imgPyr, ldetector.nOctaves - 1);
305 ldetector(imgPyr, imgKeypoints, 500);
307 unsigned int m = (
unsigned int)modelPoints.size();
308 unsigned int n = (
unsigned int)imgKeypoints.size();
309 std::vector<int> bestMatches(m, -1);
310 std::vector<float> maxLogProb(m, -FLT_MAX);
311 std::vector<float> signature;
312 unsigned int totalMatch = 0;
315 currentImagePointsList.resize(0);
316 matchedReferencePoints.resize(0);
318 for (
unsigned int i = 0; i < n; i++) {
319 cv::KeyPoint kpt = imgKeypoints[i];
320 kpt.pt.x /= (float)(1 << kpt.octave);
321 kpt.pt.y /= (float)(1 << kpt.octave);
322 int k = fernClassifier(imgPyr[(
unsigned int)kpt.octave], kpt.pt, signature);
323 if (k >= 0 && (bestMatches[(
unsigned int)k] < 0 || signature[(
unsigned int)k] > maxLogProb[(
unsigned int)k])) {
324 maxLogProb[(
unsigned int)k] = signature[(
unsigned int)k];
325 bestMatches[(
unsigned int)k] = (
int)i;
328 vpImagePoint ip_cur(imgKeypoints[i].pt.y, imgKeypoints[i].pt.x);
330 currentImagePointsList.push_back(ip_cur);
331 matchedReferencePoints.push_back((
unsigned int)k);
337 for (
unsigned int i = 0; i < m; i++) {
338 if (bestMatches[i] >= 0) {
339 refPt.push_back(modelPoints[i].pt);
340 curPt.push_back(imgKeypoints[(
unsigned int)bestMatches[i]].pt);
361 const unsigned int _height,
const unsigned int _width)
364 vpTRACE(
"Bad size for the subimage");
372 return this->matchPoint(subImage);
391 return (this->matchPoint(_I, iP, (
unsigned int)_rectangle.
getHeight(), (
unsigned int)_rectangle.
getWidth()));
414 for (
unsigned int i = 0; i < matchedReferencePoints.size(); i++) {
433 for (
unsigned int i = 0; i < matchedReferencePoints.size(); i++) {
449 void vpFernClassifier::load(
const std::string &_dataFile,
const std::string & )
451 std::cout <<
" > Load data for the planar object detector..." << std::endl;
454 cv::FileStorage fs(_dataFile, cv::FileStorage::READ);
455 cv::FileNode node = fs.getFirstTopLevelNode();
457 cv::FileNodeIterator it = node[
"model-roi"].begin(), it_end;
458 it >> modelROI.x >> modelROI.y >> modelROI.width >> modelROI.height;
460 ldetector.read(node[
"detector"]);
461 fernClassifier.read(node[
"fern-classifier"]);
463 const cv::FileNode node_ = node[
"model-points"];
464 cv::read(node_, modelPoints);
466 cv::LDetector d(radius, threshold, nbOctave, nbView, patchSize, dist);
478 void vpFernClassifier::record(
const std::string &_objectName,
const std::string &_dataFile)
481 cv::FileStorage fs(_dataFile, cv::FileStorage::WRITE);
483 cv::WriteStructContext ws(fs, _objectName, CV_NODE_MAP);
486 cv::WriteStructContext wsroi(fs,
"model-roi", CV_NODE_SEQ + CV_NODE_FLOW);
487 cv::write(fs, modelROI_Ref.x);
488 cv::write(fs, modelROI_Ref.y);
489 cv::write(fs, modelROI_Ref.width);
490 cv::write(fs, modelROI_Ref.height);
493 ldetector.write(fs,
"detector");
494 cv::write(fs,
"model-points", modelPoints);
495 fernClassifier.write(fs,
"fern-classifier");
506 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
509 if (curImg != NULL) {
510 cvResetImageROI(curImg);
511 if ((curImg->width % 8) == 0) {
512 curImg->imageData = NULL;
513 cvReleaseImageHeader(&curImg);
515 cvReleaseImage(&curImg);
520 curImg = cvCreateImageHeader(cvSize((
int)I.
getWidth(), (int)I.
getHeight()), IPL_DEPTH_8U, 1);
521 if (curImg != NULL) {
522 curImg->imageData = (
char *)I.
bitmap;
529 if (curImg == NULL) {
530 std::cout <<
"!> conversion failed" << std::endl;
536 #elif !defined(VISP_BUILD_SHARED_LIBS)
539 void dummy_vpFernClassifier(){};