C++ “边缘检测”和“图像轮廓”的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17103735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between "Edge Detection" and "Image Contours"
提问by Lemon Juice
I am working on the following code:
我正在处理以下代码:
#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);
}
Theoretically, Contours
means detecting curves. Edge detection
means detecting Edges. In my above code, I have done edge detection using Canny
and curve detection by findContours()
. Following are the resulting images
理论上,Contours
意味着检测曲线。Edge detection
表示检测边缘。在我上面的代码中,我使用做过边缘检测Canny
的曲线检测findContours()
。以下是生成的图像
Canny Image
精明的形象
Contours Image
轮廓图像
So now, as you can see, there is no difference! So, what is the actual difference between these 2? In OpenCV tutorials, only the code is given. I found an explanation about what is 'Contours' but it is not addressing this issue.
所以现在,如您所见,没有区别!那么,这两个之间的实际区别是什么?在 OpenCV 教程中,只给出了代码。我找到了关于什么是“轮廓”的解释,但它没有解决这个问题。
回答by sansuiso
Edgesare computed as points that are extrema of the image gradient in the direction of the gradient. if it helps, you can think of them as the min and max points in a 1D function. The point is, edge pixels are a local notion: they just point out a significant difference between neighbouring pixels.
边缘计算为梯度方向上图像梯度的极值点。如果有帮助,您可以将它们视为一维函数中的最小和最大点。关键是,边缘像素是一个局部概念:它们只是指出相邻像素之间的显着差异。
Contoursare often obtained from edges, but they are aimed at being object contours. Thus, they need to be closed curves. You can think of them as boundaries(some Image Processing algorithms & librarires call them like that). When they are obtained from edges, you need to connect the edges in order to obtain a closed contour.
轮廓通常从边缘获得,但它们旨在成为对象轮廓。因此,它们需要是闭合曲线。您可以将它们视为边界(一些图像处理算法和库就是这样称呼它们的)。当它们从边缘获得时,您需要连接边缘以获得闭合轮廓。
回答by jnovacho
The main difference between finding edges and countours is that if you run finding edges the output is new image. In this new (edge image) image you will have highlighted edges. There are many algorithms for detecting edges look at wiki see also.
寻找边缘和计数之间的主要区别在于,如果您运行寻找边缘,则输出是新图像。在这个新的(边缘图像)图像中,您将突出显示边缘。有许多用于检测边缘的算法,请参见 wiki。
For example Sobel operator gives smooth "foggy" results. In your particular case, the catch is that you are using Canny edge detector. This one makes few steps further than other detectors. It actually runs further edge refinement steps. Output of the Canny detector is thus binary image, with 1 px wide lines in place of edges.
例如,Sobel 算子给出了平滑的“模糊”结果。在您的特定情况下,问题在于您使用的是 Canny 边缘检测器。这个探测器比其他探测器更进一步。它实际上运行了进一步的边缘细化步骤。Canny 检测器的输出因此是二值图像,用 1 px 宽的线代替边缘。
On the other hand Contours
algorithm processes arbitrary binary image. So if you put in white filled square on black background. After running Contours
algorithm, you would get white empty square, just the borders.
另一方面,Contours
算法处理任意二进制图像。因此,如果您在黑色背景上放置白色填充方块。运行Contours
算法后,你会得到白色的空方块,只有边框。
Other added bonus of contour detection is, it actually returns set of points! That's great, because you can use these points further on for some processing.
轮廓检测的另一个额外好处是,它实际上返回了一组点!这很好,因为您可以进一步使用这些点进行一些处理。
In your particular case, it's only coincidence that both images match. It not rule, and in your case, it's because of unique property of Canny algorithm.
在您的特定情况下,两个图像匹配只是巧合。这不是规则,在你的情况下,这是因为 Canny 算法的独特属性。
回答by Nallath
Contours can actually do a bit more than "just" detect edges. The algorithm does indeed find edges of images, but also puts them in a hierarchy. This means that you can request outer borders of objects detected in your images. Such a thing would not be (directly) possible if you only check for edges.
轮廓实际上可以做的不仅仅是“只是”检测边缘。该算法确实找到了图像的边缘,但也将它们置于层次结构中。这意味着您可以请求图像中检测到的对象的外边界。如果您只检查边缘,这种事情将(直接)不可能。
As can be read in the documentation, detecting contours is mostly used for object recognition, whereas the canny edge detector is a more "global" operation. I wouldn't be surprised if the contour algorithm uses some sort of canny edge detection.
从文档中可以看出,检测轮廓主要用于对象识别,而精明的边缘检测器是一种更“全局”的操作。如果轮廓算法使用某种精明的边缘检测,我不会感到惊讶。
回答by LovaBill
The notion of contours is used as a tool to work on edge data. Not all edges are the same. But in many cases, e.g. objects with unimodal color distribution (i.e. one color), edges are the actual contours (outline,shape).
轮廓的概念被用作处理边缘数据的工具。并非所有边都相同。但在许多情况下,例如具有单峰颜色分布(即一种颜色)的对象,边缘是实际的轮廓(轮廓、形状)。
- Detect not only curves, but anything connected on the edge map. (connected component analysis)[1]
- Useful for objects with unimodal color distribution (a foreground mask is easily found with a simple threshold). Your sample image is not suitable.
- 不仅检测曲线,还检测边缘图上连接的任何东西。(连通分量分析)[1]
- 对于具有单峰颜色分布的对象很有用(使用简单的阈值很容易找到前景蒙版)。您的示例图像不合适。
[1]Topological Structural Analysis of Digitized Binary Images by Border Following by Satoshi Suzuki, 1985.
[1]Satoshi Suzuki,1985 年通过边界跟踪对数字化二进制图像进行拓扑结构分析。