参考文献:数字图像处理(第三版)(第四版) 美Rafael,C.,Gonzalez(拉斐尔,C.,冈萨雷斯) 著
及众多网上博客,教程等
线性滤波与非线性滤波的区别参考博客:https://blog.csdn.net/zqx951102/article/details/82967360
全代码地址:https://mp.csdn.net/postedit/100053767
中值滤波属于非线性滤波的一种。它是拿领域的中值来代替像素中心的值。这个好处就是把最大值没有什么贡献,最小值也没有什么贡献,只看中间值,去除椒盐噪声那些比较好。从C++的角度,既然是中值那就是排序呗。我推荐使用冒泡排序,所有的nlogn的排序方法,在n小的时候都不如n^2的排序。而冒泡排序你不用全部排完。你只要冒到中间值就行。具体代码如下(你还是要注意RGB是三个通道的)。
void Bmp::produce_median_filter_bmp_file(const int kernel_side_length)
{
string median_filter_file_name;
byte ***pixel_zero;
int *red_pixel_sort_temp;
int *green_pixel_sort_temp;
int *blue_pixel_sort_temp;
int kernel_size=kernel_side_length*kernel_side_length;//内核总大小(长度)
red_pixel_sort_temp=new int[kernel_size];
green_pixel_sort_temp=new int[kernel_size];
blue_pixel_sort_temp=new int[kernel_size];
for(int i=0;i<file_name.length()-4;++i)
{
median_filter_file_name+=file_name[i];
}
median_filter_file_name+="_median_filter.bmp";
pixel_zero=new byte**[heigth+kernel_side_length-1];
for(int i=0;i< heigth+kernel_side_length-1;++i)
pixel_zero[i]=new byte*[width+kernel_side_length-1];
for(int i=0;i< heigth+kernel_side_length-1;++i)
for(int j=0;j< width+kernel_side_length-1;++j)
pixel_zero[i][j]=new byte[byte_count];//为补0像素申请空间
supply_zero(pixel_zero,kernel_side_length);//填充0
for(int i=0;i<heigth;++i)
for (int j = 0; j < width;++j)
{
for(int m=0;m<kernel_side_length;++m)
{
for(int n=0;n<kernel_side_length;++n)
{
red_pixel_sort_temp[m*kernel_side_length+n]=pixel_zero[i+m][j+n][0];
green_pixel_sort_temp[m*kernel_side_length+n]=pixel_zero[i+m][j+n][1];
blue_pixel_sort_temp[m*kernel_side_length+n]=pixel_zero[i+m][j+n][2];
}//将临界矩阵元素值取出
}
//if(i==21&&j==21)
for(int m=0;m<(kernel_size/2+1);++m)//因为只需要找出中值,所以并不需要冒泡排序完所有元素
for(int n=m+1;n<kernel_size;++n)
{
if(red_pixel_sort_temp[n]>red_pixel_sort_temp[m])
swap(red_pixel_sort_temp[n],red_pixel_sort_temp[m]);
if(green_pixel_sort_temp[n]>green_pixel_sort_temp[m])
swap(green_pixel_sort_temp[n],green_pixel_sort_temp[m]);
if(blue_pixel_sort_temp[n]>blue_pixel_sort_temp[m])
swap(blue_pixel_sort_temp[n],blue_pixel_sort_temp[m]);
}
pixel_temp[i][j][0]=red_pixel_sort_temp[kernel_size/2];
pixel_temp[i][j][1]=green_pixel_sort_temp[kernel_size/2];
pixel_temp[i][j][2]=blue_pixel_sort_temp[kernel_size/2];
}
produce_bmp_file(pixel_temp,width,heigth,byte_count,median_filter_file_name);
for(int i=0;i< heigth+kernel_side_length-1;++i)
for(int j=0;j< width+kernel_side_length-1;++j)
delete []pixel_zero[i][j];
for(int i=0;i< heigth+kernel_side_length-1;++i)
delete []pixel_zero[i];
delete []pixel_zero;//删除补0像素申请空间
delete []red_pixel_sort_temp;
delete []green_pixel_sort_temp;
delete []blue_pixel_sort_temp;
}
展示
原图像
3x3中值滤波后