Search code examples
c++opencvfeature-detectionsurfroi

OpenCV: howto use mask parameter for feature point detection (SURF)


I want to limit a SurfFeatureDetector to a set of regions (mask). For a test I define only a single mask:

Mat srcImage; //RGB source image
Mat mask = Mat::zeros(srcImage.size(), srcImage.type());
Mat roi(mask, cv::Rect(10,10,100,100));
roi = Scalar(255, 255, 255);
SurfFeatureDetector detector();
std::vector<KeyPoint> keypoints;
detector.detect(srcImage, keypoints, roi); // crash
//detector.detect(srcImage, keypoints); // does not crash

When I pass the "roi" as the mask I get this error:

OpenCV Error: Assertion failed (mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size())) in detect, file /Users/ux/Downloads/OpenCV-iOS/OpenCV-iOS/../opencv-svn/modules/features2d/src/detectors.cpp, line 63

What is wrong with this? How can I correctly pass a mask to the SurfFeatureDetector's "detect" method?

Regards,


Solution

  • Two things about the mask.

    • the mask should be a 1-channel matrix of 8-bit unsigned chars, which translates to opencv type CV_8U. In your case the mask is of type srcImage.type(), which is a 3-channel matrix
    • you are passing roi to the detector but you should be passing mask. When you are making changes to roi, you are also changing mask.

    the following should work

    Mat srcImage; //RGB source image
    Mat mask = Mat::zeros(srcImage.size(), CV_8U);  // type of mask is CV_8U
    // roi is a sub-image of mask specified by cv::Rect object
    Mat roi(mask, cv::Rect(10,10,100,100));
    // we set elements in roi region of the mask to 255 
    roi = Scalar(255);  
    SurfFeatureDetector detector();
    std::vector<KeyPoint> keypoints;
    detector.detect(srcImage, keypoints, mask);     // passing `mask` as a parameter