【问题标题】: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&lt;vector&lt;Point&gt; &gt;,因此只需将一只眼睛的所有轮廓的所有点放入vector&lt;Point&gt;bounding_rect() 将生成可以使用cv::rectangle() 绘制的框。

标签: c++ opencv edge-detection rect


【解决方案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 );
}

【讨论】:

    猜你喜欢
    • 2018-02-12
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多