打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
图像处理基本算法

线性滤波器的向量表示:





W是一个大小为m*n的滤波器的系数,Z为由滤波器覆盖的相应图像的灰度值。


线性滤波器所能是实现的就是乘积求和操作。


几种常见的滤波器:


平滑空间滤波器如均值滤波


统计排序滤波器如中值滤波


锐化空间滤波器如锐化滤波


 


1、  均值滤波


 


 


均值滤波在去噪声的同时会有如下缺点:


边界模糊效应明显


细节丢失比较严重


 


2、  中值滤波





中值滤波在边界的保存方面优于均值滤波,是经常使用的一种滤波器,但


是在模板逐渐变大时,依然会存在一定的边界模糊


中值滤波对处理椒盐噪声非常有效,或者称为脉冲噪声。


 


如果既想去除噪声,又极大的保存细节,此时应该考虑变形虫算法模板的大小是与周围的像素有关,模板随环境自动变化大小,这样在细节较小的区域可以使用较大的模板,而在细节较多的区域使用更小的模板。变形虫算法,以后再讲。


滤波器一般为盒状滤波器,能不能使用其他形状的滤波器,以得到更好的滤波效果呢?


 源代码:


  1. //中值滤波和均值滤波  
  2. #include<cv.h>  
  3. #include<highgui.h>  
  4.   
  5. int main(){  
  6.     IplImage * image,*image2,*image3;  
  7.     image = cvLoadImage("E:\\image\\Dart.bmp",0);//以灰度图像的形式读入图片  
  8.     cvNamedWindow("image",CV_WINDOW_AUTOSIZE);  
  9.     cvNamedWindow("image2",CV_WINDOW_AUTOSIZE);  
  10.     cvNamedWindow("image3",CV_WINDOW_AUTOSIZE);  
  11.     //cvSaveImage("E:\\image\\moon.jpg",image,0);  
  12.     cvShowImage("image",image);  
  13.     //cvWaitKey(0);  
  14.     unsigned char * ptr,*dst;  
  15.     int i,j,m,n,sum,temp,r,s;  
  16.     image2 = cvCreateImage(cvGetSize(image),image->depth,1);  
  17.     image3 = cvCreateImage(cvGetSize(image),image->depth,1);  
  18.     //模板1 均值   
  19.     int tem[9] = {1,1,1,1,1,1,1,1,1};   
  20.     //也可以使用改进的高斯模板,但是效果相近   
  21.     int tem2[9] = {0};//获取中值时用于排序  
  22.   
  23.     //均值滤波3*3模板的均值  
  24.     for( i = 0 ; i < image->height;i++){  
  25.         for( j = 0; j< image->width;j++){  
  26.               
  27.             //边界处理  
  28.             if(i == 0 || i == image->height || j == 0 || j == image->width){  
  29.                 ptr = (unsigned char *)image->imageData + i*image->widthStep + j;  
  30.                 dst = (unsigned char *)image2->imageData+ i*image2->widthStep+ j;  
  31.                 *dst = *ptr; //边界值赋予源图像的值  
  32.             }  
  33.             else {  
  34.                 sum = 0;  
  35.                 for( m = -1 ; m <= 1; m++  ){  
  36.                     for( n = -1 ; n <= 1 ; n++){  
  37.                         ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;  
  38.                           
  39.                         sum += (*ptr) * tem[3*(m+1) + n+1];  
  40.                     }  
  41.                 }  
  42.                 dst = (unsigned char *)image2->imageData+ i *image2->widthStep+ j;      
  43.                 *dst = (unsigned char)((sum +4)/9);//赋新值,四舍五入  
  44.             }   
  45.           
  46.         }  
  47.     }  
  48. //中值滤波 在去除噪声的同时,图像的模糊程度比较小,比均值滤波更加适合  
  49. //冲击噪声或者称为椒盐噪声  
  50.     for( i = 0 ; i < image->height;i++){  
  51.         for( j = 0; j< image->width;j++){  
  52.   
  53.             //边界处理  
  54.             if(i == 0 || i == image->height || j == 0 || j == image->width){  
  55.                 ptr = (unsigned char *)image->imageData + i*image->widthStep + j;  
  56.                 dst = (unsigned char *)image3->imageData+ i*image3->widthStep+ j;  
  57.                 *dst = *ptr; //边界值赋予源图像的值  
  58.             }  
  59.             else {  
  60.                 temp = 0;  
  61.                 //将3*3模板覆盖的值拷贝进数组,一边查找中值  
  62.                 for( m = -1 ; m <= 1; m++  ){  
  63.                     for( n = -1 ; n <= 1 ; n++){  
  64.                         ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;  
  65.                         tem2[3*(m+1) +n +1] = *ptr;  
  66.                         //printf("%d",*ptr);  
  67.                       
  68.                     }  
  69.                 }  
  70.                 //对数组进行冒泡排序  
  71.                 for(r = 0 ; r <8; r ++){  
  72.                     for(s = 0 ; s< r -1; s++ ){  
  73.                         if(tem2[s] > tem2[s+1]){  
  74.                             temp = tem2[s];  
  75.                             tem2[s] = tem2[s+1];  
  76.                             tem2[s+1] = temp;  
  77.                         }  
  78.                     }  
  79.                 }  
  80.                 //printf("%d",tem2[4]);  
  81.                 //对新图赋予新值  
  82.                 dst = (unsigned char *)image3->imageData+ i *image3->widthStep+ j;      
  83.                 *dst = (unsigned char)(tem2[4]);//赋新值  
  84.             }   
  85.   
  86.         }  
  87.     }  
  88.   
  89.     cvShowImage("image2",image2);  
  90.     cvShowImage("image3",image3);  
  91.     cvWaitKey(0);  
  92.     cvSaveImage("E:\\image\\Dart2.bmp",image2,0);  
  93.     cvSaveImage("E:\\image\\Dart3.bmp",image3,0);  
  94.     return 0;  
  95. }  
