轮廓检测算法原理及实践
发布时间: 2024-05-01 16:45:24 阅读量: 71 订阅数: 54
![轮廓检测算法原理及实践](https://hejueyun.github.io/posts/f9b0a435/principle.png)
# 2.1 Canny边缘检测算法
### 2.1.1 算法原理
Canny边缘检测算法是一种多阶段的边缘检测算法,它通过以下步骤检测图像中的边缘:
1. **降噪:**使用高斯滤波器对图像进行平滑,去除噪声。
2. **梯度计算:**使用Sobel算子计算图像中每个像素的梯度幅值和方向。
3. **非极大值抑制:**沿着每个像素的梯度方向,只保留梯度幅值最大的像素。
4. **双阈值化:**使用两个阈值(高阈值和低阈值)对梯度幅值进行阈值化。高阈值用于确定强边缘,低阈值用于确定弱边缘。
5. **滞后阈值化:**使用滞后阈值化技术连接弱边缘和强边缘,形成完整的边缘。
### 2.1.2 算法实现
```python
import cv2
def canny_edge_detection(image):
# 降噪
image = cv2.GaussianBlur(image, (5, 5), 0)
# 梯度计算
sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=5)
gradient_magnitude = cv2.magnitude(sobelx, sobely)
# 非极大值抑制
gradient_magnitude = cv2.dilate(gradient_magnitude, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)))
gradient_magnitude = cv2.erode(gradient_magnitude, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)))
# 双阈值化
edges = cv2.Canny(image, 100, 200)
return edges
```
# 2. 轮廓检测算法实践
### 2.1 Canny边缘检测算法
#### 2.1.1 算法原理
Canny边缘检测算法是一种多阶段边缘检测算法,它通过以下步骤检测图像中的边缘:
1. **高斯滤波:**使用高斯滤波器平滑图像,以去除噪声。
2. **计算梯度:**使用 Sobel 算子计算图像中每个像素的梯度幅度和方向。
3. **非极大值抑制:**沿着梯度方向,只保留梯度幅度最大的像素,抑制其他像素。
4. **双阈值化:**使用两个阈值(高阈值和低阈值)对梯度幅度进行阈值化。高阈值用于确定强边缘,低阈值用于确定弱边缘。
5. **滞后阈值化:**将弱边缘与强边缘连接起来,形成完整的边缘。
#### 2.1.2 算法实现
```python
import cv2
import numpy as np
def canny_edge_detection(image, sigma=1.4, low_threshold=0.05, high_threshold=0.1):
"""
Canny边缘检测算法
参数:
image: 输入图像
sigma: 高斯滤波器标准差
low_threshold: 低阈值
high_threshold: 高阈值
返回:
边缘检测后的图像
"""
# 高斯滤波
blurred_image = cv2.GaussianBlur(image, (5, 5), sigma)
# 计算梯度
sobelx = cv2.Sobel(blurred_image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(blurred_image, cv2.CV_64F, 0, 1, ksize=3)
gradient_magnitude = np.sqrt(sobelx ** 2 + sobely ** 2)
gradient_direction = np.arctan2(sobely, sobelx)
# 非极大值抑制
non_max_suppressed_image = np.zeros_like(gradient_magnitude)
for i in range(1, gradient_magnitude.shape[0] - 1):
for j in range(1, gradient_magnitude.shape[1] - 1):
if gradient_magnitude[i, j] == np.max([gradient_magnitude[i - 1, j], gradient_magnitude[i + 1, j],
gradient_magnitude[i, j - 1], gradient_magnitude[i, j + 1]]):
non_max_suppressed_image[i, j] = gradient_magnitude[i, j]
# 双阈值化
thresholded_image = np.zeros_like(non_max_suppressed_image)
thresholded_image[non_max_suppressed_image > high_threshold] = 255
thresholded_image[np.logical_and(non_max_suppressed_image > low_threshold, non_max_suppressed_image < high_threshold)
```
0
0