opencv算法
OpenCV滤波算法详解
目录
1. 线性滤波算法
1.1 均值滤波 (Blur/Average Filter)
cv::blur(image, result, cv::Size(3, 3));
参数说明:
image: 输入图像 (InputArray)result: 输出图像 (OutputArray)cv::Size(3, 3): 滤波核大小 (Size),必须是奇数
作用: 用邻域像素的平均值替换中心像素
特点:
- 简单快速
- 能有效去除高斯噪声
- 会模糊边缘
- 所有权重相等
卷积核:
1/9 * [1 1 1]
[1 1 1]
[1 1 1]
1.2 高斯滤波 (Gaussian Filter)
cv::GaussianBlur(image, result, cv::Size(5, 5), 1.5);
参数说明:
image: 输入图像 (InputArray)result: 输出图像 (OutputArray)cv::Size(5, 5): 滤波核大小 (Size),宽度和高度必须是奇数1.5: 高斯核的标准差 (double sigmaX),设为0时自动计算- 可选参数:
sigmaY(Y方向标准差,默认等于sigmaX) - 可选参数:
borderType(边界类型,默认为BORDER_DEFAULT)
作用: 使用高斯分布进行加权平均
特点:
- 中心像素权重最大,距离越远权重越小
- 去噪效果好,边缘保持较好
- 符合人眼视觉特性
- 可分离滤波器,计算效率高
5×5高斯核:
1/273 * [ 1 4 7 4 1]
[ 4 16 26 16 4]
[ 7 26 41 26 7]
[ 4 16 26 16 4]
[ 1 4 7 4 1]
1.3 方框滤波 (Box Filter)
cv::boxFilter(image, result, -1, cv::Size(3, 3));
参数说明:
image: 输入图像 (InputArray)result: 输出图像 (OutputArray)-1: 输出图像深度 (int ddepth),-1表示与输入相同cv::Size(3, 3): 滤波核大小 (Size)- 可选参数:
anchor(锚点位置,默认为Point(-1,-1)表示中心) - 可选参数:
normalize(是否归一化,默认为true) - 可选参数:
borderType(边界类型)
作用: 类似均值滤波,但不进行归一化
特点:
- 可以选择是否归一化
- 适合积分图计算
2. 非线性滤波算法
2.1 中值滤波 (Median Filter)
cv::medianBlur(image, result, 3);
参数说明:
image: 输入图像 (InputArray),可以是1、3或4通道图像result: 输出图像 (OutputArray),与输入图像大小和类型相同3: 滤波核大小 (int ksize),必须是大于1的奇数,如3、5、7等
作用: 用邻域像素的中值替换中心像素
特点:
- 对椒盐噪声非常有效
- 能保持边缘清晰
- 不会产生新像素值
- 计算量较大
2.2 双边滤波 (Bilateral Filter)
cv::bilateralFilter(image, result, 9, 75, 75);
参数说明:
image: 输入图像 (InputArray),必须是8位整数或浮点数result: 输出图像 (OutputArray),与输入图像大小和类型相同9: 像素邻域直径 (int d),建议值为975: 颜色空间标准差 (double sigmaColor),值越大混合越多颜色75: 坐标空间标准差 (double sigmaSpace),值越大影响越远的像素
作用: 保边去噪滤波器
特点:
- 同时考虑空间距离和像素值相似性
- 能保持边缘锐利
- 计算复杂度高
- 美颜滤镜的基础
2.3 导向滤波 (Guided Filter)
cv::ximgproc::guidedFilter(guide, src, dst, radius, eps);
参数说明:
guide: 引导图像 (InputArray),用于指导滤波过程src: 待滤波图像 (InputArray)dst: 输出图像 (OutputArray)radius: 滤波半径 (int),通常取值为2-8eps: 正则化参数 (double),控制滤波强度,值越大平滑效果越强- 可选参数:
dDepth(输出图像深度,默认为-1表示与输入相同)
作用: 使用引导图进行滤波
特点:
- 比双边滤波速度快
- 边缘保持效果好
- 可用于HDR、去雾等
3. 边缘检测和梯度算子
3.1 Sobel算子
cv::Sobel(image, sobel_x, CV_16S, 1, 0, 3); // 水平方向
cv::Sobel(image, sobel_y, CV_16S, 0, 1, 3); // 垂直方向
参数说明:
image: 输入图像 (InputArray)sobel_x/sobel_y: 输出图像 (OutputArray)CV_16S: 输出图像深度 (int ddepth),常用CV_16S避免梯度溢出1/0: X方向导数阶数 (int dx),1表示计算X方向梯度,0表示不计算0/1: Y方向导数阶数 (int dy),1表示计算Y方向梯度,0表示不计算3: 滤波核大小 (int ksize),必须是1、3、5或7,推荐3- 可选参数:
scale(缩放因子,默认为1) - 可选参数:
delta(偏移值,默认为0) - 可选参数:
borderType(边界类型)
作用: 计算图像梯度
特点:
- 一阶导数算子
- 对噪声敏感
- 可检测水平和垂直边缘
3×3 Sobel核:
水平: [-1 0 1] 垂直: [-1 -2 -1]
[-2 0 2] [ 0 0 0]
[-1 0 1] [ 1 2 1]
3.2 Scharr算子
cv::Scharr(image, scharr_x, CV_16S, 1, 0);
参数说明:
image: 输入图像 (InputArray)scharr_x: 输出图像 (OutputArray)CV_16S: 输出图像深度 (int ddepth),常用CV_16S1: X方向导数阶数 (int dx),必须是10: Y方向导数阶数 (int dy),必须是0- 可选参数:
scale(缩放因子,默认为1) - 可选参数:
delta(偏移值,默认为0) - 可选参数:
borderType(边界类型)
注意: Scharr算子只能计算单个方向的梯度,需要分别调用计算X和Y方向
作用: Sobel算子的改进版本
特点:
- 梯度检测更准确
- 旋转不变性更好
- 适合小核
3.3 Laplacian算子
cv::Laplacian(image, laplacian, CV_16S, 3);
参数说明:
image: 输入图像 (InputArray)laplacian: 输出图像 (OutputArray)CV_16S: 输出图像深度 (int ddepth),推荐CV_16S或CV_32F3: 滤波核大小 (int ksize),必须是1、3、5或7- 可选参数:
scale(缩放因子,默认为1) - 可选参数:
delta(偏移值,默认为0) - 可选参数:
borderType(边界类型)
作用: 二阶导数算子
特点:
- 对边缘更敏感
- 对噪声更敏感
- 各向同性
Laplacian核:
[ 0 1 0] 或 [ 1 1 1]
[ 1 -4 1] [ 1 -8 1]
[ 0 1 0] [ 1 1 1]
3.4 Canny边缘检测
cv::Canny(image, edges, 50, 150);
参数说明:
image: 输入图像 (InputArray),必须是单通道8位图像edges: 输出边缘图像 (OutputArray),单通道二值图像50: 低阈值 (double threshold1),用于边缘连接150: 高阈值 (double threshold2),用于强边缘检测- 可选参数:
apertureSize(Sobel算子核大小,默认为3) - 可选参数:
L2gradient(是否使用L2梯度,默认为false使用L1梯度)
阈值说明:
- 像素梯度 > 高阈值 → 强边缘点
- 低阈值 < 像素梯度 ≤ 高阈值 → 弱边缘点
- 像素梯度 ≤ 低阈值 → 被抑制
作用: 多步骤边缘检测算法
特点:
- 使用高斯滤波去噪
- 双阈值检测
- 滞后阈值处理
- 边缘连接优化
4. 形态学操作
4.1 腐蚀 (Erosion)
cv::erode(image, result, kernel);
参数说明:
image: 输入图像 (InputArray),可以是任意通道数result: 输出图像 (OutputArray),与输入图像大小和类型相同kernel: 结构元素 (InputArray),定义腐蚀的形状和大小- 可选参数:
anchor(锚点位置,默认为Point(-1,-1)表示中心) - 可选参数:
iterations(迭代次数,默认为1) - 可选参数:
borderType(边界类型) - 可选参数:
borderValue(边界值)
作用: 消除小的白色区域
特点:
- 使物体边界收缩
- 去除孤立点
- 断开连接区域
4.2 膨胀 (Dilation)
cv::dilate(image, result, kernel);
参数说明:
image: 输入图像 (InputArray)result: 输出图像 (OutputArray)kernel: 结构元素 (InputArray)- 可选参数:
anchor(锚点位置,默认为Point(-1,-1)) - 可选参数:
iterations(迭代次数,默认为1) - 可选参数:
borderType(边界类型) - 可选参数:
borderValue(边界值)
作用: 扩大白色区域
特点:
- 使物体边界扩张
- 填充小空洞
- 连接断裂区域
4.3 开运算 (Opening)
cv::morphologyEx(image, result, cv::MORPH_OPEN, kernel);
参数说明:
image: 输入图像 (InputArray)result: 输出图像 (OutputArray)cv::MORPH_OPEN: 形态学操作类型 (int op)kernel: 结构元素 (InputArray)- 可选参数:
anchor(锚点位置) - 可选参数:
iterations(迭代次数,默认为1) - 可选参数:
borderType(边界类型)
操作类型: MORPH_OPEN、MORPH_CLOSE、MORPH_GRADIENT、MORPH_TOPHAT、MORPH_BLACKHAT
公式: Result = Erode(Dilate(image))
作用: 去除噪声,保持形状
4.4 闭运算 (Closing)
cv::morphologyEx(image, result, cv::MORPH_CLOSE, kernel);
参数说明: 同开运算,只是操作类型为MORPH_CLOSE
公式: Result = Dilate(Erode(image))
作用: 填充小洞,连接邻近物体
4.5 梯度 (Gradient)
cv::morphologyEx(image, result, cv::MORPH_GRADIENT, kernel);
参数说明: 同开运算,操作类型为MORPH_GRADIENT
公式: Result = Dilate(image) - Erode(image)
作用: 提取物体轮廓
4.6 顶帽 (Top Hat)
cv::morphologyEx(image, result, cv::MORPH_TOPHAT, kernel);
参数说明: 同开运算,操作类型为MORPH_TOPHAT
公式: Result = image - Opening(image)
作用: 提取比结构元素小的亮区域
4.7 黑帽 (Black Hat)
cv::morphologyEx(image, result, cv::MORPH_BLACKHAT, kernel);
参数说明: 同开运算,操作类型为MORPH_BLACKHAT
公式: Result = Closing(image) - image
作用: 提取比结构元素小的暗区域
5. 实际应用示例
5.1 去噪应用
// 高斯噪声 - 使用高斯滤波
cv::GaussianBlur(noisy_image, denoised, cv::Size(5, 5), 1.5);
// 椒盐噪声 - 使用中值滤波
cv::medianBlur(noisy_image, denoised, 3);
// 保边去噪 - 使用双边滤波
cv::bilateralFilter(noisy_image, denoised, 9, 75, 75);
5.2 边缘检测流程
// 完整的边缘检测流程
cv::Mat gray, blurred, edges;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 1.5);
cv::Canny(blurred, edges, 50, 150);
5.3 形态学应用
// 文字增强
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(binary_image, result, cv::MORPH_CLOSE, kernel);
// 噪声去除
cv::morphologyEx(binary_image, result, cv::MORPH_OPEN, kernel);
5.4 自定义卷积核
// 锐化滤波器
cv::Mat sharpen_kernel = (cv::Mat_<float>(3, 3) <<
-1, -1, -1,
-1, 9, -1,
-1, -1, -1);
cv::filter2D(image, result, -1, sharpen_kernel);
//浮雕效果
cv::Mat emboss_kernel = (cv::Mat_<float>(3, 3) <<
-2, -1, 0,
-1, 1, 1,
0, 1, 2);
cv::filter2D(image, result, -1, emboss_kernel);
// 水平边缘检测
cv::Mat horizontal_kernel = (cv::Mat_<float>(1, 3) << -1, 0, 1);
cv::filter2D(image, result, CV_32F, horizontal_kernel);
filter2D参数说明:
cv::filter2D(src, dst, ddepth, kernel, anchor, delta, borderType);
src: 输入图像 (InputArray)dst: 输出图像 (OutputArray)ddepth: 输出图像深度 (int),-1表示与输入相同kernel: 卷积核 (InputArray),单通道浮点矩阵anchor: 锚点位置 (Point),默认为Point(-1,-1)表示核中心delta: 偏移值 (double),默认为0borderType: 边界类型 (int),默认为BORDER_DEFAULT
5.5 convertScaleAbs的使用
// Sobel算子结果处理
cv::Mat sobel_x, sobel_x_abs;
cv::Sobel(image, sobel_x, CV_16S, 1, 0); // 16位有符号
cv::convertScaleAbs(sobel_x, sobel_x_abs); // 转为8位无符号用于显示
// 对比度和亮度调整
cv::Mat enhanced;
cv::convertScaleAbs(image, enhanced, 1.5, 50); // alpha=1.5(对比度), beta=50(亮度)
// 等价于以下三步操作:
// cv::Mat temp = image * 1.5 + 50;
// temp = cv::abs(temp);
// temp.convertTo(enhanced, CV_8U);
convertScaleAbs参数说明:
cv::convertScaleAbs(src, dst, alpha, beta);
src: 输入数组 (InputArray)dst: 输出数组 (OutputArray),8位无符号整数alpha: 缩放因子 (double),默认为1.0beta: 偏移值 (double),默认为0
5.6 结构元素创建
// 矩形结构元素
cv::Mat rect_kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
// 椭圆结构元素
cv::Mat ellipse_kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(5, 5));
// 十字形结构元素
cv::Mat cross_kernel = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
getStructuringElement参数说明:
cv::getStructuringElement(shape, ksize, anchor);
shape: 结构元素形状 (int) - MORPH_RECT, MORPH_ELLIPSE, MORPH_CROSSksize: 结构元素大小 (Size)anchor: 锚点位置 (Point),默认为Point(-1,-1)表示中心
6. 选择指南
| 应用场景 | 推荐算法 | 原因 |
|---|---|---|
| 高斯噪声 | GaussianBlur | 效果好,速度快 |
| 椒盐噪声 | medianBlur | 保持边缘,去除斑点 |
| 保边去噪 | bilateralFilter | 保持边缘锐利 |
| 边缘检测 | Canny | 完整的边缘检测流程 |
| 文字处理 | 形态学操作 | 连接断笔,去除噪声 |
| 图像增强 | filter2D+自定义核 | 灵活性高 |
| 梯度计算 | Sobel/Scharr | 一阶导数,方向敏感 |
| 轮廓提取 | morphological gradient | 提取物体边缘 |
核心概念理解
卷积的本质
通过卷积核在图像上滑动,对局部区域进行加权求和,实现不同的图像处理效果。
关键参数
- 核大小: 影响处理强度和计算量
- 核权重: 决定处理效果
- 边界处理: 常用补零或镜像
性能考虑
- 可分离核(如高斯)可优化计算
- 大核计算量成指数增长
- GPU可加速卷积运算
convertScaleAbs函数
void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0)
功能: 对输入数组进行缩放、绝对值、转换为8位无符号整数的组合操作
数学公式: dst = saturate_cast<uchar>(|src * alpha + beta|)
三个操作步骤:
- 缩放:
src * alpha - 偏移:
+ beta - 取绝对值:
|...| - 类型转换: 转为8位无符号整数 (0-255)
这个函数在处理Sobel、Laplacian等算子结果时特别有用,因为这些算子输出的是有符号的16位整数,包含正值和负值,需要转换为0-255范围才能正常显示。
这些滤波器各有特点,选择时需要考虑噪声类型、处理目标、计算效率等因素。

浙公网安备 33010602011771号