使用Canny算子对图像进行边缘检测
时间: 2023-12-05 21:03:35 浏览: 33
好的,我来给你讲一下使用Canny算子进行图像边缘检测的步骤。
Canny算子是一种常用的边缘检测算法,其步骤如下:
1. 对图像进行灰度化处理,将彩色图像转换为灰度图像。
2. 对灰度图像进行高斯滤波,以平滑图像,去除噪声。
3. 计算图像中每个像素点的梯度值和方向,采用Sobel算子计算梯度值和方向。
4. 对梯度值进行非极大值抑制,即在梯度方向上,只保留局部极大值点,其余点置零。
5. 对非极大值抑制后的图像进行双阈值处理,即将图像中的像素点分为强边缘点、弱边缘点和非边缘点三类,采用两个阈值进行划分。
6. 对双阈值处理后的图像进行边缘连接处理,即将弱边缘点沿着强边缘点连接起来,形成完整的边缘。
最终,我们可以得到一张二值图像,其中白色表示检测到的边缘,黑色表示背景。
Python中实现Canny算子边缘检测的代码如下:
```python
import cv2
# 读取图像
img = cv2.imread('img.jpg')
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯滤波
blur = cv2.GaussianBlur(gray, (3, 3), 0)
# 计算梯度值和方向
sobelx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)
gradient = cv2.sqrt(sobelx**2 + sobely**2)
theta = cv2.atan2(sobely, sobelx)
# 非极大值抑制
rows, cols = gradient.shape
for i in range(1, rows - 1):
for j in range(1, cols - 1):
if (theta[i, j] >= -np.pi/8 and theta[i, j] < np.pi/8) or (theta[i, j] >= 7*np.pi/8 and theta[i, j] < np.pi) or (theta[i, j] >= -np.pi and theta[i, j] < -7*np.pi/8):
if (gradient[i, j] >= gradient[i, j-1]) and (gradient[i, j] >= gradient[i, j+1]):
pass
else:
gradient[i, j] = 0
elif (theta[i, j] >= np.pi/8 and theta[i, j] < 3*np.pi/8) or (theta[i, j] >= -7*np.pi/8 and theta[i, j] < -5*np.pi/8):
if (gradient[i, j] >= gradient[i-1, j-1]) and (gradient[i, j] >= gradient[i+1, j+1]):
pass
else:
gradient[i, j] = 0
elif (theta[i, j] >= 3*np.pi/8 and theta[i, j] < 5*np.pi/8) or (theta[i, j] >= -5*np.pi/8 and theta[i, j] < -3*np.pi/8):
if (gradient[i, j] >= gradient[i-1, j]) and (gradient[i, j] >= gradient[i+1, j]):
pass
else:
gradient[i, j] = 0
else:
if (gradient[i, j] >= gradient[i-1, j+1]) and (gradient[i, j] >= gradient[i+1, j-1]):
pass
else:
gradient[i, j] = 0
# 双阈值处理
high_threshold = np.max(gradient) * 0.3
low_threshold = high_threshold * 0.2
rows, cols = gradient.shape
for i in range(rows):
for j in range(cols):
if gradient[i, j] >= high_threshold:
gradient[i, j] = 255
elif gradient[i, j] >= low_threshold and gradient[i, j] < high_threshold:
gradient[i, j] = 50
else:
gradient[i, j] = 0
# 边缘连接处理
for i in range(1, rows - 1):
for j in range(1, cols - 1):
if gradient[i, j] == 50:
if (gradient[i-1, j-1] == 255) or (gradient[i-1, j] == 255) or (gradient[i-1, j+1] == 255) or \
(gradient[i, j-1] == 255) or (gradient[i, j+1] == 255) or (gradient[i+1, j-1] == 255) or \
(gradient[i+1, j] == 255) or (gradient[i+1, j+1] == 255):
gradient[i, j] = 255
else:
gradient[i, j] = 0
# 显示边缘检测结果
cv2.imshow('Canny Edge Detection', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
这样就可以通过Canny算子对图像进行边缘检测了。