【从零学习OpenCV 4】均值滤波
重磅干货,第一时间送达
经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。
我们在测量数据时,往往会多次测量最后求取所有数据的平均值作为最终结果,均值滤波的思想和测量数据时多次测量求取平均值的思想一致。均值滤波将滤波器内所有的像素值都看作中心像素值的测量,将滤波器内所有的像数值的平均值作为滤波器中心处图像像素值。滤波器内的每个数据表示对应的像素在决定中心像素值的过程中所占的权重,由于滤波器内所有的像素值在决定中心像素值的过程中占有相同的权重,因此滤波器内每个数据都相等。均值滤波的优点是在像素值变换趋势一致的情况下,可以将受噪声影响而突然变化的像素值修正到接近周围像素值变化的一致性下。但是这种滤波方式会缩小像素值之间的差距,使得细节信息变得更加模糊,滤波器范围越大,变模糊的效果越明显。
OpenCV 4中提供了blur()函数用于实现图像的均值滤波,该函数的函数原型在代码清单5-8中给出。
代码清单5-8 blur()函数原型
void cv::blur(InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
待均值滤波的图像,图像的数据类型必须是CV_8U、CV_16U、CV_16S、CV_32F和CV_64F这五种数据类型之一。
dst:均值滤波后的图像,与输入图像具有相同的尺寸和数据类型。 ksize:卷积核尺寸。 anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。 borderType:像素外推法选择标志,取值范围在表3-5中给出,默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
该函数的第一个参数为待滤波图像,可以是彩色图像也可以是灰度图像,甚至可以是保存成Mat类型的多维矩阵数据。第二个参数滤波后的图像,保持与输入图像相同的数据类型、尺寸以及通道数。第三个参数是滤波器的尺寸,输入滤波器的尺寸后函数会自动确定滤波器,其形式如式所示。
函数的第四个参数为确定滤波器的基准点,默认状态下滤波器的几何中心就是基准点,不过也可以根据需求自由的调整,在均值滤波中调整基准点的位置主要影响图像外推的方向和外推的尺寸。第五个参数是图像外推方法选择标志,根据需求可以自由的选择。原图像边缘位置滤波计算过程需要使用到外推的像素值,但是这些像素值并不能真实反应图像像素值的变化情况,因此在滤波后的图像里边缘处的信息可能会出现巨大的改变,这属于正常现象。如果在边缘处有比较重要的信息,可以适当缩小滤波器尺寸、选择合适的滤波器基准点或者使用合适的图像外推算法。
为了更加了解均值滤波函数blur()的使用方法以及均值滤波的处理效果,在代码清单5-9中给出了利用不同尺寸的均值滤波器分别处理不含有噪声的图像、含有椒盐噪声的图像和含有高斯噪声的图像,处理结果在图5-10、图5-11、图5-12中给出。通过结果可以发现,滤波器的尺寸越大,滤波后图像变得越模糊。
代码清单5-9 myBlur.cpp图像均值滤波
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat equalLena = imread("equalLena.png", IMREAD_ANYDEPTH);
Mat equalLena_gauss = imread("equalLena_gauss.png", IMREAD_ANYDEPTH);
Mat equalLena_salt = imread("equalLena_salt.png", IMREAD_ANYDEPTH);
if (equalLena.empty() || equalLena_gauss.empty() || equalLena_salt.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat result_3, result_9; //存放不含噪声滤波结果,后面数字代表滤波器尺寸
Mat result_3gauss, result_9gauss; //存放含有高斯噪声滤波结果,后面数字代表滤波器尺寸
Mat result_3salt, result_9salt; //存放含有椒盐噪声滤波结果,后面数字代表滤波器尺寸
//调用均值滤波函数blur()进行滤波
blur(equalLena, result_3, Size(3, 3));
blur(equalLena, result_9, Size(9, 9));
blur(equalLena_gauss, result_3gauss, Size(3, 3));
blur(equalLena_gauss, result_9gauss, Size(9, 9));
blur(equalLena_salt, result_3salt, Size(3, 3));
blur(equalLena_salt, result_9salt, Size(9, 9));
//显示不含噪声图像
imshow("equalLena ", equalLena);
imshow("result_3", result_3);
imshow("result_9", result_9);
//显示含有高斯噪声图像
imshow("equalLena_gauss", equalLena_gauss);
imshow("result_3gauss", result_3gauss);
imshow("result_9gauss", result_9gauss);
//显示含有椒盐噪声图像
imshow("equalLena_salt", equalLena_salt);
imshow("result_3salt", result_3salt);
imshow("result_9salt", result_9salt);
waitKey(0);
return 0;
}
图5-10 myBlur.cpp程序中不含噪声图像均值滤波结果
图5-12 myBlur.cpp程序中含高斯噪声图像均值滤波结果