opencv算法

OpenCV滤波算法详解

目录

  1. 线性滤波算法
  2. 非线性滤波算法
  3. 边缘检测和梯度算子
  4. 形态学操作
  5. 实际应用示例
  6. 选择指南

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),建议值为9
  • 75: 颜色空间标准差 (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-8
  • eps: 正则化参数 (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_16S
  • 1: X方向导数阶数 (int dx),必须是1
  • 0: 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_32F
  • 3: 滤波核大小 (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_OPENMORPH_CLOSEMORPH_GRADIENTMORPH_TOPHATMORPH_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),默认为0
  • borderType: 边界类型 (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.0
  • beta: 偏移值 (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_CROSS
  • ksize: 结构元素大小 (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|)

三个操作步骤:

  1. 缩放: src * alpha
  2. 偏移: + beta
  3. 取绝对值: |...|
  4. 类型转换: 转为8位无符号整数 (0-255)

这个函数在处理Sobel、Laplacian等算子结果时特别有用,因为这些算子输出的是有符号的16位整数,包含正值和负值,需要转换为0-255范围才能正常显示。

这些滤波器各有特点,选择时需要考虑噪声类型、处理目标、计算效率等因素。

posted @ 2025-12-22 11:43  lskyl  阅读(4)  评论(0)    收藏  举报