1.medianBlur(中值滤波)

基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,主要是利用中值不受分布序列极大值和极小值影响的特点,让周围的像素值接近真实的值从而消除孤立的噪声点。

中值(又称中位数)是指将统计总体当中的各个变量值按大小顺序排列起来,形成一个数列,处于变量数列中间位置的变量值就称为中位数。

对于图像处理来说,非常适用去除于在不要求图像细节下的椒盐噪声以及脉冲噪声,能够克服线性滤波器带来的图像细节模糊等弊端,能够有效保护图像边缘信息,是非常经典的平滑噪声处理方法。

opencv中提供了medianBlur()函数实现了中值滤波操作,其原型如下:

C++: void medianBlur(InputArray src, OutputArray dst, int ksize)

参数解释:

  • InputArray src: 输入图像。特别注意的是图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。
  • OutputArray dst: 输出图像。尺寸和类型与输入图像一致,可以使用Mat::Clone以原图像为模板来初始化输出图像dst。
  • int ksize: 滤波模板的尺寸大小,必须是大于1的奇数,如3、5、7等

注意:这里的ksize我们可以简单的认为,像CNN卷积核一样,是一个3*3的矩形框,对于原图的每一个像素点,都以该像素点为中心,选取3 * 3尺寸的范围内所有像素点的灰度值取中,来代替该点的灰度值。如下图像处理例子。
原图

1.原图

在这里插入图片描述

2.中值滤波Ksize = 3

在这里插入图片描述

3.中值滤波Ksize = 11

参考代码

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

void median_Blur(){
    cv::Mat src = cv::imread("/home/cheng/Pictures/123456.png", cv::IMREAD_GRAYSCALE);
    cv::Mat dst;
    int median_block_size = 7;

    cv::medianBlur(src, dst, median_block_size);
    

    cv::imshow("median_Blur", dst);
    cv::waitKey(0);

    return;
}


int main(){
    median_Blur();
    return 0;
}

2.boxFilter(方框滤波)

其最主要的作用就是来模糊一张图片(可以部分的消除掉图像出尖锐的边缘点)
个人感觉没啥用,图像变模糊了而已。

opencv中提供了boxFilter()函数实现了方框滤波操作,其原型如下:

void boxFilter(InputArray src, OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1, -1), 
			   boolnormalize=true, int borderType=BORDER_DEPAULT);

参数解释:

  • inputArray类型的src,输入图像。Mat类的对象。该函数对通道是独立处理的,且可以处理任意通道数的图像,但是待处理的图像深度应该是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F。
  • OutputArray类型的dst,输出图像,需要和输入图像有相同的尺寸和类型。
  • int类型的ddepth,输出图像的深度。-1表示使用原图深度,即src.depth。
  • Size类型的lsize,内核的大小。一般用Size(w,h)的写法表示,例如Size(3,3),Size(5,5)。
  • Point类型anchor,表示锚点,即被平滑的那个点,默认值是Point(-1,-1)。如果这个点的坐标是负值的话,就表示取核的中心为锚点。
  • bool类型的normalize,默认值是true,表示内核是否其区域归一化。
  • int类型的borderType,用于推断图像外部像素的某种边界模式,默认值 BORDER_DEFAULT,我们一般不管它。

其中anchor必须小于ksize。
在这里插入图片描述

参考代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
 
using namespace cv;
using namespace std;
 
Mat imageBlur(Mat srcImage);
int main() {
    Mat srcImage = imread("/Users/dwz/Desktop/cpp/1.jpg");
    Mat dstImage;
    boxFilter(srcImage, dstImage, -1, Size(5, 5));
    imwrite("boxblured.jpg", dstImage);
    return 0;
}

3.GaussianBlur(高斯滤波)

高斯滤波是一种线性平滑滤波,对于除去高斯噪声有很好的效果。

高斯算法在官方文档给出的解释是高斯滤波是通过对输入数组的每个点与输入的高斯滤波模板执行卷积计算然后将这些结果一块组成了滤波后的输出数组,通俗的讲就是高斯滤波是对整幅图像进行加权平均的过程,每一个像素点的值都由其本身和邻域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

opencv提供了GaussianBlur()函数对图形进行高斯滤波,其原型如下:

C++: void GaussianBlur(InputArray src, OutputArray dst, Size ksize, 
					   double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )

参数解释:

  • InputArray src: 输入图像,可以是Mat类型,图像深度为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F。
  • OutputArray dst: 输出图像,与输入图像有相同的类型和尺寸。
  • Size ksize: 高斯内核大小,这个尺寸与前面两个滤波kernel尺寸不同,ksize.width和ksize.height可以不相同但是这两个值必须为正数和奇数,如果这两个值为0,他们的值将由sigma计算。
  • double sigmaX: 高斯核函数在X方向上的标准偏差
  • double sigmaY: 高斯核函数在Y方向上的标准偏差,如果sigmaY是0,则函数会自动将sigmaY的值设置为与sigmaX相同的值,如果sigmaX和sigmaY都是0,这两个值将由ksize.width和ksize.height计算而来。 为了结果的正确性最好把Size ksize, double sigmaX, double sigmaY指定出来。
  • int borderType=BORDER_DEFAULT: 推断图像外部像素的某种便捷模式,有默认值BORDER_DEFAULT,如果没有特殊需要不用更改。

参考例子

在这里插入图片描述

1.原图

在这里插入图片描述

2.滤波后

参考代码

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

using namespace std;
using namespace cv;

int main()
{
    cv::namedWindow("Orgin Image", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("Gaussian Blur Image", cv::WINDOW_AUTOSIZE);

    // 读取图像,并用输入的窗口显示输入图像
    cv::Mat img = cv::imread("/home/lena.jpg", -1);
    if (img.empty())
    {
        cout << "Could not load image ..." << endl;
        return -1;
    }
    cv::imshow("Orgin Image", img);

    // 声明输出矩阵
    cv::Mat out;

    // 进行平滑操作,可以使用GaussianBlur()、blur()、medianBlur()或bilateralFilter()
    // 此处共进行了两次模糊操作
    cv::GaussianBlur(img, out, cv::Size(5, 5), 3, 3);
    cv::GaussianBlur(out, out, cv::Size(5, 5), 3, 3);

    // 在输出窗口显示输出图像
    cv::imshow("Gaussian Blur Image", out);
    // 等待键盘事件
    cv::waitKey(0);

    destroyAllWindows();
    
    return 0;
}
Logo

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

更多推荐