Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

like image 321
Hyndrix Avatar asked May 03 '13 18:05

Hyndrix


People also ask

How do you detect a feature using SIFT SURF orb algorithm?

SIFT and SURF detect more features then ORB, but ORB is faster. We then load one by one the three algorythms. We find the keypoints and descriptors of each spefic algorythm. A keypoint is the position where the feature has been detected, while the descriptor is an array containing numbers to describe that feature.

Why is SIFT better than surfing?

SURF is better than SIFT in rotation invariant, blur and warp transform. SIFT is better than SURF in different scale images. SURF is 3 times faster than SIFT because using of integral image and box filter. SIFT and SURF are good in illumination changes images.

Is SIFT available in OpenCV?

Example: SIFT detector in Python jpg” generates the “image-with-keypoints. jpg” which contains the interest points, detected using the SIFT module in OpenCV, marked using circular overlays. Note: SIFT detector has been removed in the latest versions of OpenCV ( ≥ 3.4. 2.16).


2 Answers

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
like image 165
Alexey Avatar answered Oct 30 '22 15:10

Alexey


I tacked your ROI code onto some existing code I was working on, with the following changes it worked for me

cv::Mat mask = cv::Mat::zeros(frame.size(), CV_8UC1);  //NOTE: using the type explicitly
cv::Mat roi(mask, cv::Rect(10,10,100,100));
roi = cv::Scalar(255, 255, 255);

//SURF feature detection
const int minHessian = 400;
cv::SurfFeatureDetector detector(minHessian);
std::vector<cv::KeyPoint> keypoints;
detector.detect(frame, keypoints, mask);              //NOTE: using mask here, NOT roi
cv::Mat img_keypoints; 
drawKeypoints(frame, keypoints, img_keypoints, cv::Scalar::all(-1), cv::DrawMatchesFlags::DEFAULT);
cv::imshow("input image + Keypoints", img_keypoints);
cv::waitKey(0);

Without the changes to the type and the use of mask instead of roi as your mask, I'd get a runtime error as well. This makes sense, as the detect method wants a mask -- it should be the same size as the original image, and roi isn't (it's a 100x100 rectangle). To see this visually, try displaying the mask and the roi

cv::imshow("Mask", mask);
cv::waitKey(0);

cv::imshow("ROI", roi);
cv::waitKey(0);

The type has to match also; the mask should be single channel, while your image type is likely of type 16, which maps to CV_8UC3, a triple channel image

like image 2
alrikai Avatar answered Oct 30 '22 14:10

alrikai