canny算子的详细步骤并写出对应的python程序
时间: 2024-06-09 12:09:00 浏览: 7
Canny算子是一种常用的边缘检测算法,其步骤如下:
1. 对图像进行高斯平滑滤波,以减少噪声对后续计算的影响。
2. 计算图像每个像素点的梯度值及其方向。通常使用Sobel算子计算梯度。
3. 对梯度幅值进行非极大值抑制,即在梯度方向上,只保留局部极大值点,其它点抑制。
4. 应用双阈值算法进行边缘二值化。将所有高于高阈值的边缘点视为真正的边缘点,将低于低阈值的点视为非边缘点,其余部分在高低阈值之间的点,需要进一步判断是否与真正的边缘点相连,如果相连,则认为是边缘点。
下面是对应的Python程序:
```python
import cv2
import numpy as np
# 读取图像
img = cv2.imread('test.jpg', 0)
# 高斯平滑滤波
img_blur = cv2.GaussianBlur(img, (3, 3), 0)
# 计算梯度
sobelx = cv2.Sobel(img_blur, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img_blur, cv2.CV_64F, 0, 1, ksize=3)
gradient = np.sqrt(sobelx ** 2 + sobely ** 2)
gradient = cv2.normalize(gradient, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
# 非极大值抑制
gradient_angle = np.arctan2(sobely, sobelx) * 180 / np.pi
gradient_angle[gradient_angle < 0] += 180
nms = np.zeros(img.shape, dtype=np.uint8)
for i in range(1, img.shape[0] - 1):
for j in range(1, img.shape[1] - 1):
if (0 <= gradient_angle[i, j] < 22.5) or (157.5 <= gradient_angle[i, j] <= 180):
if (gradient[i, j] >= gradient[i, j + 1]) and (gradient[i, j] >= gradient[i, j - 1]):
nms[i, j] = gradient[i, j]
elif (22.5 <= gradient_angle[i, j] < 67.5):
if (gradient[i, j] >= gradient[i + 1, j + 1]) and (gradient[i, j] >= gradient[i - 1, j - 1]):
nms[i, j] = gradient[i, j]
elif (67.5 <= gradient_angle[i, j] < 112.5):
if (gradient[i, j] >= gradient[i + 1, j]) and (gradient[i, j] >= gradient[i - 1, j]):
nms[i, j] = gradient[i, j]
elif (112.5 <= gradient_angle[i, j] < 157.5):
if (gradient[i, j] >= gradient[i + 1, j - 1]) and (gradient[i, j] >= gradient[i - 1, j + 1]):
nms[i, j] = gradient[i, j]
# 双阈值算法
high_threshold, _ = cv2.threshold(nms, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
low_threshold = 0.4 * high_threshold
edge = np.zeros(img.shape, dtype=np.uint8)
weak_pixel = 75
strong_pixel = 255
strong_i, strong_j = np.where(nms >= high_threshold)
weak_i, weak_j = np.where((nms <= high_threshold) & (nms >= low_threshold))
edge[strong_i, strong_j] = strong_pixel
edge[weak_i, weak_j] = weak_pixel
# 连通分量
_, labels = cv2.connectedComponents(edge)
# 判断是否与真正的边缘点相连
for i in range(1, img.shape[0] - 1):
for j in range(1, img.shape[1] - 1):
if edge[i, j] == weak_pixel:
if (labels[i + 1, j] == 1) or (labels[i - 1, j] == 1) or \
(labels[i, j + 1] == 1) or (labels[i, j - 1] == 1) or \
(labels[i + 1, j + 1] == 1) or (labels[i - 1, j - 1] == 1) or \
(labels[i + 1, j - 1] == 1) or (labels[i - 1, j + 1] == 1):
edge[i, j] = strong_pixel
else:
edge[i, j] = 0
# 显示结果
cv2.imshow('Canny Edge Detection', edge)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
注意:以上程序只是Canny算子的基本实现,实际应用时需要根据具体场景进行调整和优化。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)