OpenCV(二十四):图像滤波

滤波概述

在数字图像处理中,滤波(Filtering) 是最基本也是最常用的操作之一。滤波的核心思想是利用邻域像素的信息,对目标像素的灰度值或颜色进行加权平均或非线性变换,从而达到 去噪、平滑、增强或提取特征 的目的。

在 OpenCV 中,滤波功能非常完善,提供了线性滤波(如均值滤波、高斯滤波)、非线性滤波(如中值滤波、双边滤波)以及基于卷积核的自定义滤波接口。

滤波的基本原理

假设输入图像为 I(x,y),滤波器或卷积核(Kernel)为 K(i,j),则线性滤波可表示为:

其中:

  • I′(x,y):滤波后的输出像素;
  • K(i,j):卷积核的权重;
  • (2k+1)×(2k+1):核的尺寸。

根据卷积核权值分布的不同,滤波可分为平滑滤波锐化滤波

  • 平滑滤波:抑制噪声与细节变化,使图像变得更"平滑";
  • 锐化滤波:增强边缘与细节,使图像更清晰。

卷积核

概念

在图像处理中,卷积核(Kernel) 是一个用于提取图像局部特征的矩阵。

它定义了如何将输入图像中每个像素与其邻域像素组合,从而生成新的输出图像。

数学上,卷积(Convolution)操作可表示为:

其中:

  • I(x,y):输入图像;
  • K(i,j):卷积核(权重矩阵);
  • G(x,y):输出图像;
  • k:卷积核的半径(若核大小为 3×3,则 k=1)。

卷积的本质是:

通过局部加权求和的方式,让图像在空间域上发生平滑、锐化、边缘增强、检测等变化。

分类

在 OpenCV 中,卷积核主要分为以下几类:

分类 核心作用 常见类型 示例函数
平滑滤波核 去噪与模糊图像 均值核、高斯核 cv2.blur, cv2.GaussianBlur
锐化核 增强边缘与细节 Laplacian、锐化核 cv2.filter2D, cv2.Laplacian
边缘检测核 提取梯度与轮廓 Sobel、Prewitt、Canny cv2.Sobel, cv2.Canny
特殊效果核 模拟浮雕、边缘光照等 Emboss、Outline 自定义卷积核

OpenCV 中的卷积函数

函数名 功能 示例
cv2.filter2D() 通用卷积操作 自定义核
cv2.blur() 均值滤波 平滑
cv2.GaussianBlur() 高斯滤波 去噪
cv2.medianBlur() 中值滤波(非线性) 去椒盐噪声
cv2.bilateralFilter() 双边滤波 平滑且保边
cv2.Sobel() 一阶导边缘检测 边缘检测
cv2.Laplacian() 二阶导锐化 边缘增强

平滑滤波(去噪滤波)

1. 均值滤波(Mean Filter)

原理:用邻域像素的平均值替代中心像素。该方法简单高效,但对边缘保留能力较差。

公式:

OpenCV 实现:

cpp 复制代码
cv::blur(src, dst, cv::Size(5, 5));

特点:

  • 计算速度快;
  • 容易模糊边缘;
  • 适合去除高斯噪声。

2. 高斯滤波(Gaussian Filter)

原理: 使用高斯分布作为权重函数,对邻域像素加权平均。距离中心越近的像素权重越大。

高斯核定义:

OpenCV 实现:

cpp 复制代码
cv::GaussianBlur(src, dst, cv::Size(5, 5), 1.5);

参数说明:

  • Size(5,5):核大小;
  • sigmaXsigmaY:高斯分布的标准差。

特点:

  • 平滑性优于均值滤波;
  • 对噪声的抑制更有效;
  • 能保持一定的边缘特征。

3. 中值滤波(Median Filter)

原理: 用邻域像素的中值替代中心像素值,属于非线性滤波。

OpenCV 实现:

cpp 复制代码
cv::medianBlur(src, dst, 5);

特点:

  • 对椒盐噪声效果非常好;
  • 边缘保留能力强;
  • 运算速度略慢于均值滤波。

4. 双边滤波(Bilateral Filter)

原理: 同时考虑空间距离与像素相似性两个因素。即使在平滑噪声的同时,也能很好地保留边缘。

加权公式:

其中:

  • Gs:空间高斯权重;
  • Gr:像素值相似度权重。

OpenCV 实现:

cpp 复制代码
cv::bilateralFilter(src, dst, 9, 75, 75);

参数含义:

  • 9:邻域直径;
  • 75:颜色与空间的高斯标准差。

特点:

  • 边缘保留能力最强;
  • 去噪效果好;
  • 计算复杂度高。

5. 非局部均值滤波(Non-Local Means)

原理: 通过在更大范围内寻找相似块进行加权平均,保留纹理和细节。

OpenCV 实现:

复制代码
cv::fastNlMeansDenoising(src, dst, 10, 7, 21);

特点:

  • 能有效保留纹理;
  • 适合自然图像;
  • 计算量大。

锐化滤波(边缘增强)

锐化滤波的目的是增强图像的边缘,使轮廓更加清晰。常用方法包括 拉普拉斯滤波Sobel 滤波自定义卷积核锐化

1. 拉普拉斯滤波(Laplacian Filter)

原理: 计算像素的二阶导数,检测灰度突变区域。

公式:

OpenCV 实现:

cpp 复制代码
cv::Laplacian(src, dst, CV_16S, 3);
cv::convertScaleAbs(dst, dst);

