2013-05-03 17 views
5

Chcę ograniczyć SurfFeatureDetector do zestawu regionów (maska). Dla testu zdefiniować tylko jedną maskę:OpenCV: howto użyj parametru maski do detekcji punktu cechy (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 

Kiedy przechodzą „ROI” jako maska ​​otrzymuję ten błąd:

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 

Co jest nie tak z tym? Jak poprawnie przekazać maskę do metody "wykrywania" SurfFeatureDetector?

Pozdrawiam,

Odpowiedz

13

Dwie rzeczy o masce.

  • maska ​​powinna być matrycą 1 kanał 8-bitowych znaków bez znaku, co przekłada się na OpenCV typu CV_8U. W twoim przypadku maska ​​jest typu srcImage.type(), która jest 3-kanałową macierzą
  • przechodzisz roi do detektora, ale powinieneś przechodzić mask. Podczas wprowadzania zmian na roi zmienia się również mask.

dodaje powinien działać

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

Dzięki, to działa. – Hyndrix

+0

Myślę, że powinno to być 'Scalar (255);' ponieważ maska ​​jest jednowymiarowa. –

+0

'roi' ma 3 kanały, takie same jak' srcImage' ('roi' to podmatryca' srcImage') – Alexey

1

ja zostałam zaatakowana kod ROI na jakimś istniejącym kodem byłem w pracy, z następującymi zmianami pracował dla mnie

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

Bez zmian Typ i użycie maski mask zamiast roi również dostanę błąd runtime. Ma to sens, ponieważ metoda wykrywania wymaga maski - powinna mieć ten sam rozmiar co oryginalny obraz, a roi nie jest (jest to prostokąt 100x100). Aby zobaczyć to wizualnie, spróbuj wyświetlić maskę i roi. Typ musi również pasować; maska ​​powinna być pojedynczy kanał, a Twój typ obrazu jest prawdopodobnie typu 16, który mapuje do CV_8UC3, potrójne kanału obraz

0

Jeśli szukasz, aby zastosować takie same dla nieregularnej maski następnie:

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 
    } 

Następnie jak zwykle wygeneruj wskaźnik SIFT/SURF/...

// Utwórz inteligentny wskaźnik dla detektora funkcji 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);