DXライブラリでの画像加工その6。Oキーで画像の輪郭を抽出する処理ができるようにします。
前置き
DXライブラリを用いて画像加工ソフトを作成していきます。初期設定はこちらから、キー入力に関してはこちらからどうぞ。
今回の実行用素材は、下のフリーのものをお借りしました。淡いスイレン素敵です。花言葉的に信頼や信仰を意味するようでして。
今までと同様画像名はtest、サイズは 640×480 、形式は bmp です。
輪郭抽出処理について
これまでの記事では、モノクロ化やモザイク処理などの非常に簡単な加工を行ってきましたが。今回扱う輪郭抽出は語感的に何となく高度っぽいですよね。実際、少し複雑なものになります。
加工の手順としては、
- 画像をモノクロに加工する
- 画像にフィルタを掛ける
といった流れで。モノクロ加工については割愛、加工後の輝度がint型配列 CD に格納済みであるとします。(モノクロ加工の詳細はこちら)実際に白黒に変換した画像が以下のものですね。
それでは、輪郭抽出の本編。画像にフィルタを掛ける処理について触れていきます。今回は、8方向ラプラシアンフィルタというフィルタを用いて、画像の輪郭を識別していきます。
以下のようなint型の3×3配列、gOUT[3][3]を利用します。
-1 | -1 | -1 |
-1 | 8 | -1 |
-1 | -1 | -1 |
横640×縦480の画像の色データが入った配列を CD[640][480] について考えるとき。画像上のある点 CD[x][y] が輪郭部か否かを判断する際には、
CD[x-1][y-1]*gOUT[0][0] + CD[x][y-1]*gOUT[1][0] + …+CD[x+1][y+1]*gOUT[2][2]
が0より大きいかどうかを考慮します。この値が0より小さければ(x,y)の点は周囲の色と大きな差がない為輪郭ではない、反対にこの値が0より大きければ、点は周囲の色より大幅に明るい為、輪郭だと判断できます。実際にプログラムで見た方が分かりやすいかもですね。
輪郭抽出機能の追加
それでは早速、輪郭抽出機能を作成していきます。oキーを入力すると画像の輪郭が表示される、という仕組みで行きましょう。ソースコードは以下の通りに。
//関数の追加 void get_outline(){ int gOUT[3][3]={ {-1,-1,-1}, {-1, 8,-1}, {-1,-1,-1} }; for(int x=1;x<639;x++){ for(int y=1;y<479;y++){ Cr[x][y][0]=0; for(int dx=0;dx<3;dx++){ for(int dy=0;dy<3;dy++){ Cr[x][y][0]+=CD[x-1+dx][y-1+dy][0]*gOUT[dx][dy]; } } if(Cr[x][y][0]<=0)Cr[x][y][0]=0; Cr[x][y][1]=Cr[x][y][2]=Cr[x][y][0]; } } } //mainのループ部内に if(ky[KEY_INPUT_O]==1)get_outline();
CD配列は画像の輝度データの格納、Cr配列は実際に出力する色データの格納です。
無事抽出完了。少々見にくいので、輪郭部を4倍に明るくしてみます。
とりあえずはこんなところでしょうか。ちなみに、このページのアイキャッチ画像は上画像の輝度を少し上げたものになります。輝度の上げ方はこちらから。
フィルタの種類は多数あるので、紹介のページを作るかもです。