效果图:


原图:




均值滤波:





中值滤波:


 


可以看到,均值滤波缺点明显:



边界模糊效应明显


细节丢失比较严重


而中值滤波在保持细节方面明显优于均值滤波。


在滤波模板变大时,效果如何呢?


matlab源码:


  1. A = imread('Dart.bmp')  
  2.   
  3. %采用中值滤波和均值滤波的比较  
  4. %模板大小的改变对滤波效果的影响  
  5. subplot(3,3,1)  
  6. imshow(A)  
  7. for n = 1 : 8   
  8.     m = 2*n +1  
  9.  B = medfilt2(A ,[m,m])  
  10.  subplot(3,3,n+1)  
  11.  imshow(B)  
  12.    
  13. end  
  14.   
  15. %采用均值滤波查看图像的变化  
  16. subplot(3,3,1)  
  17. imshow(A)  
  18. for n = 1 : 8   
  19.     m = 2*n +1  
  20.  C = imfilter(A,[m,m]);  
  21.  subplot(3,3,n+1)  
  22.  imshow(B)  
  23. end  
效果图:


均值滤波加大模板的效果:




中值滤波加大模板的效果:





可以看出随着模板的加大,中值滤波的模糊度也在增加,但是比均值要好很多。


3、Laplace图像锐化


锐化空间滤波器的一阶二阶微分的零交叉对于边缘定位非常有用


图像的边缘经一阶微分产生较粗的边缘


二阶微分产生由0分开的一个双边缘,这是一个适合锐化图像的理想特征。


锐化laplace算子可以突出图像中的灰度突变,但并不强调灰度缓慢变化的区域。


两种常用的Laplace模板:


0  1  0


1  -4 1


0  1  0


 


1 1 1


1 -8 1


1 1 1


 


