python边缘提取_OpenCV-Python学习(十四):Canny边缘提取算法

目标:

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()

你可能感兴趣的:(python边缘提取)