Canny边缘检测
Canny检测优点。
1低错误率。检测出的边缘尽可能是真实的边缘。
2 边缘点应被很好的定位。由检测器标记为边缘的点应该和真实边缘的中心之间距离最小
3 单一边缘点响应,检测器不应该指出多个边缘像素。
原理 1, f(x,y)输入图像 和f卷积得到平滑后的图像。
2,计算图像的梯度幅度和方向。
3,细化梯度极大值的边缘,采用非最大抑制。将边缘定义成四个方向水平,垂直,+45度,-45度。
非最大抑制方案:
d1,d2,d3,d4。为3*3区域的四个基本边缘方向。寻找最接近梯度方向 ,的方向dk
如果M(x,y)的值小于沿dk的两个邻居之一,则抑制。否则g(x,y)=m(x,y).
最后采用双阈值处理,高阈值和低阈值比例应该为2:1,或者3:1.
#include<opencv2/opencv.hpp>#include<opencv2/imgPRoc.hpp>#include<opencv2/highgui.hpp>#include<vector>using namespace cv;using namespace std;int main() { Mat src, gray,dst; src = imread("1333.png"); //imshow("原图", src); cvtColor(src, gray, CV_BGR2GRAY); imshow("灰度图", gray); Mat canny; int threshold = 100; Canny(gray, canny, threshold, threshold * 3, 3);//高低阈值选取,sobel核大小 imshow("边缘检测", canny); ///Prewitt算子 Mat pgx; Mat PrewittGx = (Mat_<float>(3, 3)<< -1, -1, -1, 0, 0, 0, 1, 1, 1); filter2D(gray, pgx, gray.depth(), PrewittGx); imshow("Prewitt算子Gx", pgx); Mat pgy; Mat PrewittGy = (Mat_<float>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1); filter2D(gray, pgy, gray.depth(), PrewittGy); //imshow("Prewitt算子Gy", pgy); ///Roberts算子 Mat Roberts1,Roberts2; Mat R1 = (Mat_<float>(2, 2) << -1, 0, 0, 1); filter2D(gray, Roberts1, gray.depth(), R1); imshow("Roberts算子", Roberts1); ///Sobel算子 Mat Sobel; Mat S = (Mat_<float>(3, 3) << -1, -2, -1, 0, 0, 0, 1, 2, 1) ; filter2D(gray.clone(), Sobel, src.depth(), S); imshow("Sobel算子", Sobel); ///高斯拉普拉斯 Mat GL; Mat G = (Mat_<float>(5, 5) << 0, 0, -1, 0, 0, 0, -1, -2, -1, 0, -1, -2, 16, -2, -1, 0, -1, -2, -1, 0, 0, 0, -1, 0, 0); filter2D(gray.clone(), GL, src.depth(), G); imshow("高斯拉普拉斯", GL); waitKey(0);}参考http://www.open-open.com/lib/view/open1453460512558.html
《数字图像处理》冈萨雷斯
新闻热点
疑难解答