博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
灰度图像-图像增强 中值滤波
阅读量:2379 次
发布时间:2019-05-10

本文共 4798 字,大约阅读时间需要 15 分钟。

中值滤波介绍

中值滤波时典型的非线性方法,与前面介绍的方法不同,中值滤波更接近于灰度图像的腐蚀和膨胀,是在一定区域内比较大小,找出中值,也就是排序后中间那个数,也就是中学的中位数,平均数用于均值滤波,中位数用于中值滤波,要是专家就可以写本书:统计学在图像处理中的二三事(这句话属于扯淡)。

中值滤波会产生对原始图像的人为因素破坏,所以在医疗成像等对人为因素引起误差不能够接受的时候不能是用中值滤波。
中值滤波对椒盐噪声和斑点噪声效果显著,而且中值滤波具有较好的边缘保持特性,所以在图像处理中知名度很高。

数学原理

中值滤波的数学公式就是:

g(x,y)=Median{
f(xm/2,yn/2)f(x+m/2,y+n/2)}
g(x,y)=Median{f(x−m/2,y−n/2)…f(x+m/2,y+n/2)}
翻译成自然语言就是在当前模板覆盖范围内需找中位数作为结果。
此计算中涉及到排序,所以,如果使用比较的方法排序,最快速度的复杂度是 
O(m×n×log(m×n)×W×H)O(m×n×log(m×n)×W×H) ,如果使用非比较型排序,算法最大时间复杂度是 
255×W×H255×W×H 也就是 
O(W×H)O(W×H) 但要使用更多的存储空间,最直观的方法是使用计数排序,建立一个255大小的空间,或者理解为一个直方图,来查找中值。
快速方法是使用计数排序,但存在一个类似于游标的指针,指向当前的中值,并记录当前模板覆盖范围内小于中值的数据的个数,当模板滑动的时候,观察移出数据和移入数据对小于中值个数的影响确定移动游标的方向,以此来减少直方图搜索范围,降低运算量。

快速算法

  1. 初始化 T=/2T=模板覆盖区域元素个数/2
  2. 首先,初始化直方图,将该行第一组模板覆盖的元素排序,找出中值 mid_value ,记录小于此中值的元素个数c。
  3. 移出模板覆盖区域最左侧一列元素,对于每一个元素如果小于 mid_value ,c=c1c=c−1 ;
  4. 移入模板覆盖外最右侧一列元素(相当于模板右移), 对于每一个元素如果小于 mid_value ,c=c+1c=c+1 ;
  5. 比较c和T的大小:
    • 如果 c<Tc<T :从 mid_value 开始,包括mid_value,向更大的方向检索,如果有搜索到元素,c加上对应的个数,直到 cTc≥T ,当前元素为新的 mid_value;
    • 如果 c==Tc==T :从mid_value开始,包括mid_value,向更大的方向检索,如果有搜索到元素,该元素为新的mid_value;
    • 如果 c>Tc>T :从mid_value开始,包括mid_value,向更小的方向检索,如果有搜索到元素,c减去对应的个数,直到c<=T,当前元素为新的mid_value,c的值加上新mid_value的个数;
  6. 如果模板右边无数据,到下一行,回到第2步否则回到第3步,继续;

    原型算法代码

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
//以下为低速普通中值滤波,排序使用计数排序 void initHist(int *hist,int size){
for(int i=0;i
size/2) return i; } return 0;}void MedianFilter(IplImage *src,IplImage *dst,int width,int height){
IplImage* temp=cvCreateImage(cvSize(src->width+width, src->height+height), src->depth, src->nChannels); IplImage* dsttemp=cvCreateImage(cvSize(src->width+width, src->height+height), src->depth, src->nChannels); cvZero(temp); for(int j=0;j
height;j++){
for(int i=0;i
width;i++){
double value=cvGetReal2D(src, j, i); cvSetReal2D(temp, j+height/2, i+width/2, value); } } int *window=(int *)malloc(sizeof(int)*width*height); if(window==NULL){
printf(" "); exit(0); } for(int j=height/2;j
height-height/2-1;j++){
for(int i=width/2;i
width-width/2-1;i++){
for(int n=-height/2;n
height-height/2-1;j++){ for(int i=width/2;i
width-width/2-1;i++){ double value=cvGetReal2D(dsttemp, j, i); cvSetReal2D(dst, j-height/2, i-width/2, value); } } free(window);}

快速算法代码

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
int findMedian(int *hist,int *movein,int *moveout,int movesize,int *cursor,int median,int t){
for(int i=0;i
=t+1){
(*cursor)-=hist[i]; return i; } } }else if((*cursor)>t){
for(int i=median-1;i>=0;i--){
(*cursor)-=hist[i]; if(*cursor<=t){
return i; } } } else if ((*cursor)==t){
for(int i=median;i
0) return i; } } return -1;}//初始化一行int InitRow(IplImage *src,int *hist,int row,int *cursor,int win_width,int win_height){
int t=win_width*win_height/2+1; *cursor=0; for(int i=0;i
=t){
*cursor-=hist[i]; return i; } } return -1;}void MedianFilter(IplImage *src,IplImage *dst,int width,int height){
int hist[GRAY_LEVEL]; int median; int *movein=(int *)malloc(sizeof(int)*height); int *moveout=(int *)malloc(sizeof(int)*height); double *dsttemp=(double *)malloc(sizeof(double)*src->width*src->height); int t=width*height/2; for(int j=height/2;j
height-height/2-1;j++){
int cursor=0; median=InitRow(src, hist, j, &cursor, width, height); dsttemp[j*src->width+width/2]=median; for(int i=width/2+1;i
width-width/2-1;i++){
for(int k=-height/2;k
width+i]=median; } } for(int j=0;j
height;j++){ for(int i=0;i
width;i++){ cvSetReal2D(dst, j, i, dsttemp[j*src->width+i]); } } free(dsttemp); free(movein); free(moveout);}

