Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Behaviour of ORB keypoint detection with masks

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