1.图像滤波也叫图像模糊,是平滑图像像素常用处理的方式,通常是为了达到减少图像噪声和伪影,或者降低图像分辨率,OpenCV提供了常用的五种图像模糊操作。
2.我的这里演示的系统环境是Linux,IDE是Qt creator,OpenCV的版本是3.30。
1.简单模糊
(1)blur()是实现简单模糊,是最常用的一种图像模糊方式,目标图像中的每个值都是源图像相应位置一个窗口中像素的平均值。
函数原型:
void blur(InputArray src,OutputArray,dst,Size ksize,Point anchor=Point(-1,-1),int borderType=BORDER_DEFAULT)
参数说明:
InputArray类型的src,输入图像,就是要模糊的图像,写Mat类对象即可,该函数对通道是独立处理的,且可以处理任意通道数的图片,处理图片深度应该是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F之一;
OutputArray类型的dst,输出图像,需要和原图像有一样的尺寸和类型;比如可以用Mat::clone(()或者copyTo()得到,以源图片为模板来初始目标图;
Size类型的ksize,内核的大小,一般用Size(w,h)的写法来表示内核的大小,例如Size(3,3)就是3×3的核大小,核的大小一般为(3X3),(5X5)等奇数;
Point类型的anchor,表示锚点(即被平滑的那个点),注意有默认值Point(-1,-1),如果这个点坐标是负值的话就表示取核中心为锚点;
int类型的borderType,用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT,一般不去管它。
(2)代码演示
void simpleBlur(Mat &src, Mat &dst, int kesize)
{
if(src.empty())
{
return;
}
blur(src,dst,Size(kesize,kesize));
string str = to_string(kesize) + "X" + to_string(kesize);
//在效果上加文字,对比几种核的效果
putText(dst,str,Point(50,60),FONT_HERSHEY_SIMPLEX,2,Scalar(255,23,0),4,8);
}
(3)图像结果,可以看到几个核计大小的效果
2.中值滤波
(1)中值滤波是将目标图像每个像素的都替换为围绕这个像素的矩形领域内的平均像素。常用于去掉数字图像中的拍摄噪声。
API
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(()或者copyTo()得到,以源图片为模板来初始目标图;
Size类型的ksize,内核的大小,一般用Size(w,h)的写法来表示内核的大小,例如Size(3,3)就是3×3的核大小,核的大小一般为(3X3),(5X5)等奇数;
代码演示:
void myMedianBlur(Mat &src, Mat &dst, int kesize)
{
if(src.empty())
{
return;
}
medianBlur(src,dst,kesize);
string str = to_string(kesize);
putText(dst,str,Point(50,60),FONT_HERSHEY_SIMPLEX,2,Scalar(255,23,0),4,8);
}
运行效果,可以看到几个核大小的效果:
3.高斯滤波
(1)高斯滤波是通过对输入数组的每个点与输入的高斯滤波模板执行卷积计算然后将这些结果一块组成了滤波后的输出数组。
API:
void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, intborderType=BORDER_DEFAULT )
参数说明:
InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,来初始化得到如假包换的目标图。
Size类型的ksize高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数。或者,它们可以是零的,它们都是由sigma计算而来。
double类型的sigmaX,表示高斯核函数在X方向的的标准偏差。
double类型的sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
(2)代码演示
void myGaussianBlur(Mat &src, Mat &dst, int kesize)
{
if(src.empty())
{
return;
}
GaussianBlur(src, dst, Size(kesize, kesize), 11, 11, 4);
string str = to_string(kesize) + "X" + to_string(kesize);
putText(dst,str,Point(50,60),FONT_HERSHEY_SIMPLEX,2,Scalar(255,23,0),4,8);
}
运行结果:
4.双边滤波
(1)双边滤波模板主要有两个模板生成,第一个是高斯模板,第二个是以灰度级的差值作为函数系数生成的模板,然后这两个模板点乘就得到了最终的双边滤波模板,第一个模板是全局模板,所以只需要生成以西,第二个模板需要对每个像素都计算一次。双边滤波器比高斯滤波器多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素,这样就能对边缘附近的像素值予以保存,但是由于保存过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤除。
API:
C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )
参数说明:
InputArray src: 输入图像,Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
OutputArray dst: 输出图像,和原图像有相同的尺寸和类型。
int d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
double sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.
代码演示:
oid myBilateralFilter(Mat &src, Mat &dst)
{
if(src.empty())
{
return;
}
bilateralFilter(src, dst, 25, 25*2, 35);
}