平滑化フィルタ

heikin

ごましおノイズを軽減する際によく平滑化フィルタをつかいます。

平滑化フィルタは、画像をぼかすと考えてください。

ここでは、平滑化フィルタの基本である

  • 平均値を使った処理
  • 中央値を使った処理
  • ガウシアン処理

を紹介します。

平均値を使った処理

はじめに以下のようにプログラムを書きます(Visual C++,コンソールアプリケーションで作りました)

int _tmain(int argc, _TCHAR* argv[])
{
	//画像データの読込
    IplImage* src = cvLoadImage("C:\\opencv\\samples\\c\\lena.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
    if (src == NULL){
        return 0;
    }
	IplImage* dst;
	dst=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,3);
	//平滑化処理(9x9の平均値)
	cvSmooth(src,dst,CV_BLUR,9,9,0,0);
    //表示ウィンドウの作成
    cvNamedWindow("画像");
    //画像の表示
    cvShowImage ("画像", dst);
    //キー入力待ち
    cvWaitKey (0);
    //ウィンドウの削除
    cvDestroyWindow("画像");
    //画像データの解放
    cvReleaseImage(&src);
	return 0;
}

解説

void cvSmooth(
	const CvArr* src,	//処理対象の画像
	CvArr*	dst,		//結果
	int	smoothtype,	//平滑化の方法
	int	param1,		//パラメータ1
	int	param2,		//パラメータ2
	int	param3,		//パラメータ3
	int	param4		//パラメータ4
};

というcvSmooth関数を使います。

smoothtypeで、CV_BLURを選ぶと平均値処理になります。

パラメータ1でフィルタの横方向のサイズ、

パラメータ2でフィルタの縦方向のサイズ

を指定します。たとえば今回は9×9を選んだので、対象とする点を中心として9×9の平均値が出力されます。以下の場合は、

heikin

平均値が

(1+1+1+5+71+2)/81=1

なので1となります。プログラムを実行すると以下のようになります。

スクリーンショット_112312_072605_PM

少しぼやけた感じになっていますね。

中央値を使った処理

では続いて、中央値を使った処理を見ていきましょう。

先ほどのプログラムのCV_BLURをCV_MEDIANに変えてください。

cvSmooth(src,dst,CV_MEDIAN,9,9,0,0);

すると、9×9の中の中央値を取る処理を行います。例えば

heikin

なら、大きい順に並べると

71,5,2,1,1,1,0,0,…,0

なので中央値は0となります。

そして、実行すると

スクリーンショット_112312_072921_PM

となります。さきほどと微妙にちがいますね。

ガウシアン処理

最後の処理がガウシアン処理です。

ガウシアン処理ではガウス分布

 \displaystyle f(x,y)=A\exp\left(-\frac{x^{2}+y^{2}}{B}\right)

のように中央に重みをつけるように計算します。たとえば3×3なら

1/16 2/16 1/16
2/16 4/16 2/16
1/16 2/16 1/16

と重みづけされます。では実際に

CV_BLURをCV_GAUSSIAN

に変えて処理をしてみます。つまり

cvSmooth(src,dst,CV_GAUSSIAN,9,9,0,0);

としてプログラムを実行します。

すると以下のように表示されます。

スクリーンショット_112312_073937_PM

中央値に重みづけしているのでそれほどぼやけてはいませんね。

著者:安井 真人(やすい まさと)