OpenCV:如何使用mask参数进行特征点检测(SURF)
OpenCV: howto use mask parameter for feature point detection (SURF)
我想限制一个surfffeaturedetector到一组区域(掩码)。对于一个测试,我只定义了一个掩码:
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的"检测"方法?
认为,
关于遮罩的两件事
- 掩码应该是一个8位无符号字符的1通道矩阵,转换为openv类型
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
我将您的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);
类型必须匹配also;遮罩应该是单通道,而您的图像类型可能是类型16,它映射到CV_8UC3
,一个三通道图像
如果你想对不规则蒙版应用相同的方法,那么:
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);
相关文章:
- 用于检测函数类型是否为否的特征
- 在不使用经过训练的模型的情况下检测/分割面部和面部特征:openCV C++
- 拼接图像无法检测常见特征点
- 创建特征以检测C++中的闭包类型
- 我们应该认为评估特征检测,描述和匹配的主要速率和值是多少
- 怎么来了?在特征中未检测到别名
- 为什么这C++检测T型是否具有空运算符(EDT const&)失败的特征?
- 特征检测部门的Sfinae问题
- 面部特征检测-眼角、眉毛
- Dev C 中的Flandmark库,用于特征点检测
- 编译时解决方案以检测特征对象没有eval()成员
- XML文件中Haar级联正面人脸检测的特征向量大小是多少
- 元函数,具有对缺失特征的默认行为以及如何检测随机访问
- STASM人脸特征检测的工作原理
- 特征检测算法的实现
- 如何在Visual c++ 9中使用类型特征检测按位移动类型?
- 城市环境中特征检测的最佳算法- OpenCV
- 在openv中使用GridAdaptedFeatureDetector进行特征检测
- C++ - 使用 ORB 进行 OpenCV 特征检测
- 如何在opencv中制作自己的特征检测方法