平滑化フィルタ
2012年12月6日:OpenCV
ごましおノイズを軽減する際によく平滑化フィルタをつかいます。
平滑化フィルタは、画像をぼかすと考えてください。
ここでは、平滑化フィルタの基本である
- 平均値を使った処理
- 中央値を使った処理
- ガウシアン処理
を紹介します。
平均値を使った処理
はじめに以下のようにプログラムを書きます(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の平均値が出力されます。以下の場合は、
平均値が
(1+1+1+5+71+2)/81=1
なので1となります。プログラムを実行すると以下のようになります。
少しぼやけた感じになっていますね。
中央値を使った処理
では続いて、中央値を使った処理を見ていきましょう。
先ほどのプログラムのCV_BLURをCV_MEDIANに変えてください。
cvSmooth(src,dst,CV_MEDIAN,9,9,0,0);
すると、9×9の中の中央値を取る処理を行います。例えば
なら、大きい順に並べると
71,5,2,1,1,1,0,0,…,0
なので中央値は0となります。
そして、実行すると
となります。さきほどと微妙にちがいますね。
ガウシアン処理
最後の処理がガウシアン処理です。
ガウシアン処理ではガウス分布
のように中央に重みをつけるように計算します。たとえば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);
としてプログラムを実行します。
すると以下のように表示されます。
中央値に重みづけしているのでそれほどぼやけてはいませんね。
著者:安井 真人(やすい まさと)
@yasui_masatoさんをフォロー