RIGHT:寄稿:東條遼平 * 置換をするフィルタ [#t886936f] これまでのフィルタは線形計算によってそれぞれの値を算出していましたが、 Medianフィルタは値の置き換えを行います。具体的には注目しているピクセルを中心に3×3のピクセルを考えたときに、それらの値の中から中間の値を探し、注目しているピクセルの値とするという作業を行います。 例えば画像に点々とノイズが載っているような場合、ぼかすフィルタを掛けてもノイズは無くなるのですが、鮮明さが失われてしまいます。 Medianフィルタであれば画像の劣化を押さえたままノイズを除去することができます。もちろん何度も掛ければ劣化し、水彩画のような感じになります。 中間値を求める方法ですが、ソートを使います。 3×3であれば、9つの値を保持するバッファを用意し、9つの値を取得してからソートをすれば、buf[4]がに中間値が入っていることになりますので、大変簡単に求められます。ソートのアルゴリズムは大変種類が多いですが、一般的に高速であるクイックソートを利用します。 クイックソートは標準ライブラリのstdlib.hに入っています。このとき比較関数を作成して関数ポインタを引数に渡す必要があります。比較関数とは読んで字のごとく2つの値をどういう基準で比較するのかを定義してやる関数です。要は2つの値を取って第一引数、第二引数の順であっていれば負の値、間違っていれば正の値を返してやります。 static int char_compare(const unsigned char *a, const unsigned char *b) { if(*a < *b) return -1; else if(*a > *b) return 1; else return 0; } 比較関数はこれだけで構いません。正か負かが分かればいいので、第一引数と第二引数の差を返しても問題ありません。staticが付いているのはこの関数がbitmap.c内でしか使われない事を保証するためです。 qsort(r, 9, sizeof(unsigned char), (int(*)(const void*, const void*))char_compare); qsort(g, 9, sizeof(unsigned char), (int(*)(const void*, const void*))char_compare); qsort(b, 9, sizeof(unsigned char), (int(*)(const void*, const void*))char_compare); 注目しているピクセルを中心に9つの値を保持した配列r、g、bの先頭アドレスを渡しています。最後の引数はごちゃごちゃしていますが、関数ポインタを渡せばいいので比較関数の関数名(この場合であればchar_compare)だけでも結構です。ソートの後に配列の真ん中にある値が中間値となります。 - &ref(main.c); - &ref(bitmap.c); - &ref(bitmap.h);