使用 OpenCV C++ 查找已知对象
Posted
技术标签:
【中文标题】使用 OpenCV C++ 查找已知对象【英文标题】:Finding a known object with OpenCV C++ 【发布时间】:2016-03-09 16:41:50 【问题描述】:我是 OpenCV 的新手。我在 Visual Studio 2013,Windows 10 上使用 OpenCV - 2.4.12。我正在尝试创建一个程序,它将 2 个图像作为输入,并尝试在第 2 个图像中找到类似的第 1 个图像块。通过查找功能和 Homography.. 基本上我正在关注 This 教程。并成功实现了代码。所以我想更进一步,我想裁剪匹配的块......所以,我成功创建了一个蒙版图像,但是当我尝试 bitwise_and 或类似的东西时,它显示以下错误。
Unhandled exception at 0x772FD928 in OpenCVTut.exe Microsoft C++ exception: cv::Exception at memory location 0x0017E6C0.
我尝试了很多谷歌搜索...但找不到任何解决方案。以下是代码,以及我正在使用的图像和我生成的掩码..
#include <iostream>
#include <opencv2\opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\calib3d\calib3d.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\nonfree\nonfree.hpp>
using namespace std;
using namespace cv;
int main()
Mat imgObject = cvLoadImage("E:/opencv/images/Experiments/target.jpg", CV_LOAD_IMAGE_GRAYSCALE);
Mat imgScene = cvLoadImage("E:/opencv/images/Experiments/source.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (!imgObject.data || !imgScene.data)
cout << "Error reading images" << endl;
return -1;
int minHessian = 400;
SurfFeatureDetector detector(minHessian);
vector<KeyPoint> keyPointsObject;
vector<KeyPoint> keyPointsScene;
detector.detect(imgObject, keyPointsObject);
detector.detect(imgScene, keyPointsScene);
SurfDescriptorExtractor extractor;
Mat descriptorObject;
Mat descriptorScene;
extractor.compute(imgObject, keyPointsObject, descriptorObject);
extractor.compute(imgScene, keyPointsScene, descriptorScene);
FlannBasedMatcher matcher;
vector<DMatch> matches;
matcher.match(descriptorObject, descriptorScene, matches);
double maxDist = 0;
double minDist = 100;
for (int i = 0; i < descriptorObject.rows; i++)
double dist = matches[i].distance;
if (dist > maxDist) maxDist = dist;
if (dist < minDist) minDist = dist;
cout << "-- Max dist : " << maxDist << endl;
cout << "-- Min dist : " << minDist << endl;
vector<DMatch> goodMatches;
for (int i = 0; i < descriptorObject.rows; i++)
if (matches[i].distance < 3 * minDist)
goodMatches.push_back(matches[i]);
/*Mat imgMatches;
drawMatches(imgObject, keyPointsObject, imgScene, keyPointsScene,
goodMatches, imgMatches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);*/
vector<Point2f> obj;
vector<Point2f> scene;
for (int i = 0; i < goodMatches.size(); i++)
obj.push_back(keyPointsObject[goodMatches[i].queryIdx].pt);
scene.push_back(keyPointsScene[goodMatches[i].trainIdx].pt);
Mat H = findHomography(obj, scene, CV_RANSAC);
vector<Point2f> objCorners(4);
objCorners[0] = cvPoint(0, 0);
objCorners[1] = cvPoint(imgObject.cols, 0);
objCorners[2] = cvPoint(imgObject.cols, imgObject.rows);
objCorners[3] = cvPoint(0, imgObject.rows);
vector<Point2f> sceneCorners(4);
perspectiveTransform(objCorners, sceneCorners, H);
line(imgScene, sceneCorners[0], sceneCorners[1], Scalar(0, 255, 0), 4);
line(imgScene, sceneCorners[1], sceneCorners[2], Scalar(0, 255, 0), 4);
line(imgScene, sceneCorners[2], sceneCorners[3], Scalar(0, 255, 0), 4);
line(imgScene, sceneCorners[3], sceneCorners[0], Scalar(0, 255, 0), 4);
Mat mask = Mat::zeros(imgScene.rows, imgScene.cols, CV_8UC3);
vector< vector<Point> > contours;
vector< Vec4i > hierarchy;
Mat coun;
imgScene.copyTo(coun);
findContours(coun, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
Scalar color(255, 255, 255);
drawContours(mask, contours, 0, color, CV_FILLED, 8, hierarchy);
Mat element = getStructuringElement(MORPH_RECT, Size(2, 2), Point(0, 0));
dilate(mask, mask, element);
erode(mask, mask, element);
Mat res(imgScene.rows, imgScene.cols, CV_8UC1, Scalar(0, 0, 0));
bitwise_and(imgScene, mask, res);
namedWindow("Good Matches & Object detection", CV_WINDOW_AUTOSIZE);
imshow("Good Matches & Object detection", mask);
waitKey(0);
return 0;
场景
目标
面具
那么,谁能解释一下这个错误......以及我需要做些什么来解决它......
提前致谢:)
【问题讨论】:
您可以先检查在抛出此异常时中断的选项,然后自己看看为什么会抛出它。 @StoryTeller。也试过了......如果这很有意义,我不会在这里问......:p :')......就像我说的......我在opencv中很新,或者更有可能是计算机视觉。 请找到发生错误的代码行。偶尔使用调试器或 std::cout 一条独特的消息。 @Micka... 我很确定错误在“bitwise_and(imgScene, mask, res);”中这一行…… 【参考方案1】:错误发生在以下行:
bitwise_and(imgScene, mask, res);
因为这两个矩阵的类型不同:imgScene
是 CV_8UC1
矩阵,mask
是 CV_8UC3
。
由于掩码通常只是一个二进制图像,可以用单通道矩阵安全地表示,您可以修复您的代码,使mask
CV_8UC1
矩阵:
Mat mask = Mat::zeros(imgScene.rows, imgScene.cols, CV_8UC1); // Instead of CV_8UC3
【讨论】:
谢谢人...你是一个救生员 :D 很抱歉迟到的回应,搞砸了一些配置...不得不解决这个问题... :) ...非常感谢您的帮助。 .. :)以上是关于使用 OpenCV C++ 查找已知对象的主要内容,如果未能解决你的问题,请参考以下文章