特点:

  • 对噪声敏感;
  • 常与高斯滤波配合使用(如 LoG 算法)。

2. Sobel 滤波(Sobel Filter)

原理: 一阶导数算子,用于检测边缘方向。

Sobel 核:

OpenCV 实现:

cpp 复制代码
cv::Sobel(src, grad_x, CV_16S, 1, 0);
cv::Sobel(src, grad_y, CV_16S, 0, 1);
cv::convertScaleAbs(grad_x, grad_x);
cv::convertScaleAbs(grad_y, grad_y);
cv::addWeighted(grad_x, 0.5, grad_y, 0.5, 0, dst);

特点:

  • 对边缘方向敏感;
  • 可结合梯度幅值计算实现边缘检测。

3. 自定义卷积锐化

可以通过自定义卷积核实现更灵活的锐化效果。例如经典锐化核:

OpenCV 实现:

cpp 复制代码
cv::Mat kernel = (cv::Mat_<float>(3,3) << 0,-1,0,-1,5,-1,0,-1,0);
cv::filter2D(src, dst, -1, kernel);

特点:

  • 可灵活调整锐化强度;
  • 可与平滑滤波结合使用。

自定义滤波与卷积

OpenCV 提供了 filter2D() 通用接口,可自定义任意卷积核,实现各种滤波器。

示例:

cpp 复制代码
cv::Mat kernel = (cv::Mat_<float>(3,3) << 1,1,1,1,1,1,1,1,1);
kernel = kernel / 9.0;
cv::filter2D(src, dst, -1, kernel);

说明:

  • 第三个参数 -1 表示输出图像深度与输入相同;
  • 可通过改变核系数实现不同效果。

示例:

python 复制代码
import cv2
import numpy as np

# 读取原图(灰度)
src = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE)

# ----------------------------
# 1. 自定义均值滤波核
# ----------------------------
mean_kernel = np.ones((5, 5), np.float32) / 25
dst_mean = cv2.filter2D(src, -1, mean_kernel)

# ----------------------------
# 2. 自定义锐化滤波核
# ----------------------------
sharpen_kernel = np.array([[0, -1, 0],
                           [-1, 5, -1],
                           [0, -1, 0]], np.float32)
dst_sharp = cv2.filter2D(src, -1, sharpen_kernel)

# ----------------------------
# 3. 自定义边缘检测核(Sobel X方向)
# ----------------------------
sobelx_kernel = np.array([[-1, 0, 1],
                          [-2, 0, 2],
                          [-1, 0, 1]], np.float32)
dst_sobelx = cv2.filter2D(src, -1, sobelx_kernel)

# ----------------------------
# 4. 自定义拉普拉斯核(边缘增强)
# ----------------------------
laplacian_kernel = np.array([[0, 1, 0],
                             [1, -4, 1],
                             [0, 1, 0]], np.float32)
dst_lap = cv2.filter2D(src, -1, laplacian_kernel)

# ----------------------------
# 5. 自定义浮雕滤波核
# ----------------------------
emboss_kernel = np.array([[-2, -1, 0],
                          [-1, 1, 1],
                          [0, 1, 2]], np.float32)
dst_emboss = cv2.filter2D(src, -1, emboss_kernel)
dst_emboss = cv2.normalize(dst_emboss, None, 0, 255, cv2.NORM_MINMAX)

# ----------------------------
# 显示结果
# ----------------------------
cv2.imshow("Original", src)
cv2.imshow("Mean Blur", dst_mean)
cv2.imshow("Sharpen", dst_sharp)
cv2.imshow("Sobel X", dst_sobelx)
cv2.imshow("Laplacian", dst_lap)
cv2.imshow("Emboss", dst_emboss)

cv2.waitKey(0)
cv2.destroyAllWindows()

总结

滤波类型 是否线性 主要优点 主要缺点 典型场景
均值滤波 线性 简单高效 模糊边缘 基础平滑
高斯滤波 线性 去噪效果好 边缘损失 图像预处理
中值滤波 非线性 去椒盐噪声 运算慢 工业视觉
双边滤波 非线性 保边去噪 计算复杂 美颜、HDR
非局部均值 非线性 保留纹理 速度慢 高质量去噪
Sobel/拉普拉斯 线性 边缘增强 对噪声敏感 边缘检测
相关推荐
人工智能训练1 天前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
源于花海1 天前
迁移学习相关的期刊和会议
人工智能·机器学习·迁移学习·期刊会议
DisonTangor1 天前
DeepSeek-OCR 2: 视觉因果流
人工智能·开源·aigc·ocr·deepseek
薛定谔的猫19821 天前
二十一、基于 Hugging Face Transformers 实现中文情感分析情感分析
人工智能·自然语言处理·大模型 训练 调优
发哥来了1 天前
《AI视频生成技术原理剖析及金管道·图生视频的应用实践》
人工智能
数智联AI团队1 天前
AI搜索引领开源大模型新浪潮,技术创新重塑信息检索未来格局
人工智能·开源
不懒不懒1 天前
【线性 VS 逻辑回归:一篇讲透两种核心回归模型】
人工智能·机器学习
冰西瓜6001 天前
从项目入手机器学习——(四)特征工程(简单特征探索)
人工智能·机器学习
Ryan老房1 天前
未来已来-AI标注工具的下一个10年
人工智能·yolo·目标检测·ai
丝斯20111 天前
AI学习笔记整理(66)——多模态大模型MOE-LLAVA
人工智能·笔记·学习