八、OpenCV中的常见滤波方式

文章目录

一、滤波的分类

1.线性滤波

均值滤波(cv::blur)

作用:用邻域内像素的均值来代替中心像素,平滑图像,去除噪声。缺点是模糊明显,边缘不清晰。

函数原型:

cpp 复制代码
void cv::blur(InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT);

参数:

  • src: 输入图像。
  • dst: 输出图像。
  • ksize: 滤波核大小,如 Size(3,3)。
  • anchor: 锚点(默认中心)。
  • borderType: 边界处理方式。

示例:

cpp 复制代码
cv::Mat img = cv::imread("lena.jpg");
cv::Mat result;
cv::blur(img, result, cv::Size(5,5));

高斯滤波(cv::GaussianBlur)

作用:高斯加权平均,邻域内越靠近中心的像素权重越大,常用于图像去噪。优点是保留更多边缘信息,效果比均值滤波更自然。

函数原型:

cpp 复制代码
void cv::GaussianBlur(InputArray src, OutputArray dst, Size ksize,
                      double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT);

参数:

  • ksize: 高斯核大小(必须为奇数)。
  • sigmaX: X方向标准差。
    sigmaY: Y方向标准差(默认 0,即与 sigmaX 相同)。

示例:

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

方框滤波(cv::boxFilter)

作用:类似均值滤波,但可以选择是否进行归一化。

函数原型:

cpp 复制代码
void cv::boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize,
                   Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT);

区别:

  • normalize = true → 等价于均值滤波。
  • normalize = false → 卷积核全为 1,不做均值,输出像素值可能变大。

示例:

cpp 复制代码
cv::boxFilter(img, result, -1, cv::Size(5,5), cv::Point(-1,-1), true);

2. 非线性滤波

中值滤波(cv::medianBlur)

作用:用邻域内像素的中值替代中心像素,特别适合去除椒盐噪声。

函数原型:

cpp 复制代码
void cv::medianBlur(InputArray src, OutputArray dst, int ksize);

参数:

  • ksize: 滤波核大小(必须为奇数,如 3、5、7)。

示例:

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

双边滤波(cv::bilateralFilter)

作用:同时考虑空间距离和像素差异,既能平滑噪声,又能保持边缘。

函数原型:

cpp 复制代码
void cv::bilateralFilter(InputArray src, OutputArray dst, int d,
                         double sigmaColor, double sigmaSpace, int borderType = BORDER_DEFAULT);

参数:

  • d: 邻域直径(像素数,推荐 5~15)。
  • sigmaColor: 颜色空间标准差(越大越模糊)。
  • sigmaSpace: 坐标空间标准差(越大越模糊)。

示例:

cpp 复制代码
cv::bilateralFilter(img, result, 9, 75, 75);

自定义滤波(cv::filter2D)

作用:用自定义的卷积核对图像进行滤波(如锐化、边缘检测)。

函数原型:

cpp 复制代码
void cv::filter2D(InputArray src, OutputArray dst, int ddepth,
                  InputArray kernel, Point anchor = Point(-1,-1), double delta = 0,
                  int borderType = BORDER_DEFAULT);

示例:

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

二、示例代码

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

// 辅助函数:在图像上添加标题
Mat addTitle(const Mat& img, const string& title) {
    Mat dst;
    img.copyTo(dst);
    putText(dst, title, Point(10, 30), FONT_HERSHEY_SIMPLEX,
        1.0, Scalar(0, 0, 255), 2); // 红色文字
    return dst;
}

int main() {
    // 读取图像
    Mat src = imread("opencv_demo.png");
    if (src.empty()) {
        cout << "无法读取图片!" << endl;
        return -1;
    }

    // 调整大小,保证拼接时统一尺寸
    Mat src_resized;
    resize(src, src_resized, Size(300, 300));

    // 各种滤波结果
    Mat blurImg, gaussianImg, medianImg, bilateralImg, sharpenImg;

    // 均值滤波
    blur(src_resized, blurImg, Size(5, 5));

    // 高斯滤波
    GaussianBlur(src_resized, gaussianImg, Size(5, 5), 1.5);

    // 中值滤波
    medianBlur(src_resized, medianImg, 5);

    // 双边滤波
    bilateralFilter(src_resized, bilateralImg, 9, 75, 75);

    // 锐化滤波 (自定义卷积核)
    Mat kernel = (Mat_<float>(3, 3) <<
        0, -1, 0,
        -1, 5, -1,
        0, -1, 0);
    filter2D(src_resized, sharpenImg, -1, kernel);

    // 加标题
    Mat img1 = addTitle(src_resized, "Original");
    Mat img2 = addTitle(blurImg, "Mean Blur");
    Mat img3 = addTitle(gaussianImg, "Gaussian Blur");
    Mat img4 = addTitle(medianImg, "Median Blur");
    Mat img5 = addTitle(bilateralImg, "Bilateral Filter");
    Mat img6 = addTitle(sharpenImg, "Sharpen");

    // 第一行 (原图 + 均值 + 高斯)
    Mat topRow;
    hconcat(vector<Mat>{img1, img2, img3}, topRow);

    // 第二行 (中值 + 双边 + 锐化)
    Mat bottomRow;
    hconcat(vector<Mat>{img4, img5, img6}, bottomRow);

    // 拼成 2x3 大图
    Mat finalShow;
    vconcat(topRow, bottomRow, finalShow);

    imshow("滤波对比", finalShow);
    waitKey(0);
    return 0;
}

输出结果如下:

相关推荐
dazzle3 分钟前
计算机视觉处理(OpenCV基础教学(二十一):模板匹配技术详解)
人工智能·opencv·计算机视觉
啊巴矲6 分钟前
小白从零开始勇闯人工智能:计算机视觉初级篇(初识Opencv中)
人工智能·opencv·计算机视觉
saoys9 小时前
Opencv 学习笔记:图像掩膜操作(精准提取指定区域像素)
笔记·opencv·学习
li星野14 小时前
OpenCV4X学习—核心模块Core
人工智能·opencv·学习
saoys15 小时前
Opencv 学习笔记:绘制动态随机直线(附实时展示)
笔记·opencv·学习
MM_MS17 小时前
Halcon图像锐化和图像增强、窗口的相关算子
大数据·图像处理·人工智能·opencv·算法·计算机视觉·视觉检测
saoys20 小时前
Opencv 学习笔记:一文掌握四种经典图像滤波(均值 / 高斯 / 中值 / 双边)
笔记·opencv·学习
Elaine3361 天前
【验证码识别算法性能对比实验系统——KNN、SVM、CNN 与多模态大模型的性能博弈与机理分析】
python·opencv·支持向量机·cnn·多模态·数字图像处理
saoys1 天前
Opencv 学习笔记:滑块(Trackbar)实现动态调整二值化阈值
笔记·opencv·学习
saoys1 天前
Opencv 学习笔记:图像绘制(直线 / 圆 / 椭圆 / 矩形 / 多边形 + 文字添加)
笔记·opencv·学习