2013-05-03 240 views
5

我想將SurfFeatureDetector限制爲一組區域(掩碼)。對於一個測試,我只定義了一個面具:OpenCV:如何使用特徵點檢測的掩碼參數(SURF)

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 

當我通過「投資回報率」作爲掩膜我得到這個錯誤:

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 

有什麼不對呢?我如何正確地將掩碼傳遞給SurfFeatureDetector的「檢測」方法?

Regards,

回答

13

有關面膜的兩件事。

  • 該掩碼應該是一個8位無符號字符的1通道矩陣,它轉換爲opencv類型CV_8U。在你的情況下,掩碼的類型爲srcImage.type(),它是一個3通道矩陣,你正在將roi傳遞給檢測器,但你應該傳遞mask。當您對roi進行更改時,您也正在更改mask

以下應該工作

Mat srcImage; //RGB source image 
Mat mask = Mat::zeros(srcImage.size(), CV_8U); // type of mask is CV_8U 
Mat roi(mask, cv::Rect(10,10,100,100)); 
roi = Scalar(255, 255, 255); 
SurfFeatureDetector detector(); 
std::vector<KeyPoint> keypoints; 
detector.detect(srcImage, keypoints, mask);  // passing `mask` as a parameter 
+1

謝謝,這是工作。 – Hyndrix 2013-05-04 05:35:49

+0

我認爲它應該是'標量(255);'因爲面具是一維的。 – 2015-09-15 21:52:29

+0

'roi'有3個通道,與'srcImage'相同('roi'是'srcImage'的子矩陣) – Alexey 2015-09-16 12:47:19

1

我上漲你的投資回報率碼在一些現有的代碼我工作的,它爲我工作

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); 

沒有改變以下更改mask而不是roi作爲掩碼的類型和用法,我也會遇到運行時錯誤。這是有道理的,因爲檢測方法需要掩碼 - 它應該與原始圖像大小相同,而且roi不是(它是一個100x100的矩形)。爲了直觀地看到這種情況,嘗試顯示掩碼和roi

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

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

該類型也必須匹配;面膜應該是單通道,而你的圖像類型可能是16型,如果你正在尋找應用相同的不規則面膜,然後映射到CV_8UC3,三通道圖像

0

的:

Mat& obtainIregularROI(Mat& origImag, Point2f topLeft, Point2f topRight, Point2f botLeft, Point2f botRight){ 

     static Mat black(origImag.rows, origImag.cols, origImag.type(), cv::Scalar::all(0)); 
     Mat mask(origImag.rows, origImag.cols, CV_8UC1, cv::Scalar(0)); 
     vector< vector<Point> > co_ordinates; 
     co_ordinates.push_back(vector<Point>()); 
     co_ordinates[0].push_back(topLeft); 
     co_ordinates[0].push_back(botLeft); 
     co_ordinates[0].push_back(botRight); 
     co_ordinates[0].push_back(topRight); 
     drawContours(mask,co_ordinates,0, Scalar(255),CV_FILLED, 8); 

     // origImag.copyTo(black,mask); 
     //BasicAlgo::getInstance()->writeImage(black); 
     return mask; // returning the mask only 
    } 

然後照常生成SIFT/SURF/...指針

//爲SIFT特徵檢測器創建智能指針。

Ptr<FeatureDetector> SIFT_FeatureDetector = FeatureDetector::create("SIFT"); 
vector<KeyPoint> SIFT_Keypoints; 
vector<KeyPoint> SIFT_KeypointsRotated; 
Mat maskedImg = ImageDeformationOperations::getInstance()->obtainIregularROI(rotatedImg,rotTopLeft,rotTopRight,rotBotLeft,rotBotRight); 
SIFT_FeatureDetector->detect(rotatedImg, SIFT_KeypointsRotated, maskedImg); 
Mat outputSIFTKeyPt; 
drawKeypoints(rotatedImg, SIFT_KeypointsRotated, outputSIFTKeyPt, keypointColor, DrawMatchesFlags::DEFAULT);