Canny函数进行边缘检测的原理
时间: 2024-06-10 08:06:09 浏览: 2
Canny边缘检测算法的原理是通过多次滤波和阈值化的方法,将图像中的边缘检测出来。算法主要由4个步骤组成:1.高斯滤波,2.计算梯度,3.非极大值抑制,4.双阈值处理。其中,高斯滤波的作用是去除图像中的噪声,梯度的计算用于检测图像中的边缘,非极大值抑制用于提取边缘上的极值点,最后将图像分为边缘、非边缘和可能为边缘的部分,以达到边缘检测的目的。
相关问题
根据anny算法的原理自定义一个my_canny函数来实现边缘检测
以下是一个基于anny算法实现的my_canny函数,用于边缘检测:
```python
import numpy as np
import cv2
def my_canny(image, low_threshold, high_threshold, aperture_size=3):
# 1. 首先进行灰度化处理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 2. 对图像进行高斯滤波
blurred = cv2.GaussianBlur(gray, (aperture_size, aperture_size), 0)
# 3. 计算图像边缘的梯度和方向
grad_x = cv2.Sobel(blurred, cv2.CV_16S, 1, 0)
grad_y = cv2.Sobel(blurred, cv2.CV_16S, 0, 1)
gradient = cv2.addWeighted(np.abs(grad_x), 0.5, np.abs(grad_y), 0.5, 0)
theta = np.arctan2(grad_y, grad_x)
theta = np.rad2deg(theta) % 180
# 4. 计算图像中的非极大值点
rows, cols = gradient.shape
non_max_sup = np.zeros((rows, cols), dtype=np.uint8)
for i in range(1, rows-1):
for j in range(1, cols-1):
if (0 <= theta[i,j] < 22.5) or (157.5 <= theta[i,j] <= 180):
if (gradient[i,j] >= gradient[i,j-1]) and (gradient[i,j] >= gradient[i,j+1]):
non_max_sup[i,j] = gradient[i,j]
elif (22.5 <= theta[i,j] < 67.5):
if (gradient[i,j] >= gradient[i-1,j-1]) and (gradient[i,j] >= gradient[i+1,j+1]):
non_max_sup[i,j] = gradient[i,j]
elif (67.5 <= theta[i,j] < 112.5):
if (gradient[i,j] >= gradient[i-1,j]) and (gradient[i,j] >= gradient[i+1,j]):
non_max_sup[i,j] = gradient[i,j]
else:
if (gradient[i,j] >= gradient[i-1,j+1]) and (gradient[i,j] >= gradient[i+1,j-1]):
non_max_sup[i,j] = gradient[i,j]
# 5. 使用双阈值算法进行边缘检测
thresholded = np.zeros((rows, cols), dtype=np.uint8)
strong_edges = (non_max_sup > high_threshold)
thresholded[strong_edges] = 255
weak_edges = (non_max_sup >= low_threshold) & (non_max_sup <= high_threshold)
thresholded[weak_edges] = 127
# 使用连通性分析来增强弱边缘
_, contours, hierarchy = cv2.findContours(thresholded, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
if cv2.contourArea(contour) < 100:
continue
contour = contour.reshape(-1, 2)
for x, y in contour:
if thresholded[y, x] == 127:
thresholded[y, x] = 255
# 6. 返回检测到的边缘图像
return thresholded
```
上述函数中,使用的参数和方法与anny算法中的一致:
- aperture_size表示高斯滤波的卷积核大小,一般设置为3;
- low_threshold和high_threshold表示双阈值算法的两个阈值;
- 在计算非极大值点时,根据梯度方向来判断当前像素是否为非极大值点;
- 在进行弱边缘的增强时,先使用cv2.findContours函数找到所有的轮廓,然后对每个轮廓进行面积大小的判断,只有面积大于一定值的轮廓才会被认为是真正的边缘。
cv2.Canny边缘检测实例
cv2.Canny是OpenCV中用于进行边缘检测的函数。它的原理是基于Canny算法,该算法是一种非常流行的边缘检测算法,其实现主要有以下几个步骤:
1. 高斯滤波:对图像进行高斯滤波,以平滑图像并去除噪声。
2. 计算梯度:使用Sobel等算子计算图像梯度,以检测出边缘。
3. 非极大值抑制:对梯度幅值图像进行非极大值抑制,以使边缘更加细化。
4. 双阈值处理:将梯度幅值图像分为两个阈值区间,并进行二值化处理,以获得最终的二值化图像。
5. 滞后阈值处理:对于二值化图像中的边缘像素,进一步检测其是否真正属于边缘,并去除一些误检出来的边缘。
下面是cv2.Canny的一段实例代码:
```
import cv2
import numpy as np
# 读取图像
img = cv2.imread('test.jpg', 0)
# 进行边缘检测
edges = cv2.Canny(img, 100, 200)
# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
这段代码中,首先使用cv2.imread函数读取了一张灰度图像。然后使用cv2.Canny函数进行边缘检测,其中第二个和第三个参数分别为两个阈值(即双阈值处理中的两个阈值),这里设置为100和200。最后使用cv2.imshow函数显示原图和边缘检测结果。
相关推荐
![pptx](https://img-home.csdnimg.cn/images/20210720083543.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![docx](https://img-home.csdnimg.cn/images/20210720083331.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_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)