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