天天看點

圖像處理基本算法-濾波

線性濾波器的向量表示:

圖像處理基本算法-濾波

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;
}
           

原圖:

圖像處理基本算法-濾波

銳化圖像:

圖像處理基本算法-濾波

疊加圖像:

圖像處理基本算法-濾波

由疊加圖像可知,經過銳化處理和疊加之後,圖像的細節部分更加清晰。

轉載于:https://www.cnblogs.com/libing64/archive/2011/12/14/2878737.html

繼續閱讀