ここでいうフィルタとは画像に対して様々な加工を施すものを指します.フィルタの種類はいろいろあるのですが,平均化フィルタとは画像をぼかすような効果を得ることが出来るフィルタです.表現を変えると画像が水でにじんだような雰囲気になります.そのとき色の濃い部分から薄い部分に拡がっていきます.
これを実装しようとするとフィルタは
のようになります.注目しているピクセルとその周りのピクセルの値を取ってきて平均をとるわけです.このようにすると値の大きい部分は小さくなり,値の小さい部分は大きくなります.また平均をとっているために全体の値の大きさは変化していません.しかし,これをプログラムにしようとすると問題があります.注目しているピクセルをフィルタにかけるためにはその周囲のピクセルの値が必要となりますが,画像の端のピクセルは周りにピクセルがありません.これをクリアするためには,端のピクセルは無視し,その次のピクセルからフィルタをかけていく方法と,値の無い部分についてはその隣のピクセルの値を使用する方法があります.前者の方が実装が楽なので端のピクセルを無視することにします.
for(i=1; i<img->height-1; i++){ for(j=1; j<img->width-1; j++){ sumr = sumg = sumb = 0; for(k=-1; k<=1; k++){ for(l=-1; l<=1; l++){ sumr += img->data[(i+k)*img->width + j + l].r; sumg += img->data[(i+k)*img->width + j + l].g; sumb += img->data[(i+k)*img->width + j + l].b; } } temp->data[i*temp->width + j].r = sumr/9; temp->data[i*temp->width + j].g = sumg/9; temp->data[i*temp->width + j].b = sumb/9; } }
sumr, sumg, sumbはそれぞれ注目しているピクセルの値とその周りのピクセルの値の合計を保持する変数です.i, jで注目しているピクセルを指定し, k,lを-1から1まで動かすことで注目しているピクセルを中心に9ピクセルの値を足し合わせています.最後に合計を9で割る事で平均値を出しています. tempはimgのコピーなのですが,フィルタにかけた値をimgにそのままいれると次のピクセルでフィルタをかけたあとの値が使われてしまうためです.全てフィルタにかけ終わったらimgにコピーします.フィルタをかける前にコピーしている理由は周囲1ピクセルを無視しているため,できあがった画像から周囲1ピクセル分の値が無くなってしまうためです.