中值滤波就是用滤波器范围内所有像素值的中值来替代滤波器中心位置像素值的滤波方法,是一种基于排序统计理论的能够有效抑制噪声的非线性信号处理方法。中值滤波计算方式如图5-21所示,将滤波器范围内所有的像素值按照由小到大的顺序排列,选取排序序列的中值作为滤波器中心处黄色像素的新像素值,之后将滤波器移动到下一个位置,重复进行排序取中值的操作,直到将图像所有的像素点都被滤波器中心对应一遍。中值滤波不依赖于滤波器内那些与典型值差别很大的值,因此对斑点噪声和椒盐噪声的处理具有较好的处理效果。
相比于均值滤波,中值滤波对于脉冲干扰信号和图像扫描噪声的处理效果更佳,同时在一定条件下中值滤波对图像的边缘信息保护效果更佳,可以避免图像细节的模糊,但是当中值滤波尺寸变大之后同样会产生图像模糊的效果。在处理时间上,中值滤波所消耗的时间要远大于均值滤波消耗的时间。
图5-21 中值滤波计算过程示意图
OpenCV 4提供了对图像进行中值滤波操作的medianBlur()函数,该函数的函数原型在代码清单5-18中给出。
代码语言:javascript复制代码清单5-18 medianBlur()函数原型
void cv::medianBlur(InputArray src,
OutputArray dst,
int ksize
)
- src:待中值滤波的图像,可以是单通道,三通道和四通道,数据类型与滤波器的尺寸相关,当滤波器尺寸为3或5时,图像可以是CV_8U,CV_16U或CV_32F类型,对于较大尺寸的滤波器,数据类型只能是CV_8U。
- dst:输出图像,与输入图像src具有相同的尺寸和数据类型。
- ksize:滤波器尺寸,必须是大于1的奇数,例如:3、5、7……
该函数只能处理符合图像信息的Mat类数据,2通道或者更多通道的Mat类矩阵不能被该函数处理,并且对于图像数据类型的要求也和滤波器的尺寸有着密切的关系。函数第一个参数是待中值滤波的图像,可以是单通道,三通道和四通道,数据类型与滤波器的尺寸相关。当滤波器尺寸为3或5时,图像可以是CV_8U,CV_16U或CV_32F类型,对于较大尺寸的滤波器,数据类型只能是CV_8U。第二个参数是输出图像,输出图像的尺寸和数据类型与输入图像相同。最后一个参数是滤波其的尺寸,区别于之前的线性滤波,中值滤波的滤波器必须是正方形且尺寸为大于1的奇数。该函数对于多通道的彩色图像是针对每个通道的内部数据进行中值滤波操作。
为了了解中值滤波函数medianBlur()的使用方法,在代码清单5-19中给出了对含有椒盐噪声的灰度图像和彩色图像进行中值滤波的示例程序,程序中分别用3×3和9×9的滤波器对图像进行中值滤波,程序的运行结果在图5-22、图5-23给出,通过结果可以看出,9×9的中值滤波同样会对整个图像造成模糊的现象。
代码语言:javascript复制 代码清单5-19 myMedianBlur.cpp中值滤波
#include <opencv2opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat gray = imread("equalLena_salt.png", IMREAD_ANYCOLOR);
Mat img = imread("lena_salt.png", IMREAD_ANYCOLOR);
if (gray.empty() || img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat imgResult3, grayResult3, imgResult9, grayResult9;
//分别对含有椒盐噪声的彩色和灰度图像进行滤波,滤波模板为3×3
medianBlur(img, imgResult3, 3);
medianBlur(gray, grayResult3, 3);
//加大滤波模板,图像滤波结果会变模糊
medianBlur(img, imgResult9, 9);
medianBlur(gray, grayResult9, 9);
//显示滤波处理结果
imshow("img", img);
imshow("gray", gray);
imshow("imgResult3", imgResult3);
imshow("grayResult3", grayResult3);
imshow("imgResult9", imgResult9);
imshow("grayResult9", grayResult9);
waitKey(0);
return 0;
}
图5-21 中值滤波计算过程示意图
图5-21 中值滤波计算过程示意图