在精明边缘的结果周围绘制矩形
Posted
技术标签:
【中文标题】在精明边缘的结果周围绘制矩形【英文标题】:Draw Rect around result of canny edge 【发布时间】:2016-01-06 10:59:10 【问题描述】:我想在检测到的精巧边缘周围绘制矩形。我有这张图像是眼睛检测、形态学操作和精明边缘的结果。
我尝试使用轮廓通过 rect 对其进行边界,但结果不准确。
我怎样才能得到类似这张图片的东西?
我正在使用这个函数来绘制轮廓:
void find_contour(Mat image)
Mat src_mat, gray_mat, canny_mat;
Mat contour_mat;
Mat bounding_mat;
contour_mat = image.clone();
bounding_mat = image.clone();
cvtColor(image, gray_mat, CV_GRAY2BGR);
// apply canny edge detection
Canny(gray_mat, canny_mat, 30, 128, 3, false);
//3. Find & process the contours
//3.1 find contours on the edge image.
vector< vector< cv::Point> > contours;
findContours(canny_mat, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//3.2 draw contours & property value on the source image.
int largest_area = 0;
int largest_contour_index = 0;
Rect bounding_rect;
for (size_t i = 0; i< contours.size(); i++) // iterate through each contour.
double area = contourArea(contours[i]); // Find the area of contour
if (area > largest_area)
largest_area = area;
largest_contour_index = i; //Store the index of largest contour
bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
drawContours(image, contours, largest_contour_index, Scalar(0, 255, 0), 2);
imshow("Bounding ", image);
【问题讨论】:
boundingRect()
创建的边界矩形“不准确”?是对的吗?如果您想要更小的界限,您可以尝试cv::minAreaRect()
以获得可能更小的RotatedRect
。但是,如果您绘制 bounding_rect
例如,您的示例就是您所得到的。使用cv::line()
。你能举个“不准确”的例子并解释问题出在哪里吗?
这个 postimg.org/image/ursfkojs5 是 boundRect 使用轮廓的输出,它没有像我想要的那样在上图中绘制
在 imshow 之前使用 cv::rectangle(image, bounding_rect, cv::Scalar(255,255,255));
。但这只会绘制一个(最大的)轮廓的边界框,所以如果你想要 ALL,你必须对每个矩形使用调用它,而不仅仅是最大的轮廓。
轮廓是vector<vector<Point> >
,因此只需将一只眼睛的所有轮廓的所有点放入vector<Point>
和bounding_rect()
将生成可以使用cv::rectangle()
绘制的框。
【参考方案1】:
在您的代码中,您根本没有绘制边界矩形。试试这个:
void find_contour(Mat image)
Mat src_mat, gray_mat, canny_mat;
Mat contour_mat;
Mat bounding_mat;
contour_mat = image.clone();
bounding_mat = image.clone();
cvtColor(image, gray_mat, CV_GRAY2BGR);
// apply canny edge detection
Canny(gray_mat, canny_mat, 30, 128, 3, false);
//3. Find & process the contours
//3.1 find contours on the edge image.
vector< vector< cv::Point> > contours;
findContours(canny_mat, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//3.2 draw contours & property value on the source image.
int largest_area = 0;
int largest_contour_index = 0;
Rect bounding_rect;
for (size_t i = 0; i< contours.size(); i++) // iterate through each contour.
// draw rectangle around the contour:
cv::Rect boundingBox = boundingRect(contours[i]);
cv::rectangle(image, boundingBox, cv::Scalar(255,0,255)); // if you want read and "image" is color image, use cv::Scalar(0,0,255) instead
// you aren't using the largest contour at all? no need to compute it...
/*
double area = contourArea(contours[i]); // Find the area of contour
if (area > largest_area)
largest_area = area;
largest_contour_index = i; //Store the index of largest contour
bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
*/
//drawContours(image, contours, largest_contour_index, Scalar(0, 255, 0), 2);
imshow("Bounding ", image);
【讨论】:
HI @Micka 感谢您的帮助,这是输出仍然不准确postimg.org/image/4odd9xjix 眼睛周围可能有矩形 看起来你的轮廓不太好?如果实际上仅绘制最大轮廓就足够了(如果您只想提取最大轮廓),您是否可以通过调整我的代码示例来绘制它? 我已经更新了您的代码,但没有改变该区域周围许多 Rects 的相同结果 我可以使用 Blob 吗?【参考方案2】:你也可以这样做,
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
vector<RotatedRect> minRect( contours.size() );
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
Scalar color = Scalar(255, 255, 255);
cv::Rect boundingBox = cv::boundingRect(cv::Mat(contours[i]));
minRect[i] = minAreaRect(Mat(contours[i]));
drawContours( drawing, contours, i, color, 1, 8, hierarchy, 0, Point() );
for( int i = 0; i< contours.size(); i++ )
// rotated rectangle
Point2f rect_points[4]; minRect[i].points( rect_points );
for( int j = 0; j < 4; j++ )
line( drawing, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8 );
【讨论】:
以上是关于在精明边缘的结果周围绘制矩形的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV:Canny 边缘检测器获取 minEnclosureCircle