Ask Your Question
2

Behaviour of ORB keypoint detection with masks

asked 2016-09-27 08:14:21 -0600

Mellon gravatar image

I was doing some work in OpenCV 2.4.8 and I noticed a strange behaviour when detecting keypoints using ORB: ORB::detect() gives a different result if I use an all-permissive mask (all set to non-zero values). I was expecting the same result, but the keypoints got smaller, like if the pyramid used to detect keypoints had less levels, even if I used the same default parameters.

Does anyone know if this is the desired behaviour? And if it is, why?

Here it goes a minimal working example:

#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>

void orb_without_mask(const cv::Mat & img)
{
    cv::ORB orb;
    std::vector<cv::KeyPoint> keypoints;
    orb.detect(img, keypoints);
    // Decriptors not needed, but I compute it anyway because keypoints vector
    // may change based on descriptor computation (be reordered or have
    // elements removed)
    cv::Mat descriptors;
    orb.compute(img, keypoints, descriptors);
    cv::Mat output_img;
    cv::drawKeypoints(img,
        keypoints,
        output_img,
        cv::Scalar::all(-1),
        cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::imshow("orb_mwe", output_img);
    cv::waitKey(0);
}

// Same as before, but with a mask of the same size as the image that accepts
// everything
void orb_with_mask(const cv::Mat & img)
{
    cv::ORB orb;
    std::vector<cv::KeyPoint> keypoints;
    cv::Mat mask(cv::Mat::ones(img.size(),CV_8U)); // declare mask here 
    orb.detect(img, keypoints, mask);              // use mask here
    cv::Mat descriptors;
    orb.compute(img, keypoints, descriptors);
    cv::Mat output_img;
    cv::drawKeypoints(img,
        keypoints,
        output_img,
        cv::Scalar::all(-1),
        cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    cv::imshow("orb_mwe", output_img);
    cv::waitKey(0);
}

int main(int argc, char const *argv[])
{
    cv::namedWindow("orb_mwe", cv::WINDOW_NORMAL);
    cv::Mat img = cv::imread( argv[1] );
    orb_without_mask(img);
    orb_with_mask(img);
    return 0;
}

And the results I got:

image description

image description

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-09-27 11:14:13 -0600

Tetragramm gravatar image

Change the mask from all 1s to all 255s. When ORB resizes the mask for the smaller layers, I suspect there's a check for edges that ensures the mask is greater than some value.

edit flag offensive delete link more

Comments

Thanks! It solved the problem.

Mellon gravatar imageMellon ( 2016-09-28 04:26:52 -0600 )edit

How does the change from all 1s to 255s exactly occur? cv::Mat mask(255 * cv::Mat::ones(img.size(),CV_8U)); ?

Farid gravatar imageFarid ( 2019-07-19 05:28:24 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-09-27 08:07:41 -0600

Seen: 4,796 times

Last updated: Sep 27 '16