但是得到突变的区域之后该怎么用呢?


事实上,如果源图像和laplace图像和叠加,这样既可以复原原图的背景特性,并保持laplace锐化处理的效果。这样做可以极大的增强图像的细节。


源代码:


  1. //锐化滤波,并利用锐化滤波增强图像的细节  
  2. #include<cv.h>  
  3. #include<highgui.h>  
  4.   
  5. int main(){  
  6.     IplImage * image,*image2,*image3;  
  7.     image = cvLoadImage("E:\\image\\moon.tif",0);  
  8.     cvNamedWindow("image",CV_WINDOW_AUTOSIZE);  
  9.     cvNamedWindow("image2",CV_WINDOW_AUTOSIZE);  
  10.     cvNamedWindow("image3",CV_WINDOW_AUTOSIZE);  
  11.     cvSaveImage("E:\\image\\moon.jpg",image,0);  
  12.     cvShowImage("image",image);  
  13.     //cvWaitKey(0);  
  14.     unsigned char * ptr,*dst;  
  15.     image2 = cvCreateImage(cvGetSize(image),image->depth,1);  
  16.     image3 = cvCreateImage(cvGetSize(image),image->depth,1);  
  17.       
  18.       
  19.     int i,j,m,n,sum;  
  20.   
  21.     //锐化模板  
  22.     int tem[9] = {0,1,0,1,-4,1,0,1,0};   
  23.   
  24.     //锐化滤波  
  25.     for( i = 0 ; i < image->height;i++){  
  26.         for( j = 0; j< image->width;j++){  
  27.   
  28.             //边界处理  
  29.             if(i == 0 || i == image->height || j == 0 || j == image->width){  
  30.                 ptr = (unsigned char *)image->imageData + i*image->widthStep + j;  
  31.                 dst = (unsigned char *)image2->imageData+ i*image2->widthStep+ j;  
  32.                 *dst = *ptr; //边界值赋予源图像的值  
  33.             }  
  34.             else {  
  35.                 sum = 0;  
  36.                 for( m = -1 ; m <= 1; m++  ){  
  37.                     for( n = -1 ; n <= 1 ; n++){  
  38.                         ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;  
  39.   
  40.                         sum += (*ptr) * tem[3*(m+1) + n+1];  
  41.                     }  
  42.                 }  
  43.                 dst = (unsigned char *)image2->imageData+ i *image2->widthStep+ j;      
  44.                 *dst = (unsigned char)((sum +4)/9);//赋新值,四舍五入  
  45.             }   
  46.   
  47.         }  
  48.     }  
  49.   
  50.     //锐化的图像与源图像相加,但是在相加之前需要先讲锐化的值稍微降低一些  
  51.       
  52.       
  53.     cvShowImage("image2",image2);  
  54.   
  55.     for( i = 0 ; i < image2->height;i++){  
  56.         for( j = 0; j< image->width;j++){  
  57.             ptr = (unsigned char *)image2->imageData + i*image2->widthStep + j;   
  58.             *ptr = ((*ptr)+4)/5;  
  59.         }  
  60.     }  
  61.     cvAdd(image,image2,image3,0);  
  62.     cvShowImage("image3",image3);  
  63.       
  64.     cvWaitKey(0);  
  65.     cvSaveImage("E:\\image\\moon2.jpg",image2,0);  
  66.     cvSaveImage("E:\\image\\moon3.jpg",image3,0);  
  67.     return 0;  
  68. }  
原图:



锐化图像:



叠加图像:



由叠加图像可知,经过锐化处理和叠加之后,图像的细节部分更加清晰。



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
IplImage结构体
OpenCv,EmguCv及.net之间的互动(The Interaction of OpenCv, EmguCv AND .net)
将指针下的图片传给opencv进行处理。
LevelDB源码剖析之Varint | 赖明星
DNS协议 报文格式
【技巧】C中Union的巧妙用法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服