1.概念及原理
(1)之前我们是对梯度大小进行阈值化以得到二值的边缘图像。但是这样做有两个缺点。其一是检测到的边缘过粗,难以实现物体的准确定位。其二是很难找到合适的阈值既能足够低于检测到所有重要边缘,又能不至于包含过多次要边缘,这就是Canny算法尝试解决的问题。
(2)Canny算子通常是基于Sobel算子,当然也可以使用其他梯度算子。其思想是使用一个低阈值一个高阈值来确定哪些点属于轮廓。低阈值的作用主要是包括所有属于明显图像轮廓的边缘像素。高阈值的作用是定义所有重要轮廓的边缘。Canny算子是组合低阈值和高阈值这两幅边缘图以生成最优的轮廓图。这种使用双阈值以得到二值图像的策略被称为磁滞阈值化。
2.实验
使用Canny算子检测轮廓
源码示例(很简单)
1. <pre name="code" class="cpp">#include<iostream>
2. #include <opencv2/core/core.hpp>
3. #include <opencv2/highgui/highgui.hpp>
4. #include<imgproc/imgproc.hpp>
5.
6. using namespace std;
7. using namespace cv;
8.
9. int main(){
10.
11. Mat image = imread("tree.jpg", 0);
12. namedWindow("image");
13. imshow("image", image);
14.
15. Mat contours;
16. Canny(image, //灰度图
17. contours, //输出轮廓
18. 125, //低阈值
19. 350); //高阈值
20.
21. //因为正常情况下轮廓是用非零像素表示 我们反转黑白值
22. Mat contoursInv; //反转后的图像
23. threshold(contours,
24. contoursInv,
25. 128, //低于该值的像素
26. 255, //将变成255
27. THRESH_BINARY_INV);
28. namedWindow("contoursInv");
29. imshow("contoursInv", contoursInv);
30.
31. waitKey(0);
32. return 0;
33. }
实验效果图