Ask Your Question
0

mask in FlannBasedMatcher::match doesn't work normally

asked 2017-11-16 03:00:19 -0600

yode gravatar image

updated 2017-11-16 20:07:35 -0600

Cross post here


I note the FlannBasedMatcher::match have a parameter mask, so I give a try with following code:

#include<opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;
using namespace std;

int main() {
    Mat rightImg = imread("right.jpg", 0);
    Mat leanImg = imread("lean.jpg", 0);
    if (!rightImg.data || !leanImg.data) {
        cout << "Fail to read your image. Please check your path.\n";
        return -1;
    }
    resize(leanImg, leanImg, rightImg.size());
    int minHessian = 400;
    SurfFeatureDetector detector(minHessian);
    vector<KeyPoint> keypoints_right, keypoints_lean;

    detector.detect(rightImg, keypoints_right);
    detector.detect(leanImg, keypoints_lean);

    Mat med_right, med_lean;
    drawKeypoints(rightImg, keypoints_right, med_right);
    drawKeypoints(leanImg, keypoints_lean, med_lean);

    SurfDescriptorExtractor extractor;
    Mat descriptors_right, descriptors_lean;
    extractor.compute(rightImg, keypoints_right, descriptors_right);
    extractor.compute(leanImg, keypoints_lean, descriptors_lean);

    FlannBasedMatcher matcher;
    vector< DMatch > matches;

    Mat mask(rightImg.size(), CV_8UC1, Scalar(255));

    ellipse(mask, Point(rightImg.cols / 2, rightImg.rows / 2), Size(rightImg.cols / 2.5, rightImg.rows / 2.5), 0, 0, 360, Scalar(0), CV_FILLED);

    matcher.match(descriptors_right, descriptors_lean, matches/*, mask*/);// You can use the mask or not to test

    Mat img_matches;
    drawMatches(rightImg, keypoints_right, leanImg, keypoints_lean,
        matches, img_matches, Scalar::all(-1), Scalar::all(-1),
        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    return 0;
    }

And this is my right.jpg and lean.jpg. But I note I will get a same result totally whether I use the mask in the function FlannBasedMatcher::match. You can use the mask or not to reproduce it. Do I have missed something or the OpenCV have a bug in my 2.4.13? Can anyone tell me how to use the mask in the FlannBasedMatcher::match? I even don't know its size should same with the query image or train image. But I think it is a usefull parameter..

edit retag flag offensive close merge delete

Comments

why do you want to use a mask, and where would you get the information, how to fill it ?

https://docs.opencv.org/master/db/d39...

Namely, queryDescriptors[i] can be matched with trainDescriptors[j] only if mask.at<uchar>(i,j) is non-zero.

see, that is not an "image", the shape of your mask is entirely wrong, if at all, it should be:

Mat mask(nquery_descs, ntrain_descs, CV_8UC1, Scalar(255));

but what to mask out there ? we're back at the why ...

berak gravatar imageberak ( 2017-11-16 03:13:26 -0600 )edit

@berak I'm sorry, actually no why. I'm just studing OpenCV, and I want to know how to use the parameter of mask..I don't care those points in the center of right.jpg. So I create those mask.

yode gravatar imageyode ( 2017-11-16 03:44:57 -0600 )edit

".I don't care those points in the center of right.jpg"

i never used this, but i guess, what you have to do then is: find the keypoints in the right image, which you want to ignore, and set the resp. column in the mask to 0

again it's not the image size, you have to use the keypoint indices, not their coords

berak gravatar imageberak ( 2017-11-16 03:57:01 -0600 )edit

@berak As you first comment and your link, I make a new comment. But seen don't work still..

yode gravatar imageyode ( 2017-11-16 07:59:26 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
0

answered 2017-11-17 02:07:58 -0600

berak gravatar image

updated 2017-11-17 02:08:38 -0600

so, just for the record, the FlannBasedMatcher does not support using masks at all:

Ptr<FlannBasedMatcher> fl = FlannBasedMatcher::create();

cerr << fl->isMaskSupported();

0
edit flag offensive delete link more

Comments

Could I know which version are you using?

yode gravatar imageyode ( 2017-11-17 02:10:17 -0600 )edit

3.3.1. (latest)

but it's the same problem in 2.4

berak gravatar imageberak ( 2017-11-17 02:12:12 -0600 )edit

Yes, I'm in 2.4.13. You mean you are using 3.3.1, it don't support the mask parameter neither??? I'm compling the 3.3.1 now.. But I hope to use the mask in my task. Is there any workaroud?

yode gravatar imageyode ( 2017-11-17 02:16:08 -0600 )edit

As I know, we can build a matcher by BruteForceMatcher and FlannBaseMatcher. The BruteForceMatcher is expired. Is there any class to do this?

yode gravatar imageyode ( 2017-11-17 02:21:47 -0600 )edit

tl;dr: only BFMatcher supports it

berak gravatar imageberak ( 2017-11-17 02:22:05 -0600 )edit
0

answered 2017-11-16 07:57:57 -0600

yode gravatar image

Actually this is not a answer but a long comment for @berak. As the mention, I make a new code for this target

#include<opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;
using namespace std;

int main() {
    Mat rightImg = imread("right.jpg", 0);
    Mat leanImg = imread("lean.jpg", 0);
    if (!rightImg.data || !leanImg.data) {
        cout << "Fail to read your image. Please check your path.\n";
        return -1;
    }
    resize(leanImg, leanImg, rightImg.size());
    int minHessian = 400;
    SurfFeatureDetector detector(minHessian);
    vector<KeyPoint> keypoints_right, keypoints_lean;

    detector.detect(rightImg, keypoints_right);
    detector.detect(leanImg, keypoints_lean);

    Mat med_right, med_lean;
    drawKeypoints(rightImg, keypoints_right, med_right);
    drawKeypoints(leanImg, keypoints_lean, med_lean);

    SurfDescriptorExtractor extractor;
    Mat descriptors_right, descriptors_lean;
    extractor.compute(rightImg, keypoints_right, descriptors_right);
    extractor.compute(leanImg, keypoints_lean, descriptors_lean);

    FlannBasedMatcher matcher;
    vector< DMatch > matches;

    /*New mask*/
    Mat mask(descriptors_right.rows, descriptors_lean.rows, CV_8UC1, Scalar(0));

    Mat target(rightImg.size(), CV_8UC1, Scalar(255));
    ellipse(target, Point(rightImg.cols / 2, rightImg.rows / 2), Size(rightImg.cols / 2, rightImg.rows / 2), 0, 0, 360, Scalar(0), CV_FILLED);

    for (int i = 0; i < mask.rows; i++) {
        uchar* pixrow = mask.ptr<uchar>(i);
        for (int j = 0; j < mask.cols; j++) {
            if (target.at<uchar>(keypoints_right[i].pt) == 255)
                pixrow[j] = 255;
        }
    }
   /*New mask*/

    matcher.match(descriptors_right, descriptors_lean, matches, mask);

    Mat img_matches;
    drawMatches(rightImg, keypoints_right, leanImg, keypoints_lean,
        matches, img_matches, Scalar::all(-1), Scalar::all(-1),
        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    return 0;
    }

But it seem don't work me still..

edit flag offensive delete link more

Comments

i feel honoured, already ;)

berak gravatar imageberak ( 2017-11-16 07:58:50 -0600 )edit

@berak Sorry my English,Why feel honoured?

yode gravatar imageyode ( 2017-11-16 08:01:16 -0600 )edit

just joking, you made an answer specially for me ... ;)

berak gravatar imageberak ( 2017-11-16 08:04:34 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-11-16 03:00:19 -0600

Seen: 694 times

Last updated: Nov 17 '17