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

Hyndrix picture Hyndrix · May 3, 2013 · Viewed 21.7k times · Source

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,

Answer

Alexey picture Alexey · May 3, 2013

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