目标:
1.Canny算法
2.OpenCV函数:Canny()
一、Canny算法
Canny算法是一种边缘检测算法,步骤如下:
Canny边缘检查算法步骤:
1.彩色图转化为灰度图
2.应用高斯滤波来平滑图像-->去除噪声
由于边缘检测容易受到图像中噪声的影响
3.找寻图像的强度梯度
Canny的基本思想是找寻一幅图像中强度变化最强的位置。所谓的变化最强,即指梯度方向。
平滑后的图像中每个像素点的梯度可以由Sobel算子来获得:
1)首先,利用Sobel算子得到沿x轴和y轴方向的梯度G_x和G_y。
2)由G_X和G_Y便可计算每一个像素点的梯度幅值G。
3)接着,每一个像素点用G代替。对于变化剧烈的边界处,G值越大,对应的颜色为白色。
4)然后,这些边界通常非常粗,难以标定边界的真正位置,还必须存储梯度的方向θ。
4.应用非极大抑制技术来消除边误检(本来不是边缘但检测出来是)
沿着梯度θ方向上比较该像素点,若该像素点与两侧相比最大则保留,否则抑制(置为0)。
这一步的目的是将模糊的边界变得清晰,剔除一大部分不是边缘的点。
5.双阈值边缘连接处理
规则:设定两个阈值,minVal和maxVal。
大于maxVal的边缘肯定是边缘(保留),低于minVal的边缘是非边缘(舍去)。
对于介于两者之间的值,判断是否与真正的边界(强边界)相连,相连就保留,否则丢弃。
6.二值化图像输出结果
非极大值抑制
非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0。
将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制(置为0)。
双阈值边缘连接处理
这个阶段决定哪些边缘是边缘,哪些边缘不是边缘。为此,我们需要两个阈值,minVal和maxVal。强度梯度大于maxVal的边缘肯定是边缘,而minVal以下的边缘肯定是非边缘的,因此被丢弃。对于介于两者之间的值要判断是否与真正的边界相连,相连就保留,不相连舍弃。
二、OpenCV函数:Canny()
函数:
Canny(image, threshold1, threshold2)
参数
threshold1: 双阈值边缘连接中的minVal
threshold2: 双阈值边缘连接中的maxVal
示例1
import cv2
# 1.转化为灰度图
img = cv2.imread("image/1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2.高斯模糊
gaussian = cv2.GaussianBlur(gray, (5, 5), 6)
# 3.Canny边缘提取
canny = cv2.Canny(gaussian, 50, 150)
cv2.imshow("img", img)
cv2.imshow("gaussian", gaussian)
cv2.imshow("canny", canny)
cv2.waitKey(0)
cv2.destroyWindow()
示例2:ct图
import cv2
import matplotlib.pyplot as plt
# 1.将图片转化为灰度图
img = cv2.imread("image/25.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对于对比度较暗的图片,可进行高亮处理
abs = cv2.convertScaleAbs(gray, alpha=6, beta=0)
# 形态学操作(去除中间的黑色噪点)
kerner = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
close = cv2.morphologyEx(abs, cv2.MORPH_CLOSE, kerner)
# 2.高斯平滑
gaussian = cv2.GaussianBlur(close, (5, 5), 3)
# 3.Canny算法
canny = cv2.Canny(gaussian, 100, 150)
# 结合matplotlib展示多张图片
imags = [img, gray, abs, close, gaussian, canny]
titles = ["Input Image", "Gray", "ABS", "Close", "Gaussian", "Canny"]
plt.figure(figsize=(10, 10))
for i in range(6):
plt.subplot(2, 3, i+1)
plt.imshow(imags[i], cmap="gray")
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()