opencv中有多种滤波方法实现图像平滑,线性滤波包括方框、均值、高斯。非线性滤波有:中值、双边滤波。
线性滤波:像素的输出值取决于输入像素的加权求和
线性滤波其原始数据与滤波结果是一种算术运算,即用加减乘除等运算实现,如均值滤波(模板内像素灰度值的平均值)、高斯滤波(高斯加权平均值)等。由于线性滤波是算术运算,有固定的模板。
非线性滤波:其算子中包含了非线性算子
非线性滤波的原始数据与滤波结果是一种逻辑关系,即用逻辑运算实现,如最大值滤波器、最小值滤波器、中值滤波器等,是通过比较一定邻域内的灰度值大小来实现的,没有固定的模板。
滤波和模糊、锐化的区别
以高斯滤波为例,
高斯滤波是指用高斯函数作为滤波函数的滤波操作。高斯模糊就是高斯低通滤波。高斯锐化就是高斯高通滤波。
卷积:左边图像与中间图像卷积产生右边图像
图片源于:https://summitgao.github.io/new/opencv/lesson5.html
其中f 表示输入像素值,h表示加权系统"核",g表示输出像素。
函数原型分析及对应实现
//方框滤波
boxFilter( InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor=Point(-1,-1),
bool normalize=true,
int borderType=BORDER_DEFAULT );boxFilter(srcImage,dstImage1,-1,Size(nBoxFilterValue + 1,nBoxFilterValue + 1));
int类型的ddepth,输出图像的深度,-1表示使用原图深度,即src.depth()
Size类型的ksize ,表示内核大小,一般写成Size(w,h),例如Size(3,3)表示3x3的核大小
//均值滤波
输出图像的每一个像素是核窗口内输入图像对应像素的像素的平均值( 所有像素加权系数相等)。主要方法为邻域平均法,例如中心像素,周围8邻域为其模板(内核),邻域像素平均值作为中间像素值
vid blur( InputArray src, OutputArray dst,
Size ksize, Point anchor=Point(-1,-1),
int borderType=BORDER_DEFAULT );
//高斯滤波
广泛应用于图像处理的减噪过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。可参考博主@ MingChaoSun
void GaussianBlur( InputArray src,
OutputArray dst, Size ksize,
double sigmaX, double sigmaY=0,
int borderType=BORDER_DEFAULT );
//中值滤波
用像素点邻域灰度值的中值来代替该像素点的灰度值。
void medianBlur( InputArray src, OutputArray dst, int ksize );
与均值滤波对比发现,具体过程类似,一个取邻域均值(去掉目标像素本身),一个取邻域中值(包括目标像素本身)。
中值滤波优势: 消除噪声以及保存边缘
均值滤波优势:耗时只需中值滤波的1/5。
//双边滤波
void bilateralFilter( InputArray src, OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType=BORDER_DEFAULT );int类型的d,表示在过滤过程中每个像素邻域的直径
nBilateralFilterValue=50;
bilateralFilter(srcImage,dstImage5,nBilateralFilterValue,nBilateralFilterValue*2,nBilateralFilterValue/2);