MATLABによる画像処理6

ページトップへ 一つ上へ

ポイント


ノイズ除去、移動平均法、メディアンフィルタ



さてさて、今回も画像処理の続きをやってみたいと思います。
前回は画像の二値化について学びました。
今回はノイズ除去について考えていきたいと思います。

さて、実環境で何か計測を行う場合、どうしてもノイズが入ってしまいます。
音でも画像でも同じ事で、どうしても理想にはなりません。
そこで、ノイズ成分を除去する必要があります。

今回は、意図的に画像にノイズを付加してそれを除去してみましょう。

今回使った素材の画像は、



この画像はIEEEの研究用標準画像です。

まずは、この画像にノイズを付加してみましょう。
では実際のプログラムは以下のように
function image_proc9

%
% 乱数使用によるノイズ付加
% 
%

imagedata=imread('LENNA.bmp'); 
imagedata=double(imagedata); 
[width height]=size(imagedata);

noise=rand(width,height);

for ii = 1 : width
	for jj = 1 : height
		if (noise(ii,jj) < 0.03)
			imagedata(ii,jj)=0;
		end
	end
end

imagesc(imagedata); 
colormap(gray(256));


かなり適当な方法ですが、約3%の確率で画素が真っ黒になります。
それが結果として、以下のようなノイズ画像に変わります。



さて、この画像のノイズを除去する方法について考えていきます。
今回は以下の2つの方法について説明します。

1.移動平均法による雑音除去
2.メディアンフィルタによる雑音除去

まずは1の移動平均法から。
ある画素の周りの値を読みます。
434
4195
233
こんな感じだったとしましょう。中心がそのある画素です。
この中心以外の部分の平均を取った値を中心の値とするのが、
移動平均法の考え方です。
具体的には、

(4+3+4+4+5+2+3+3)/8=28/8=3.5

となり、これが中心の値になります。
四捨五入するなら4に、切り捨てるなら3になります。
さて、ではこの方法をプログラミングし、結果を見ましょう。
function image_proc9_1

%
% 乱数使用によるノイズ付加
% 移動平均法によるノイズ除去
% 
%

imagedata=imread('LENNA.bmp'); 
imagedata=double(imagedata); 
[width height]=size(imagedata);

noise=rand(width,height);

for ii = 1 : width
	for jj = 1 : height
		if (noise(ii,jj) < 0.03)
			imagedata(ii,jj)=0;
		end
	end
end

imagesc(imagedata); 
colormap(gray(256));

figure;
averageimage=imagedata;
for ii = 2 : width - 1
	for jj = 2 : height - 1
		num(1)=imagedata(ii-1,jj-1);
		num(2)=imagedata(ii,jj-1);
		num(3)=imagedata(ii+1,jj-1);
		num(4)=imagedata(ii-1,jj);
		num(5)=imagedata(ii+1,jj);
		num(6)=imagedata(ii-1,jj+1);
		num(7)=imagedata(ii,jj+1);
		num(8)=imagedata(ii+1,jj+1);
		averageimage(ii,jj)=mean(num);
	end
end

imagesc(averageimage); 
colormap(gray(256));
title('move average');

こんな感じです。
上の方はノイズ付加で、下に移動平均法です。
このプログラムからノイズ除去した画像がこちら



ノイズは除去されていますが、全体的にぼやけてしまってますね。
移動平均法はノイズ以外の部分も平均化してしまいます。

そこで、違う方法について考えてみましょう。
それが、メディアンフィルタというものです。
メディアンフィルタというのは、ある画素の周りの値の中間(メディアン)を
ある画素とする考え方です。

434
4195
233
こうだった場合、中心の画素は、
4 3 4 4 19 5 2 3 3→2 3 3 3 4 4 4 5 19
この真中の値だから、4という事になります。
この考え方をプログラミングすると、
function image_proc9_1

%
% 乱数使用によるノイズ付加
% メディアンフィルタによるノイズ除去
% 
%

imagedata=imread('LENNA.bmp'); 
imagedata=double(imagedata); 
[width height]=size(imagedata);

noise=rand(width,height);

for ii = 1 : width
	for jj = 1 : height
		if (noise(ii,jj) < 0.03)
			imagedata(ii,jj)=0;
		end
	end
end

imagesc(imagedata); 
colormap(gray(256));

figure;
medianimage=imagedata;
for ii = 2 : width - 1
	for jj = 2 : height - 1
		num(1)=imagedata(ii-1,jj-1);
		num(2)=imagedata(ii,jj-1);
		num(3)=imagedata(ii+1,jj-1);
		num(4)=imagedata(ii-1,jj);
		num(5)=imagedata(ii,jj);
		num(6)=imagedata(ii+1,jj);
		num(7)=imagedata(ii-1,jj+1);
		num(8)=imagedata(ii,jj+1);
		num(9)=imagedata(ii+1,jj+1);
		num=sort(num);
		medianimage(ii,jj)=num(5);
	end
end

imagesc(medianimage); 
colormap(gray(256));
title('median filter');

こんな感じになります。
では、実際に処理した結果を以下に。



となり、上手くノイズを除去出来ている事がわかります。
しかし、世の中万能なノイズ除去なんてありません。
まぁ、気休め程度に考えておいて下さい。