zoukankan      html  css  js  c++  java
  • 图像处理基本算法滤波

    线性滤波器的向量表示:


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

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

    几种常见的滤波器:

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

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

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

    1、  均值滤波

     

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

    边界模糊效应明显

    细节丢失比较严重

    2、  中值滤波


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

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

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

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

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

     源代码:

    //中值滤波和均值滤波
    #include<cv.h>
    #include<highgui.h>
    
    int main(){
    	IplImage * image,*image2,*image3;
    	image = cvLoadImage("E:\\image\\Dart.bmp",0);//以灰度图像的形式读入图片
    	cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("image2",CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("image3",CV_WINDOW_AUTOSIZE);
    	//cvSaveImage("E:\\image\\moon.jpg",image,0);
    	cvShowImage("image",image);
    	//cvWaitKey(0);
    	unsigned char * ptr,*dst;
    	int i,j,m,n,sum,temp,r,s;
    	image2 = cvCreateImage(cvGetSize(image),image->depth,1);
    	image3 = cvCreateImage(cvGetSize(image),image->depth,1);
    	//模板1 均值 
    	int tem[9] = {1,1,1,1,1,1,1,1,1}; 
    	//也可以使用改进的高斯模板,但是效果相近 
    	int tem2[9] = {0};//获取中值时用于排序
    
    	//均值滤波3*3模板的均值
    	for( i = 0 ; i < image->height;i++){
    		for( j = 0; j< image->width;j++){
    			
    			//边界处理
    			if(i == 0 || i == image->height || j == 0 || j == image->width){
    				ptr = (unsigned char *)image->imageData + i*image->widthStep + j;
    				dst = (unsigned char *)image2->imageData+ i*image2->widthStep+ j;
    			 	*dst = *ptr; //边界值赋予源图像的值
    			}
    			else {
    				sum = 0;
    				for( m = -1 ; m <= 1; m++  ){
    					for( n = -1 ; n <= 1 ; n++){
    						ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;
    						
    						sum += (*ptr) * tem[3*(m+1) + n+1];
    					}
    				}
    				dst = (unsigned char *)image2->imageData+ i *image2->widthStep+ j;	
    				*dst = (unsigned char)((sum +4)/9);//赋新值,四舍五入
    			} 
    		
    		}
    	}
    //中值滤波 在去除噪声的同时,图像的模糊程度比较小,比均值滤波更加适合
    //冲击噪声或者称为椒盐噪声
    	for( i = 0 ; i < image->height;i++){
    		for( j = 0; j< image->width;j++){
    
    			//边界处理
    			if(i == 0 || i == image->height || j == 0 || j == image->width){
    				ptr = (unsigned char *)image->imageData + i*image->widthStep + j;
    				dst = (unsigned char *)image3->imageData+ i*image3->widthStep+ j;
    				*dst = *ptr; //边界值赋予源图像的值
    			}
    			else {
    				temp = 0;
    				//将3*3模板覆盖的值拷贝进数组,一边查找中值
    				for( m = -1 ; m <= 1; m++  ){
    					for( n = -1 ; n <= 1 ; n++){
    						ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;
    						tem2[3*(m+1) +n +1] = *ptr;
    						//printf("%d",*ptr);
    					
    					}
    				}
    				//对数组进行冒泡排序
    				for(r = 0 ; r <8; r ++){
    					for(s = 0 ; s< r -1; s++ ){
    						if(tem2[s] > tem2[s+1]){
    							temp = tem2[s];
    							tem2[s] = tem2[s+1];
    							tem2[s+1] = temp;
    						}
    					}
    				}
    				//printf("%d",tem2[4]);
    				//对新图赋予新值
    				dst = (unsigned char *)image3->imageData+ i *image3->widthStep+ j;	
    				*dst = (unsigned char)(tem2[4]);//赋新值
    			} 
    
    		}
    	}
    
    	cvShowImage("image2",image2);
    	cvShowImage("image3",image3);
    	cvWaitKey(0);
    	cvSaveImage("E:\\image\\Dart2.bmp",image2,0);
    	cvSaveImage("E:\\image\\Dart3.bmp",image3,0);
    	return 0;
    }
    效果图:

    原图:


    均值滤波:


    中值滤波:

     

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

    边界模糊效应明显

    细节丢失比较严重

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

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

    matlab源码:

    A = imread('Dart.bmp')
    
    %采用中值滤波和均值滤波的比较
    %模板大小的改变对滤波效果的影响
    subplot(3,3,1)
    imshow(A)
    for n = 1 : 8 
        m = 2*n +1
     B = medfilt2(A ,[m,m])
     subplot(3,3,n+1)
     imshow(B)
     
    end
    
    %采用均值滤波查看图像的变化
    subplot(3,3,1)
    imshow(A)
    for n = 1 : 8 
        m = 2*n +1
     C = imfilter(A,[m,m]);
     subplot(3,3,n+1)
     imshow(B)
    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锐化处理的效果。这样做可以极大的增强图像的细节。

    源代码:

    //锐化滤波,并利用锐化滤波增强图像的细节
    #include<cv.h>
    #include<highgui.h>
    
    int main(){
    	IplImage * image,*image2,*image3;
    	image = cvLoadImage("E:\\image\\moon.tif",0);
    	cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("image2",CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("image3",CV_WINDOW_AUTOSIZE);
    	cvSaveImage("E:\\image\\moon.jpg",image,0);
    	cvShowImage("image",image);
    	//cvWaitKey(0);
    	unsigned char * ptr,*dst;
    	image2 = cvCreateImage(cvGetSize(image),image->depth,1);
    	image3 = cvCreateImage(cvGetSize(image),image->depth,1);
    	
    	
    	int i,j,m,n,sum;
    
    	//锐化模板
    	int tem[9] = {0,1,0,1,-4,1,0,1,0}; 
    
    	//锐化滤波
    	for( i = 0 ; i < image->height;i++){
    		for( j = 0; j< image->width;j++){
    
    			//边界处理
    			if(i == 0 || i == image->height || j == 0 || j == image->width){
    				ptr = (unsigned char *)image->imageData + i*image->widthStep + j;
    				dst = (unsigned char *)image2->imageData+ i*image2->widthStep+ j;
    				*dst = *ptr; //边界值赋予源图像的值
    			}
    			else {
    				sum = 0;
    				for( m = -1 ; m <= 1; m++  ){
    					for( n = -1 ; n <= 1 ; n++){
    						ptr = (unsigned char *)image->imageData + (i + m)*image->widthStep + j + n;
    
    						sum += (*ptr) * tem[3*(m+1) + n+1];
    					}
    				}
    				dst = (unsigned char *)image2->imageData+ i *image2->widthStep+ j;	
    				*dst = (unsigned char)((sum +4)/9);//赋新值,四舍五入
    			} 
    
    		}
    	}
    
    	//锐化的图像与源图像相加,但是在相加之前需要先讲锐化的值稍微降低一些
    	
    	
    	cvShowImage("image2",image2);
    
    	for( i = 0 ; i < image2->height;i++){
    		for( j = 0; j< image->width;j++){
    			ptr = (unsigned char *)image2->imageData + i*image2->widthStep + j; 
    			*ptr = ((*ptr)+4)/5;
    		}
    	}
    	cvAdd(image,image2,image3,0);
    	cvShowImage("image3",image3);
    	
    	cvWaitKey(0);
    	cvSaveImage("E:\\image\\moon2.jpg",image2,0);
    	cvSaveImage("E:\\image\\moon3.jpg",image3,0);
    	return 0;
    }
    原图:

    锐化图像:

    叠加图像:

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

  • 相关阅读:
    文件修改的两种方式
    人工智能 01. 语音合成,语音识别,相似度,图灵机器人,智能对话
    flask --- 04 . 偏函数, 线程安全,栈堆,
    flask --- 03 .特殊装饰器, CBV , redis ,三方组件
    flask --- 02. 路由, 初始化配置,蓝图
    linux --- 10.常见命令
    flask --- 01 .初始
    linux --- 9. docker 容器 和 rabbitmq 队列
    linux --- 8. mysql数据库,redis 数据库
    linux --- 7. 路飞学城部署
  • 原文地址:https://www.cnblogs.com/libing64/p/2878737.html
Copyright © 2011-2022 走看看