【opencv学习】【Canny边缘检测】

今天学习下 Canny检测,具体的算法介绍在代码中展示。

import cv2
import numpy as np

# 边缘检测,边缘点的特征就是梯度大,一般非边缘点,梯度就偏小甚至是0
# Canny 边缘检测流程:
#   1:使用高斯滤波器平滑图像,去除噪声点
#   2:计算图像中的每个像素点的梯度和方向,这个方法可以使用Sobel算子X和Y方向得到
#   3:应用非极大值抑制(Non-Maximum-suppression),消除一些边缘检测的边缘影响,因为很可能临近的像素点都可能被认为是边缘点,这个时候就得去除一些不必要的干扰点,取最有可能的边缘像素点
#   4:应用双阈值法,确定真实地潜在的边界,去掉一些不必要的噪声点
#   5:再抑制掉孤立的边缘(认为是噪声或者不关键的边缘点)完成目的

# 拆解说明
# 1: 高斯滤波器,这个我们很熟悉了,使用下面的核进行卷积操作
# 比如:
# H = [[0.0924, 0.1192, 0.0924],
#   [0.1192, 0.1538, 0.1192],
#   [0.0924, 0.1192, 0.0924]]
# img = img * H

# 2:计算像素点的梯度和方向
# 这里使用Sobel算子
# Sx = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
# Sy = [[-1, -2, -1], [0, 0, 0], [1, 2, 1]]
# 分别和图像机进行卷积,得到水平梯度Gx,以及垂直梯度Gy
# Gx = img * Sx
# Gy = img * Sy
# 利用 Gx 和 Gy 计算总的梯度强度G 和方向 θ
# G = (Gx^2 + Gy^2)^0.5
# θ = arctan(Gy / Gx),这个是为了确定该中心像素点是和哪俩临近像素点进行比较

# 3:非极大值抑制
# 为了计算简单,一个像素点周围的有八个方向,角度分别是(0, 45,90, 135, 180, 225, 270, 315)
# θ和哪个角度范围最近,就归属于哪个角度,每个角度方向上都可以找到中心点临近的N个数值(梯度强度值),N取决于kernel size的大小
# 中心点的梯度强度值和 临近的N个点的梯度强度值做对比,如果中心点的梯度强度值最大,则保留该强度值,否则抑制掉,改成0。

# 4:双阈值法
# 设置一个梯度强度最大值 max, 和梯度强度最小值 min
# 对上面计算后的强度在进行过滤,
# 梯度强度值小于 min的,直接抑制掉,改为0.
# 梯度强度值大于 max的,直接保留。
# 梯度强度介于二者之间的,看看这个数值是否和其他边界相连接,有链接的话则保留,否则则抑制为0。

img = cv2.imread('images/saoge.jpg', cv2.IMREAD_GRAYSCALE)
print(img.shape)

can1 = cv2.Canny(img, threshold1=20, threshold2=100)
print(can1.shape)
can2 = cv2.Canny(img, threshold1=80, threshold2=160)
print(can2.shape)

ret = np.hstack((img, can1, can2))
cv2.imshow('Canny', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果如下:
请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_29367075/article/details/122908447