图像识别之边缘检测Laplacian算子
Laplacian算子是一种基于二阶导数的边缘检测算子,它可以通过计算图像像素在水平和垂直方向上的二阶导数之和来检测图像中的边缘。具体来说,Laplacian算子可以用下面的卷积核表示:
0 1 0
1 -4 1
0 1 0
在应用Laplacian算子之前,需要先将图像进行灰度化处理,然后对图像进行卷积操作。卷积的公式如下:
output(x, y) = sum(kernel(i, j) * input(x + i - 1, y + j - 1))
其中,input表示输入图像,output表示输出图像,kernel表示Laplacian算子的卷积核。
除了直接使用Laplacian算子进行卷积之外,还可以通过先对图像进行高斯滤波来抑制噪声,然后再应用Laplacian算子进行边缘检测。这种方法被称为LoG算法(Laplacian of Gaussian)。
下面是一个Python实现的Laplacian算子代码示例:
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg')
# 将图像转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 定义Laplacian算子的卷积核
kernel = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
# 应用Laplacian算子进行卷积
laplacian = cv2.filter2D(gray, -1, kernel)
# 显示原始图像和边缘检测结果
cv2.imshow('Original', img)
cv2.imshow('Laplacian Edge Detection', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
需要注意的是,由于Laplacian算子对噪声比较敏感,因此在实际应用中,通常需要对图像进行预处理来降低噪声的影响。
对于噪声比较敏感,可能会产生虚假的边缘。
在实际应用中,我们常常需要对图像进行预处理,以降低噪声对边缘检测的影响。常用的预处理方法包括高斯平滑和中值滤波等。
高斯平滑是一种基于高斯函数的滤波器,其主要思想是通过对像素点周围一定范围内的像素进行加权平均,来降低噪声的影响。高斯平滑可以用卷积运算实现,具体操作如下:
其中,III表示原始图像,IsmoothI_{smooth}Ismooth表示平滑后的图像。
代码实现如下(以OpenCV为例):
import cv2
import numpy as np
# 加载图像
img = cv2.imread('test.jpg')
# 定义卷积核大小和标准差
ksize = (5, 5)
sigma = 1.5
# 生成高斯卷积核
kernel = cv2.getGaussianKernel(ksize, sigma)
# 对图像进行卷积操作
img_smooth = cv2.filter2D(img, -1, kernel)
# 显示图像
cv2.imshow('Original', img)
cv2.imshow('Smooth', img_smooth)
cv2.waitKey(0)
cv2.destroyAllWindows()
中值滤波是一种基于像素邻域的滤波器,其主要思想是将像素点周围一定范围内的像素排序后取中值作为当前像素的值,以去除孤立的噪声点。中值滤波可以用滑动窗口实现,具体操作如下:
- 定义窗口大小,例如 3×33\times33×3,5×55\times55×5 等。窗口大小应该根据图像噪声的程度和分辨率来选择。
- 将窗口移动到图像上的每一个像素,以此作为窗口的中心点。
- 对窗口内的所有像素的灰度值进行排序。
- 取排序后中间的值作为当前像素的灰度值。
- 将所有像素都进行相同的操作,得到一个新的图像。
下面是中值滤波的Python代码实现:
import numpy as np
import cv2
# 定义中值滤波函数
def median_filter(img, kernel_size):
# 获取图像宽、高
height, width = img.shape[:2]
# 复制原始图像,以便不改变原始图像
new_img = img.copy()
# 计算滤波器半径
radius = kernel_size // 2
# 对每一个像素进行滤波
for i in range(radius, height - radius):
for j in range(radius, width - radius):
# 获取窗口内的像素
window = img[i - radius:i + radius + 1, j - radius:j + radius + 1]
# 对窗口内的像素进行排序,并取中间值
new_img[i, j] = np.median(window)
return new_img
# 读取图像
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
# 中值滤波处理
median_img = median_filter(img, 3)
# 显示图像
cv2.imshow("Original Image", img)
cv2.imshow("Median Filtered Image", median_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
上述代码中,median_filter 函数用于实现中值滤波,接受两个参数:待处理的图像和滤波器大小。函数使用 numpy 库中的 median 函数计算窗口内像素的中值,并将其赋给中心像素。函数返回处理后的图像。最后,我们读取一张灰度图像,使用 median_filter 函数进行中值滤波处理,然后显示原始图像和处理后的图像。
运算速度比较慢,需要使用高斯平滑等预处理操作来降低噪声和运算量
因为Laplacian算子对于噪声比较敏感,噪声会导致算法检测出虚假的边缘。而高斯平滑可以减少噪声的影响,同时也可以对图像进行平滑处理,以便更好地检测边缘。
具体来说,可以使用高斯平滑算法对图像进行预处理,然后再使用Laplacian算子进行边缘检测。高斯平滑算法的公式如下:
其中,xxx和yyy表示像素在图像中的位置,σ\sigmaσ是高斯分布的标准差。该公式表示了一个二维高斯分布,用于对图像进行平滑处理。可以在代码中使用该公式生成高斯滤波器,对图像进行卷积操作以达到平滑处理的效果。
代码示例如下(使用Python和OpenCV库):
import cv2
import numpy as np
# 读取图像
img = cv2.imread('image.jpg', 0)
# 高斯滤波器
kernel = cv2.getGaussianKernel(5, 0)
kernel = kernel * kernel.T
# 高斯平滑处理
img_smooth = cv2.filter2D(img, -1, kernel)
# Laplacian算子
laplacian = cv2.Laplacian(img_smooth, cv2.CV_64F)
# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Smoothed', img_smooth)
cv2.imshow('Laplacian', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
在这个示例代码中,我们首先使用cv2.imread()函数读取一张灰度图像。然后使用cv2.getGaussianKernel()函数生成一个大小为5x5的高斯滤波器,再对图像进行卷积操作,得到平滑处理后的图像。接着,使用cv2.Laplacian()函数对平滑后的图像进行Laplacian边缘检测,得到边缘图像。最后使用cv2.imshow()函数显示原图、平滑处理后的图像和边缘检测后的图像。
转载自:https://juejin.cn/post/7225921312212582456