“边缘检测”和“图像轮廓”之间的区别
请看下面的代码
#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"