三种滤波函数及其周边内容

boxFilter, blur, GaussianBlur

Posted by XushengLee on July 31, 2016

D.VA镇_(:зゝ∠)_

传送门lala

图像中的”频率”

首先说说图像频率的物理意义。图像可以看做是一个定义为二维平面上的信号,该信号的幅值对应于像素的灰度(对于彩色图像则是RGB三个分量),如果我们仅仅考虑图像上某一行像素,则可以将之视为一个定义在一维空间上信号,这个信号在形式上与传统的信号处理领域的时变信号是相似的。不过是一个是定义在空间域上的,而另一个是定义在时间域上的。所以图像的频率又称为空间频率,它反映了图像的像素灰度在空间中变化的情况。例如,一面墙壁的图像,由于灰度值分布平坦,其低频成分就较强,而高频成分较弱;而对于国际象棋棋盘或者沟壑纵横的卫星图片这类具有快速空间变化的图像来说,其高频成分会相对较强,低频则较弱(注意,是相对而言)。
图像的频率是一个分布。
将图像做二维傅里叶变换所得的频谱图,也就是图像的梯度分布图即可定义为该图像的频率。
即是直观表现为衡量表征图像中灰度变化剧烈程度的指标。

图像中的”噪声”

噪声对人的影响噪声可以理解为“ 妨碍人们感觉器官对所接收的信源信息理解的因素”。而图像中各种妨碍人们对其信息接受的因素即可称为图像噪声 。噪声在理论上可以定义为“不可预测,只能用概率统计方法来认识的随机误差”。因此将图像噪声看成是多维随机过程是合适的,因而描述噪声的方法完全可以借用随机过程的描述,即用其概率分布函数和概率密度分布函数。

boxFilter函数

C++: void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
1:输入.2:输出.3:输出深度,-1表示用原图的深度.4:Size类型,内核的大小.5:Point类型锚点anchor,默认中心(-1,-1) 6:bool型normalize,默认为true,表示内核是否归一化.7:边界模式.

blur函数

C++: void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT )
blur里面套用的就是boxFilter函数.

Size类型

Size ksize = Size(5,5),内核大小width=5,height=5.

GaussianBlur函数

C++: void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT ) 1:输入.2:输出.3:深度.4:double类型的sigmaX,表示高斯核函数在X方向的的标准偏差.5:double类型的sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。 6:边界模式.
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
大家常常说高斯滤波最有用的滤波操作,虽然它用起来,效率往往不是最高的。
高斯函数,正态分布

代码(有用到trackbar)

#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include"opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

static void on_BoxFilter(int, void *);
static void on_Blur(int, void *);
static void on_GaussianBlur(int,void*);

Mat srcImage,dstImage1,dstImage2,dstImage3;
int initBoxFilterValue = 3, initBlurValue = 3, initGaussianBlurValue = 3;

int main() {

    srcImage = imread("/Users/mac/Pictures/pixiv-dasktop/DVA.jpg");
    if(!srcImage.data){cout<<"imreading srcImage failed";return 0;}
    dstImage1 = srcImage.clone();
    dstImage2 = srcImage.clone();
    dstImage3 = srcImage.clone();

//    namedWindow("boxFilter",1);
//    createTrackbar("core","boxFilter",&initBoxFilterValue,40,on_BoxFilter);
//    imshow("boxFilter", dstImage1);
//    waitKey();
//
//    namedWindow("blur",1);
//    createTrackbar("core","blur",&initBlurValue,40,on_Blur);
//    imshow("blur", dstImage2);
//    waitKey();

    namedWindow("GaussianBlur",1);
    createTrackbar("core","GaussianBlur",&initGaussianBlurValue,40,on_GaussianBlur);
    imshow("GaussianBlur", dstImage1);
    waitKey();

    return 0;
}

static void on_BoxFilter(int, void *){
    boxFilter(srcImage,dstImage1,-1,Size(initBoxFilterValue+1,initBlurValue+1));
    imshow("boxFilter",dstImage1);
}

static void on_Blur(int, void*){
    blur(srcImage,dstImage2,Size(initBlurValue+1,initBlurValue+1));
    imshow("blur", dstImage2);
}

static void on_GaussianBlur(int,void*){
    GaussianBlur(srcImage,dstImage3,
                 Size(initGaussianBlurValue*2+1,initGaussianBlurValue*2+1),0,0);
    //(ksize.width > 0 && ksize.width % 2 == 1 &&
    // ksize.height > 0 && ksize.height % 2 == 1) in createGaussianFilter
    imshow("GaussianBlur", dstImage3);
}