图像边缘检测是计算机视觉和图像处理中的基本任务,用于提取图像中的显著特征。在本文中,我们将介绍和分析四种常用的边缘检测算法:Sobel、Canny、SUSAN和Harris。
1. Sobel 边缘检测
简介: Sobel算子图像边缘检测最重要的算子之一,在机器学习,数字媒体,计算机视觉等领域起着重要作用。Sobel边缘检测是一种基于梯度的边缘检测方法,通过计算图像在x方向和y方向的梯度来检测边缘。它使用两个3x3卷积核分别计算水平和垂直方向的梯度,然后合并这两个梯度以得到边缘强度。
优点:
-
简单且计算效率高。
-
对噪声有一定的抑制效果,适合处理一些简单的边缘检测任务。
-
可以检测图像中的水平和垂直边缘。
缺点:
-
对噪声敏感,特别是图像中的高频噪声。
-
无法检测到细小的边缘和角点。
-
在检测对比度较低的边缘时效果较差。
应用场景: 适用于需要快速处理的简单边缘检测任务,例如初步图像处理和特征提取。
2. Canny 边缘检测
简介: Canny边缘检测是一种多阶段边缘检测算法,包括噪声过滤、梯度计算、非极大值抑制和双阈值检测。它旨在找到图像中的强边缘并去除弱边缘。Canny算法使用4个mask检测水平、垂直以及对角线方向的边缘。原始图像与每个mask所作的卷积都存储起来。对于每个点我们都标识在这个点上的最大值以及生成的边缘的方向,这样我们就从原始图像生成了每个点亮度梯度图以及亮度梯度的方向。
比如下图就是检测道路车辆并把阈值设置为[30,100]的检测结果:
优点:
-
边缘检测精度高,能够检测到图像中的细小边缘。
-
具有良好的噪声抑制效果。
-
可以调节高低阈值以控制边缘检测的敏感度。
缺点:
-
计算复杂度较高,处理速度较慢。
-
参数选择(高低阈值)对检测结果影响较大,需要根据具体应用进行调整。
应用场景: 适用于需要高精度边缘检测的场景,如医学图像分析、物体识别和轮廓检测等。
3. SUSAN 边缘检测
简介: SUSAN(Smallest Univalue Segment Assimilating Nucleus)是一种基于局部相似性的边缘检测方法。它通过比较像素与其邻域内其他像素的相似性来检测边缘和角点。SUSAN算子是一种基于灰度的特征点获取方法,适用于图像中边缘和角点的检测,可以去除图像中的噪声,它具有简单、有效、抗噪声能力强、计算速度快的特点。
SUSAN算子的模版与常规卷积算法的正方形模版不同,它采用一种近似圆形的模版,用圆形模版在图像上移动,模版内部每个图像像素点的灰度值都和模版中心像素的灰度值作比较,若模版内某个像素的灰度与模版中心像素(核)的灰度的差值小于一定值,则认为该点与核具有相同(或相近)的灰度,如下图所示。由满足这一条件的像素组成的区域称为吸收核同值区。
优点:
-
对噪声不敏感,具有较好的鲁棒性。
-
可以同时检测边缘和角点。
-
不需要计算图像的梯度。
缺点:
-
计算复杂度较高,处理速度较慢。
-
对参数的依赖较大,需要调节相似性阈值以获得最佳效果。
应用场景: 适用于需要鲁棒性高且对噪声不敏感的边缘和角点检测任务,如环境较为复杂的图像分析。
4. Harris 角点检测
简介: Harris角点检测是一种基于梯度的角点检测算法,通过计算图像在x方向和y方向的梯度矩阵来检测角点。它常用于检测图像中的角点,但也可以用于边缘检测。Harris算子是Harris和Stephens在1998年提出的一种基于信号的点特征提取算子。其基本思想是:在图像中设计一个局部检测窗口,当该窗口沿各个方向做微小移动时,考虑窗口的灰度变化,若在所有方向的移动,都会产生较大的灰度变化,则该点为角点。
添加图片注释,不超过 140 字(可选)
下面是Harris检测椅子角点的结果:
优点:
-
对图像的旋转和光照变化具有一定的鲁棒性。
-
计算效率较高,适合实时应用。
-
可以检测到图像中的角点和边缘。
缺点:
-
对噪声较为敏感,需要预处理以去除噪声。
-
需要设定阈值来区分角点和非角点,参数选择较为敏感。
应用场景: 适用于需要检测角点的场景,如图像配准、3D重建和运动检测等。-
算法对比
我们使用python编程来直观对比这几种算法,具体代码如下:
import cv2
import numpy as np
from matplotlib import pyplot as plt
# Load the image
image = cv2.imread(r"C:\Users\Feng\Desktop\R-C.jpg", cv2.IMREAD_GRAYSCALE)
# Sobel Edge Detection
def sobel_edge_detection(image):
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
sobel_combined = cv2.magnitude(sobel_x, sobel_y)
return sobel_combined
# Canny Edge Detection
def canny_edge_detection(image):
blurred_image = cv2.GaussianBlur(image, (5, 5), 1.4)
canny_edges = cv2.Canny(blurred_image, 100, 200)
return canny_edges
# SUSAN Edge Detection
def susan_edge_detection(image, t=27):
# Create an output image to store the edge points
edge_image = np.zeros_like(image)
# Define the USAN circular mask
mask = np.array([
[0, 0, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 1, 1, 1, 0, 0],
])
mask_size = mask.shape[0]
offset = mask_size // 2
for i in range(offset, image.shape[0] - offset):
for j in range(offset, image.shape[1] - offset):
region = image[i-offset:i+offset+1, j-offset:j+offset+1]
center_value = image[i, j]
n_usan = np.sum(mask * (np.abs(region - center_value) <= t))
if n_usan < 0.5 * np.sum(mask):
edge_image[i, j] = 255
return edge_image
# Harris Corner Detection
def harris_corner_detection(image):
dst = cv2.cornerHarris(image, 2, 3, 0.04)
dst = cv2.dilate(dst, None)
image[dst > 0.01 * dst.max()] = 255
return image
# Apply the edge detection methods
sobel_edges = sobel_edge_detection(image)
canny_edges = canny_edge_detection(image)
susan_edges = susan_edge_detection(image)
harris_corners = harris_corner_detection(image)
# Plot the results
plt.figure(figsize=(20, 10))
plt.subplot(1, 4, 1)
plt.title('Sobel Edge Detection')
plt.imshow(sobel_edges, cmap='gray')
plt.subplot(1, 4, 2)
plt.title('Canny Edge Detection')
plt.imshow(canny_edges, cmap='gray')
plt.subplot(1, 4, 3)
plt.title('SUSAN Edge Detection')
plt.imshow(susan_edges, cmap='gray')
plt.subplot(1, 4, 4)
plt.title('Harris Corner Detection')
plt.imshow(harris_corners, cmap='gray')
plt.show()
其中,SUSAN算子opencv并没有提供可直接使用的函数,所有我们这里用一个近似为圆形的核来取自定义了SUSAN算子,检测结果如下:
可以看到,每种边缘检测算法都有其优点和缺点,适用于不同的应用场景。Sobel算法简单高效,但对噪声敏感;Canny算法检测精度高,但计算复杂度较高;SUSAN算法对噪声不敏感,但计算较慢;Harris算法适合检测角点,但对噪声较为敏感。根据具体的应用需求选择合适的算法,可以达到最佳的边缘检测效果。
希望这篇博客能帮助你更好地理解和选择合适的边缘检测算法。如果你有任何问题或建议,欢迎留言讨论!