1

我正在使用 opencv 进行对象检测。我想在用鼠标单击对象后在对象周围绘制一个矩形。我可以使用什么样的技术?我尝试使用 SURF 但徒劳无功。

任何帮助将不胜感激。

4

5 回答 5

6

你想使用什么样的图像?如果图像是一种简单的图像(例如白纸上的铅笔,普通墙上的标记),您会考虑使用以下方法吗?我认为这是非常经典的方法,但在情况有限时效果很好。

cv::Mat img = // your image.
double threshold = 128; // needs adjustment.
int n_erode_dilate = 1; // needs adjustment.

cv::Mat m = img.clone();
cv::cvtColor(m, m, CV_RGB2GRAY); // convert to glayscale image.
cv::blur(m, m, cv::Size(5,5));
cv::threshold(m, m, threshold, 255,CV_THRESH_BINARY_INV);
cv::erode(m, m, cv::Mat(),cv::Point(-1,-1),n_erode_dilate);
cv::dilate(m, m, cv::Mat(),cv::Point(-1,-1),n_erode_dilate);

std::vector< std::vector<cv::Point> > contours;
std::vector<cv::Point> points;
cv::findContours(m, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
for (size_t i=0; i<contours.size(); i++) {
    for (size_t j = 0; j < contours[i].size(); j++) {
        cv::Point p = contours[i][j];
        points.push_back(p);
    }
}
// And process the points or contours to pick up specified object.

// for example: draws rectangle on original image.
if(points.size() > 0){
    cv::Rect brect = cv::boundingRect(cv::Mat(points).reshape(2));
    cv::rectangle(img, brect.tl(), brect.br(), cv::Scalar(100, 100, 200), 2, CV_AA);
}
于 2013-03-31T13:52:39.897 回答
1

我最好的建议是首先使用一些 OpenCV 图像处理技术检测对象,例如......阈值来二进制图像,使用模糊来增强边缘检测,使用 canny 过滤器可能会腐蚀和膨胀。

一旦你得到一个合适的阈值,你的投资回报率从背景中脱颖而出,我将使用一个名为 findcontours 的函数来获取图像中存在的所有斑点的轮廓,如果你得到一些不常见的轮廓,你可以指定只绘制轮廓,如果是大于 X。

一旦存储了 ROI 的轮廓(在向量中),下一步就是使用 Rect 函数在这些轮廓周围绘制边界框。

对于每个问题,OpenCV 都是一个非常开放的领域,有很多解决方案或路径可供您选择。我强烈建议访问OpenCv 文档

但首先检查你已经安装或使用的opencv的版本

于 2013-04-02T02:02:44.530 回答
0

必须先检测对象,然后才能找到其边界矩形。通过单击对象,您只需指定属于该对象的像素。这还不够,因为您对物体的形状一无所知。所以点击物体不等于物体检测。

如何检测对象取决于应用程序。找到对象轮廓(边缘)的一种方法是分割。研究OpenCV中的分水岭抓取分割算法。它将为您提供对象的轮廓(如果对象从其背景中突出)。一般来说,目标检测方法取决于应用程序,是一个活跃的研究领域。了解正在检测的对象类型可以极大地帮助检测和分割。

一旦你有了对象的轮廓,你就可以使用boundingRect函数找到它的边界矩形。绘制矩形很容易,只需使用矩形函数即可。

于 2013-03-31T15:09:55.977 回答
0

如果对象比较简单,只有一种颜色,可以尝试使用分水岭算法。它应该适用于像铅笔这样的一种颜色的物体,但在更复杂的情况下肯定会失败。

于 2013-03-31T15:12:16.503 回答
0

cvtColor 侵蚀扩张后

// get the contours
std::vector< std::vector< cv::Point> > contours;
cv::findContours(imageMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

// http://blog.csdn.net/corcplusplusorjava/article/details/20536251
// draw contours
cv::drawContours(imageMat , allContours ,-1 , cv::Scalar(0) , 2) ; 
于 2017-06-20T15:54:26.610 回答