目录

引言

1. 线性滤波

1.1 定义

1.2 特点

1.3 常见类型

1.3.1 方框滤波(Box Filter)

1.3.2 均值滤波(Blur)

1.3.3 高斯滤波(Gaussian Blur)

2. 非线性滤波

2.1 定义

2.2 特点

2.3 常见类型

2.3.1 中值滤波(Median Filter)

2.3.2 双边滤波(Bilateral Filter)

3. 所有示例

4. 总结


引言

在图像处理领域,滤波是一项基本且重要的技术,用于改善图像质量、去除噪声、增强边缘等。OpenCV作为一个强大的计算机视觉库,提供了多种图像滤波技术,包括线性滤波和非线性滤波。本文将详细介绍OpenCV中的图像滤波技术,包括相关类和函数的用法,并通过示例代码展示其应用。

1. 线性滤波

1.1 定义

线性滤波是指对邻域中的像素进行线性运算的滤波方法,如利用窗口函数进行平滑加权求和的运算,或者某种卷积运算。线性滤波器的输出是输入像素的加权和,权重由滤波器(也称为卷积核或模板)确定。

1.2 特点

  • 线性运算:对图像中的每个像素点,其输出值是该点邻域内像素值的线性组合。
  • 模板固定:滤波时使用的模板(或卷积核)是固定的,不随图像内容的变化而变化。
  • 平滑效果:线性滤波通常用于平滑图像,减少图像噪声,但也可能导致图像细节模糊。

1.3 常见类型

1.3.1 方框滤波(Box Filter)

方框滤波通过计算像素邻域内的平均值来平滑图像,也称为均值滤波。OpenCV中,可以使用cv::boxFilter函数实现。

函数原型

void cv::boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), bool normalize=true, int borderType=BORDER_DEFAULT)
  • src:输入图像。
  • dst:输出图像。
  • ddepth:输出图像的深度,通常设为-1表示与输入图像相同。
  • ksize:滤波器的大小。
  • anchor:锚点位置,默认为(-1, -1),表示核的中心。
  • normalize:是否进行归一化,默认为true。
  • borderType:边界类型,默认为4。

示例代码

cv::Mat src = cv::imread("example.jpg");  
cv::Mat dst;  
cv::boxFilter(src, dst, -1, cv::Size(5, 5));  
cv::imshow("Box Filter", dst);  
cv::waitKey(0);
1.3.2 均值滤波(Blur)

均值滤波与方框滤波类似,但在OpenCV中,cv::blur函数直接提供均值滤波的功能。

函数原型

void cv::blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT)
  • src:输入图像。
  • dst:输出图像。
  • ksize:滤波器的大小。
  • anchor:锚点位置,默认为(-1, -1),表示核的中心。
  • borderType:边界类型,默认为4。

参数与cv::boxFilter类似,但normalize参数在cv::blur中默认为true,因此无需显式指定。

示例代码

cv::Mat src = cv::imread("example.jpg");  
cv::Mat dst;  
cv::blur(src, dst, cv::Size(5, 5));  
cv::imshow("Blur", dst);  
cv::waitKey(0);
1.3.3 高斯滤波(Gaussian Blur)

高斯滤波是一种加权滤波,权重由高斯函数决定,适用于去除高斯噪声。

函数原型

void cv::GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT)
  • src:输入图像。
  • dst:输出图像。
  • ksize:滤波器的大小。
  • sigmaX 和 sigmaY 分别控制X和Y方向上的高斯核标准差。如果sigmaY为0,则与sigmaX相同。
  • borderType:边界类型,默认为4。

示例代码

cv::Mat src = cv::imread("example.jpg");  
cv::Mat dst;  
cv::GaussianBlur(src, dst, cv::Size(5, 5), 1.5);  
cv::imshow("Gaussian Blur", dst);  
cv::waitKey(0);

2. 非线性滤波

2.1 定义

非线性滤波是指对图像进行非线性运算的滤波方法。与线性滤波不同,非线性滤波的输出不是输入像素的线性组合,而是基于某种非线性函数或规则计算得到的。

2.2 特点

  • 非线性运算:对图像中的每个像素点,其输出值不是该点邻域内像素值的线性组合,而是基于某种非线性函数或规则计算得到的。
  • 适应性:非线性滤波通常具有更好的适应性,能够更好地处理图像中的复杂噪声和细节。
  • 边缘保持:非线性滤波在去除噪声的同时,能够更好地保持图像的边缘和细节信息。

2.3 常见类型

2.3.1 中值滤波(Median Filter)

中值滤波是一种非线性滤波技术,用于去除图像中的椒盐噪声。它用邻域内像素值的中值代替中心像素值。

函数原型

void cv::medianBlur(InputArray src, OutputArray dst, int ksize)
  • src:输入图像。
  • dst:输出图像。
  • ksize:滤波器的大小,必须是正奇数。

示例代码

cv::Mat src = cv::imread("example.jpg");  
cv::Mat dst;  
cv::medianBlur(src, dst, 5);  
cv::imshow("Median Filter", dst);  
cv::waitKey(0);
2.3.2 双边滤波(Bilateral Filter)

双边滤波是一种边缘保持滤波技术,同时考虑像素的空间邻近度和像素值相似度。

函数原型

void cv::bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT)

  • src:输入图像。
  • dst:输出图像。
  • d:邻域直径。
  • sigmaColor:颜色空间标准差。
  • sigmaSpace:灰度空间标准差。
  • borderType:边界类型,默认为4。

示例代码

cv::Mat src = cv::imread("example.jpg");  
cv::Mat dst;  
cv::bilateralFilter(src, dst, 9, 75, 75);
cv::imshow("Median Filter", dst);  
cv::waitKey(0);

3. 所有示例

#include <opencv2/opencv.hpp>  
#include <iostream>  

using namespace cv;
using namespace std;

int main() {
    // 读取图像  
    Mat src = imread("C:/Users/Administrator/Desktop/444.jpg");
    if (src.empty()) {
        cout << "Could not open or find the image!" << endl;
        return -1;
    }
    imshow("Original Image", src);  // 显示原始图像

    // 创建输出图像:方框滤波 均值滤波 高斯滤波 中值滤波 双边滤波
    Mat boxdst, blurdst, gaussdst, mediandst, bilaterdst;

    // 方框滤波
    boxFilter(src, boxdst, -1, Size(2, 2), Point(-1, -1), false);   // 默认值可以不用显式指定
    imshow("Box Filter", boxdst);

    // 均值滤波
    blur(src, blurdst, Size(6, 6));
    imshow("Blur Filter", boxdst);

    // 高斯滤波
    GaussianBlur(src, gaussdst, Size(3, 3), 0, 0);
    imshow("Gaussian Filter", gaussdst);

    // 中值滤波
    medianBlur(src, mediandst, 9);  // ksize为奇数
    imshow("Median Filter", mediandst);

    // 双边滤波  
    bilateralFilter(src, bilaterdst, 10, 10, 10);
    imshow("Bilateral Filter", bilaterdst);  
    
    // 等待按键操作  
    waitKey(0);
    return 0;
}

4. 总结

线性滤波和非线性滤波各有优缺点,适用于不同的图像处理场景。线性滤波简单高效,但可能导致图像细节模糊;非线性滤波具有更好的适应性和边缘保持能力,但计算复杂度通常较高。在实际应用中,应根据具体需求选择合适的滤波方法。希望本文能帮助读者更好地理解和使用滤波这项基本且重要的技术,用于改善图像质量、去除噪声、增强边缘等。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