边缘检测
什么是边缘:
* 图像中像素值发生剧烈变化的位置(高频信息区域)
* 这些区域往往都是图像的边缘
方法:滤波、形态学处理等
边缘的作用
本质上,边缘是不同区域之间的边界。
其中包含了图像的区域信息,形状信息
一方面,可以利用这些信息来作为特征对图像进行理解(甚至深度学习中也有应用)
另一方面,事先提取出这些信息加以保存,以避免在一些操作中将边缘信息抹除
成熟的边缘检测算法--canny
canny算法是目前为止接触的最复杂的算法之一。
他具有很多的前后处理优化细节,可以得到更好的边缘检测结果。
总的来说,他的基本原理是:在图像中寻找局部最大梯度,将非最大值梯度抑制和双阈值处理结合,产生好的边缘检测结果。
提出动机
canny算法之前,边缘提取方法长期受困于噪声影响。
噪声,会使得图像中的像素值产生随机变化,从而使得边缘检测的结果出现错误或者不准确。
而canny采用以下方法来抑制噪声
1. 引入高斯滤波器,来平滑噪声
2. 采用非最大值抑制来抑制边缘响应,对于边缘宽度的变化更加敏感
3. 采用两段阈值方法处理,从噪声中分离边缘
具体步骤
- 高斯滤波
- 计算梯度幅值和方向
- 非最大值抑制

- 双阈值处理
设定一个上限和下限
如果nsm中的内容小于下限,则值为零,目的在去除噪声
如果nms中的内容大于上限,则值为255, 目的在于强化边缘
如果一个像素值处于上下限之间,但如果周围
- 边缘连接
edges = cv2.Canny(img, 50, 100)
连通区域分析
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('E:/notebook/car.jpg')[670:-570, 370:-370, :]
img = cv2.resize(img, (512, int(512 * img.shape[0] / img.shape[1])))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(img)
plt.show()
# 提取边缘
edges = cv2.Canny(img, 50, 100)
plt.imshow(edges, cmap='gray')
plt.show()
# 从图像左上角开始扫描,对每个像素:
# - 如果为前景像素,则会从同一行的前面,或上一行的后面选择标号最小的进行标记
# - 如果没有找到已标记的连通区域,则会单独标记
output = cv2.connectedComponents(edges, 4) # 4连通:上下左右检测,8连通:上下左右,斜上下左右
#print("连通区域数量:", output[0])#19
#print("连通区域的标签形状:", output[1].shape, "最大标签:", output[1].max())# (170, 512), 18
mask = np