8

SurfFeatureDetector を一連の領域 (マスク) に制限したい。テストでは、マスクを 1 つだけ定義します。

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

「roi」をマスクとして渡すと、次のエラーが発生します。

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 の "detect" メソッドに正しく渡すにはどうすればよいですか?

よろしく、

4

3 に答える 3

18

マスクについて2点。

  • マスクは、opencv type に変換される 8 ビット符号なし文字の 1 チャネル マトリックスである必要があります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
// 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
于 2013-05-03T19:35:26.587 に答える
2

あなたのROIコードを、私が取り組んでいた既存のコードに追加しました。次の変更を加えて、私にとってはうまくいきました

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、トリプル チャネル イメージにマップされます。

于 2013-05-03T19:36:07.463 に答える