“边缘检测”和“图像轮廓”之间的区别

请看下面的代码

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

Mat src, grey;
int thresh = 10;

const char* windowName = "Contours";

void detectContours(int,void*);

int main()
{
    src = imread("C:/Users/Public/Pictures/Sample Pictures/Penguins.jpg");

    //Convert to grey scale
    cvtColor(src,grey,CV_BGR2GRAY);

    //Remove the noise
    cv::GaussianBlur(grey,grey,Size(3,3),0);

    //Create the window
    namedWindow(windowName);

    //Display the original image
    namedWindow("Original");
    imshow("Original",src);

    //Create the trackbar
    cv::createTrackbar("Thresholding",windowName,&thresh,255,detectContours);

    detectContours(0,0);
    waitKey(0);
    return 0;

}

void detectContours(int,void*)
{
    Mat canny_output,drawing;

    vector<vector<Point>> contours;
    vector<Vec4i>heirachy;

    //Detect edges using canny
    cv::Canny(grey,canny_output,thresh,2*thresh);

    namedWindow("Canny");
    imshow("Canny",canny_output);

    //Find contours
    cv::findContours(canny_output,contours,heirachy,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE,Point(0,0));

    //Setup the output into black
    drawing = Mat::zeros(canny_output.size(),CV_8UC3);



    //Draw contours
    for(int i=0;i<contours.size();i++)
    {
        cv::drawContours(drawing,contours,i,Scalar(255,255,255),1,8,heirachy,0,Point());
    }

    imshow(windowName,drawing);

}

理论上, Contours意味着检测曲线。 Edge detection意味着检测边缘。 在我上面的代码中,我使用Canny完成了边缘检测,并通过findContours()曲线检测。 以下是最终的图像

Canny图像

在这里输入图像描述

轮廓图像

在这里输入图像描述

好的,现在,你可以看到,没有什么区别! 那么,这两个实际的区别是什么? 在OpenCV教程中,只给出了代码。 我找到了关于什么是Contours的解释,但它没有解决这个问题。

请帮忙!


边缘被计算为梯度方向上图像梯度极值的点。 如果有帮助,你可以将它们看作一维函数中的最小和最大点。 重点是,边缘像素是一个局部的概念:他们只是指出了相邻像素之间的显着差异。

轮廓通常从边缘获得,但它们旨在成为对象轮廓。 因此,他们需要闭合曲线。 你可以将它们看作边界(一些图像处理算法和图书馆称它们为这样的边界)。 从边缘获得它们时,需要连接边缘以获得封闭的轮廓。


查找边和计数的主要区别在于,如果您运行查找边缘,则输出是新图像。 在这个新的(边缘图像)图像中,您将突出显示边缘。 另外还有很多用于检测边缘的算法。

例如Sobel操作员可以提供平滑的“模糊”结果。 在你的特定情况下,问题在于你正在使用Canny边缘检测器。 这个比其他探测器更进一步。 它实际上运行了更多边缘细化步骤。 Canny检测器的输出是二值图像,1px宽线代替边缘。

另一方面Contours算法处理任意的二值图像。 所以如果你把黑色背景上的白色填充正方形。 运行Contours算法后,您将获得白色的空白正方形,只是边框。

其他额外的轮廓检测奖励,它实际上返回一组点! 这很好,因为你可以进一步使用这些点进行一些处理。

在你的特定情况下,两个图像匹配只是巧合。 它不是规则,在你的情况下,这是因为Canny算法的独特性质。


轮廓实际上可以做的不仅仅是“检测”边缘。 该算法确实可以找到图像的边缘,但也可以将它们放在层次结构中。 这意味着您可以请求图像中检测到的物体的外部边界。 如果你只检查边缘,这样的事情不会(直接)可能。

从文档中可以看出,轮廓主要用于物体识别,其中Canny边缘检测器是一种更“全局”的操作。 如果轮廓算法使用某种Canny边缘检测,我不会感到惊讶。

链接地址: http://www.djcxy.com/p/64029.html

上一篇: Difference between "Edge Detection" and "Image Contours"

下一篇: OpenCV Python and Histogram of Oriented Gradient