声明
声明:本系列博客是我在学习OpenCV官方教程中文版(For Python)(段力辉 译)所做的笔记。所以,其中的绝大部分内容引自这本书,博客中的代码也是其配套所附带的代码或书中的代码,侵删。其中部分代码可能会因需要而改动。在本系列博客中,其中包含书中的引用,也包括我自己对知识的理解,思考和总结。本系列博客的目的主要有两个,一个是可以作为我自己的学习笔记,时常复习巩固。第二个是可以为想学习python下的opencv 3 相关知识的朋友提供一些参考。
正文
1.Canny算法简介
Canny边缘检测算法是一个多阶段的算法,即由多个步骤构成。可大致分四步:
1. 图像降噪
第一步选择降噪的原因是:噪声就是灰度变化很大的地方,容易被识别为伪边缘。
2. 计算图像梯度
计算图像梯度,得到可能边缘,因为梯度是灰度变化明显的地方,而边缘也是灰度变化明显的地方。但这一步只能得到可能的边缘。这一步就有了所有可能是边缘的集合。
3. 非极大值抑制
在获得梯度的方向和大小之后,应该对整幅图像做一个扫描,去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的。如下图:
现在你得到的是一个包含“窄边界”的二值图像。
4. 双阈值筛选
要确定哪些边界才是真正的边界。我们需要设置两个阈值:minVal和maxVal,当图像的灰度梯度高于 maxVal 时被认为是真的边界,那些低于 minVal 的边界会被抛弃。如果介于两者之间的话,就要看这个点是否与某个被确定为真正的边界点相连,如果是就认为它也是边界点,如果不是就抛弃。如下图:
选择合适的 maxVal和 minVal 对于能否得到好的结果非常重要。
2.cv2.Canny()
在 OpenCV 中只需要一个函数:cv2.Canny(),就可以完成以上几步。
cv2.Canny(image,threshold1,threshold2[,edges[,apertureSize[,L2gradient]]])
参数解释:
- image:源图像
- threshold1:阈值1
- threshold2:阈值2
- apertureSize:可选参数,Sobel算子的大小,默认值为3.
- L2gradient:它可以用来设定求梯度大小的方程。如果设为 True,就会使用
E d g e _ G r a d i e n t ( G ) = G x 2 + G y 2 Edge\_Gradient(G)=\sqrt{G_x^2+G_y^2} Edge_Gradient(G)=Gx2+Gy2
否则使用方程:
E d g e _ G r a d i e n t ( G ) = ∣ G x 2 ∣ + ∣ G y 2 ∣ Edge\_Gradient(G)=|G_x^2|+|G_y^2| Edge_Gradient(G)=∣Gx2∣+∣Gy2∣
替代,默认值为 False。
3.完整代码及运行结果
import matplotlib
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('shaniu1.jpg',0)
edges = cv2.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()
运行结果:
感谢观看!
如有错误,欢迎批评指正!