八、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;
}

输出结果如下:

相关推荐
别动我齐刘海13 小时前
机器学习基础2——C++、OpenCV、点云、Open3D
c++·人工智能·opencv·机器学习·计算机视觉·机器人·ros2
雪碧透心凉_16 小时前
Python OpenCV图像处理入门
图像处理·python·opencv
躺不平的理查德17 小时前
OpenCV Mat 备忘录
人工智能·opencv·计算机视觉
欧特克_Glodon18 小时前
OpenCV计算机视觉开发入门与实践<二>:图像噪声与图像处理
c++·图像处理·opencv·计算机视觉
牧羊人.3331 天前
计算机视觉基础|第2章 OpenCV图像基础操作(读写、窗口、像素操作)
人工智能·opencv·计算机视觉
崖边看雾2 天前
OpenCV 图像处理学习笔记|图像运算、边界填充、阈值处理、图像平滑滤波
图像处理·opencv·学习
AI的探索之旅2 天前
嵌入式视觉学习路线:Qt + OpenCV + 工业相机,从零到综合项目
qt·opencv·学习
AI的探索之旅2 天前
AI + LLM Wiki 高效学习 OpenCV:我的 8 步闭环方法论
人工智能·opencv·学习
≮傷£≯√2 天前
Opencv VideoCapture
qt·opencv
sali-tec3 天前
C# 基于OpenCv的视觉工作流-章102-车牌识别
图像处理·人工智能·opencv·计算机视觉