我正在使用opencv进行对象检测。 我想用鼠标点击对象后围绕对象绘制一个矩形。 我可以使用什么样的技术?我试过SURF但是徒劳无功。
任何帮助将不胜感激。
答案 0 :(得分: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);
}
答案 1 :(得分:0)
必须首先检测对象,然后才能找到其边界矩形。通过单击对象,您只需指定属于该对象的像素。这还不够,因为你对物体的形状一无所知。因此,单击对象不等于对象检测。
如何检测对象取决于应用程序。找到对象轮廓(边缘)的一种方法是通过分割。在OpenCV中查看watershed或grabcut分段算法。它将为您提供对象的轮廓(如果对象从其背景中突出)。一般来说,对象检测的方法取决于应用程序,它是一个活跃的研究领域。知道检测到哪种物体可以极大地帮助检测和分割。
获得对象轮廓后,可以使用boundingRect函数找到其边界矩形。绘制矩形很简单,只需使用rectangle函数。
答案 2 :(得分:0)
如果对象相当简单并且使用一种颜色,则可以尝试使用watershed algorithm https://code.ros.org/trac/opencv/browser/trunk/opencv/samples/cpp/watershed.cpp?rev=4270它应该适用于铅笔等一个颜色对象,但在更复杂的情况下肯定会失败。
答案 3 :(得分:0)
我最好的建议是首先使用一些OpenCV图像处理技术来检测物体,例如......阈值来对你的图像进行二值化,使用模糊来增强边缘检测,使用精细过滤器可能会腐蚀和扩张。
一旦你获得了一个体面的门槛,你的投资回报率从背景中脱颖而出,我会使用一个名为findcontours的函数来获取图像中存在的所有斑点的轮廓,如果你得到一些不同的轮廓你可以指定只绘制轮廓the are大于X.
一旦你存储了ROI的轮廓(在矢量中),下一步就是使用Rect函数在这些轮廓周围绘制边界框。
对于每个问题,OpenCV都是一个非常开放的领域,您可以选择采用大量解决方案或路径。我强烈建议您访问OpenCv Documentation
但首先请检查您已安装或使用
的opencv版本答案 4 :(得分:0)
cvtColor erode dilate
之后// 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) ;