opencv(5): 滤波器
滤波的作用:一幅图像通过滤波器得到另一幅图像;其中滤波器又称为卷积核,滤波的过程称为卷积。
锐化:边缘变清晰
低通滤波(Low-pass Filtering):
目标:去除图像中的高频成分,保留低频成分。
效果:平滑图像、去除噪声。
应用:图像平滑、模糊、去噪等。
常见滤波器:均值滤波、高斯滤波等。
高通滤波(High-pass Filtering):
目标:去除图像中的低频成分,保留高频成分。
效果:突出图像的边缘、细节。
应用:图像锐化、边缘检测等。
常见滤波器:拉普拉斯滤波、Sobel 滤波等。
在频域中,图像的低频成分对应于图像中变化缓慢的区域,而高频成分对应于图像中变化较快的区域。因此,低通滤波器通过减小图像中相邻像素之间的差异来平滑图像,而高通滤波器则通过强调相邻像素之间的差异来突出图像的边缘和细节。
低通滤波
主要是用来去噪。
均值滤波 cv2.blur
均值滤波是一种基本的图像处理技术,它通过取周围像素的平均值来模糊图像,从而减少图像中的噪声。这种滤波方法对于平滑图像、去除噪声或模糊图像中的细节很有用。
高斯滤波 cv2.GaussianBlur
高斯滤波是一种常用的图像处理技术,它通过在图像上应用高斯函数来进行平滑处理,从而降低图像的噪声并模糊图像。
cv2.GaussianBlur 函数接受三个参数:待处理的图像、高斯核的大小和标准差。高斯核的大小决定了平滑的程度,标准差越大,模糊效果越明显。在这个例子中,使用了一个 (5, 5) 的高斯核,标准差为 0,表示使用默认的标准差。
# 定义高斯核的大小,例如 (5, 5),和标准差,例如 0
kernel_size = (5, 5)
sigma = 0
# 进行高斯滤波
blurred_img = cv2.GaussianBlur(img, kernel_size, sigma)
中值滤波 cv2.medianBlur
中值滤波是一种非线性滤波方法,它的原理是用窗口内的中值来代替中心像素的值,这样可以有效地去除图像中的椒盐噪声等离群值。
cv2.medianBlur 函数接受两个参数:待处理的图像和中值滤波的卷积核大小。卷积核大小必须是奇数,通常选择 3x3 或 5x5。
# 定义中值滤波的卷积核大小,必须是奇数
kernel_size = 5
# 进行中值滤波
blurred_img = cv2.medianBlur(img, kernel_size)
双边滤波 (对美颜效果好)
双边滤波是一种用于平滑图像的滤波技术,与传统的高斯滤波不同,它在平滑的同时保留了图像的边缘信息。这是通过同时考虑像素的颜色相似性和空间相似性来实现的。
cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])
- src: 输入图像(单通道或多通道图像)。
- d: 表示滤波器的直径,也就是每个像素邻域的直径。整数类型的值,通常取正整数。
- sigmaColor: 颜色空间的标准差,控制颜色相似性的权重。较大的值表示更广泛的颜色相似性。通常取正实数。
- sigmaSpace: 坐标空间的标准差,控制像素空间的权重。较大的值表示更广泛的空间相似性。通常取正实数。
- dst (可选): 输出图像,与输入图像大小和类型相同。
- borderType (可选): 边界模式,默认为 cv2.BORDER_DEFAULT。
返回值:如果提供了 dst 参数,则返回 dst,否则返回新创建的输出图像。
# 设置参数
d = 15 # 邻域直径
sigma_color = 75 # 颜色空间的标准差
sigma_space = 75 # 坐标空间的标准差
# 进行双边滤波
bilateral_filtered_img = cv2.bilateralFilter(img, d, sigma_color, sigma_space)
高通滤波
主要是为了检测边缘。
Sobel
Sobel 算子是图像处理中常用的边缘检测算子之一,用于寻找图像中灰度变化明显的地方,通常用于边缘检测和图像梯度计算。Sobel 算子对图像进行卷积操作,分别计算水平方向和垂直方向的梯度,然后通过这两个梯度的组合来找到图像中的边缘。
Sobel 算子的具体形式如下:
水平方向 Sobel 算子:
垂直方向 Sobel 算子:
算法步骤:
- 将图像与水平方向 Sobel 算子进行卷积,得到水平方向的梯度。
- 将图像与垂直方向 Sobel 算子进行卷积,得到垂直方向的梯度。
- 将水平和垂直梯度的幅值进行合并,得到边缘强度。
cv2.Sobel(src, ddepth, dx, dy, ksize[, dst[, scale[, delta[, borderType]]]])
参数说明:
- src: 输入图像,灰度图像(单通道)。
- ddepth: 输出图像的深度,通常使用 cv2.CV_64F。
- dx: x 方向的导数阶数。
- dy: y 方向的导数阶数。
- ksize: Sobel 算子的大小,可以为 1、3、5、7。
- dst (可选): 输出图像。
- scale (可选): 缩放导数的比例因子,默认为1。
- delta (可选): 添加到结果的值,默认为0。
- borderType (可选): 边界模式,默认为 cv2.BORDER_DEFAULT。
Sobel 算子的优点是简单易实现,对于一些基本的边缘检测任务效果较好。在 OpenCV 中,可以使用 cv2.Sobel 函数来应用 Sobel 算子。例如:
import cv2
import numpy as np
# 读取图像
image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)
# 水平方向 Sobel 算子
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
# 垂直方向 Sobel 算子
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
# 计算梯度幅值
gradient_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)
# 显示结果
cv2.imshow('Original Image', image)
cv2.imshow('Sobel X', sobel_x)
cv2.imshow('Sobel Y', sobel_y)
cv2.imshow('Gradient Magnitude', gradient_magnitude)
cv2.waitKey(0)
cv2.destroyAllWindows()
拉普拉斯算子
拉普拉斯算子是一种用于图像处理的算子,用于检测图像中的边缘和细节。在离散形式下,拉普拉斯算子通常定义为一个二阶导数的模板。在二维图像处理中,常见的拉普拉斯算子有以下几种形式:
cv2.Laplacian(src, ddepth[, ksize[, scale[, delta[, borderType]]]])
相比于 sobel,不需要分别计算水平和垂直。缺点是对噪音比较敏感,所以一般先进行平滑去噪。
ddepth
常见的深度值包括:
cv2.CV_8U: 无符号8位整数(0-255)。
cv2.CV_16U: 无符号16位整数。
cv2.CV_16S: 有符号16位整数。
cv2.CV_32F: 单精度浮点数。
cv2.CV_64F: 双精度浮点数。
选择适当的深度取决于应用程序的需求。如果图像中的边缘强度较大且可能为负值,则使用浮点数类型(如 cv2.CV_64F)可能更合适。
Canny 边缘检测
Canny边缘检测是一种经典的边缘检测算法,具有很好的性能和鲁棒性。以下是Canny边缘检测的基本步骤:
- 灰度转换: 首先,将输入图像转换为灰度图像。这是因为Canny算法通常应用于灰度图像,而不是彩色图像。
- 高斯滤波: 对灰度图像进行高斯滤波,以平滑图像并减小噪声。这有助于确保在边缘检测过程中不受到噪声的干扰。
- 计算梯度: 使用Sobel等算子计算图像的梯度。这一步将得到图像中每个像素点的梯度幅值和方向。方向包括
- 非极大值抑制: 对梯度图进行非极大值抑制,以保留局部梯度最大的像素,而抑制其他非极大值的像素。
- 双阈值检测: 使用双阈值来标记图像中的强边缘和弱边缘。根据梯度幅值,像素被分类为强边缘、弱边缘或非边缘。一般来说,强边缘具有较大的梯度值,而弱边缘具有较小的梯度值。超过强阈值,一定是边缘,低于弱阈值,一定不是,中间的则看与已经确定的边缘的连接性。
- 边缘跟踪: 根据强边缘的连通性,将弱边缘中与强边缘相连的部分保留作为最终的边缘。
# 进行Canny边缘检测
edges = cv2.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=False)
# 参数说明:
# - image: 输入的灰度图像
# - threshold1, threshold2: 用于进行边缘检测的双阈值,低阈值和高阈值之间的区域会被认为是边缘。
# - apertureSize: Sobel算子的孔径大小,默认为3。
# - L2gradient: 一个布尔值,如果为True,则使用更精确的L2范数进行梯度计算,否则使用L1范数。默认为False。