OPENCV(python)--初学之路(九)
一前言
今天的状态比前几天好很多,快痊愈了,应该能稳定更新了,但是这个系列还能更多少就不一定了。
二主要内容--canny边缘检测
Canny 边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 在 1986 年提出。
这是一个多阶段算法,我们将介绍算法的每一个步骤。
1降噪
由于边缘检测易受图像中的噪声影响,因此第一步是使用 5x5 高斯滤波器去除图像中的噪声。我们在前面的章节中已经介绍到了这一点。
2寻找图像的强度梯度
然后在水平和垂直方向上用 Sobel 内核对平滑后的图像进行滤波,以获得水平方向(
)和垂直方向(
)的一阶导数。从这两个图像中,我们可以找到每个像素的边缘梯度和方向,如下所示:
渐变方向始终垂直于边缘。它被四舍五入到表示垂直,水平和两个对角线方向的四个角度中的一个。
3非最大抑制
在获得梯度幅度和方向之后,完成图像的全扫描以去除可能不构成边缘的任何不需要的像素。为此,在每个像素处,检查像素是否是其在梯度方向上的邻域中的局部最大值。检查下图:

A 点位于边缘(垂直方向)。渐变方向与边缘垂直。 B 点和 C 点处于梯度方向。因此,用点 B 和 C 检查点 A,看它是否形成局部最大值。如果是这样,则考虑下一阶段,否则,它被抑制(归零)。
总而言之,用这个函数的作用是描边,将图像的边缘勾勒出来。
4滞后阈值
这个阶段决定哪些边缘都是边缘,哪些边缘不是边缘。为此,我们需要两个阈值,minVal 和 maxVal。强度梯度大于 maxVal 的任何边缘肯定是边缘,而 minVal 以下的边缘肯定是非边缘,因此被丢弃。位于这两个阈值之间的人是基于其连通性的分类边缘或非边缘。如果它们连接到“可靠边缘”像素,则它们被视为边缘的一部分。否则,他们也被丢弃。见下图:

边缘 A 高于 maxVal,因此被视为“确定边缘”。虽然边 C 低于 maxVal,但它连接到边 A,因此也被视为有效边,我们得到完整的曲线。但是边缘 B 虽然高于 minVal 并且与边缘 C 的区域相同,但它没有连接到任何“可靠边缘”,因此被丢弃。因此,我们必须相应地选择 minVal 和 maxVal 才能获得正确的结果
5实际应用
OpenCV 将以上所有内容放在单个函数中, cv.Canny()
edges = cv.Canny(image, threshold1, threshold2,
apertureSize=3, L2gradient=False)
参数说明
-
image: 输入图像(单通道灰度图)
-
threshold1: 第一个阈值(低阈值)
-
threshold2: 第二个阈值(高阈值)
-
apertureSize: Sobel 算子的孔径大小(默认 3)
-
L2gradient: 梯度计算方式
-
False: 使用 L1 范数(默认) -
True: 使用 L2 范数(更精确)
-
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 读取灰度图像
img = cv.imread('D:\python_code\pic\myself.webp', 0)
# 应用Canny边缘检测
edges = cv.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()
大家都动手试一试,这是我一直主张的。
效果如下

三最后一语
本来想写多一点但是后面的内容不太好写,所以今天先这样吧,都好好理解一下。
我夜坐听风,昼眠听雨,悟得月如何缺,天如何老--戴望舒
感谢观看,共勉!!
更多推荐



所有评论(0)