效果

来观察下lena图矩阵原版的中值滤波结果:

原图数据:
Center
我们的慢速结果:
Center 1
我们的快速结果:
Center 2
OpenCV的结果:
Center 3
下面看加了椒盐噪声的lena图的中值滤波和高斯滤波的效果:
Center 4
3x3中值:
Center 5
3x3高斯:
Center 6
5x5中值:
Center 7
5x5高斯:
Center 8
7x7中值:
Center 9
7x7高斯:
Center 10
观察结果:对于椒盐噪声影响严重的图片,中值滤波效果远远好于高斯滤波,中值滤波的模板越大图像被模糊的越严重

https://www.tony4ai.com/DIP-5-4%E7%81%B0%E5%BA%A6%E5%9B%BE%E5%83%8F-%E5%9B%BE%E5%83%8F%E5%A2%9E%E5%BC%BA-%E4%B8%AD%E5%80%BC%E6%BB%A4%E6%B3%A2/

转载地址:http://xgqxb.baihongyu.com/

你可能感兴趣的文章
VS 2005中毒后编译出现的错误及其解决过程
查看>>
周国平:教育的七条箴言
查看>>
应用程序初始化失败问题的解决
查看>>
开启Windows 7远程桌面功能的做法
查看>>
有关error PRJ0003错误的思考
查看>>
韩少功:怎么赚钱
查看>>
如何煮鸡粥
查看>>
实现自定义对话框程序快捷键的两种方法
查看>>
如何对抗微软霸权,google给我们上了一课
查看>>
未能将基于用户的Visual C++项目设置保存到user文件错误的解决
查看>>
获取windows版本信息的做法
查看>>
打开文件对话框在xp和win7上的实现文件任意多选
查看>>
略谈如何创建一个监控线程
查看>>
苯事两则
查看>>
批处理实现添加java环境变量
查看>>
关于sizeof运算符的一些理解
查看>>
比你更自信,比你更勇敢
查看>>
关于jacob支持BSTR类型的经验总结
查看>>
对Jscript操作注册表接口的一点不解
查看>>
开发一个软件平台的一些心得体会
查看>>