C言語による画像処理: 色の抜き出し/入れ換え/反転
筑波大学農林工学系 奈佐原(西田)顕郎
Note: 以下, プロンプトを$で表すので, 以下の説明で, $は打ち込まなくてよい。
色チャンネルの抜き出し
カラー画像は,基本的には赤(Red), 緑(Green), 青(Blue)の3つの色情報の組み合わせでひとつのピクセルの色が表現されます.ここから,たとえば赤の情報だけを抜き出すと,赤色のセロハンを通して見たようなモノクロ(単色)画像になります.それをやってみましょう.
以下の方針で,各自でプログラムしてみてください.
- 基本的な構造は前回の"reverse_LR.c"と同じ.
- 左右の反転はしないので,1ラインをまとめて読み込む必要はありません.そこで,前々回のcutimage.cのように,ループの部分を
for (y=0; y<YL; y++) for (x=0; x<XL; x++) {fread(data, BPP, 1, stdin); fwrite(data, 1, 1, stdout); }
と変更し,さらに配列data[ ]の宣言を,
unsigned char data[BPP]
と変更しましょう.
- ファイル名はcolor_extract.cとしましょう.
- 出力画像ファイル(今回はPPM形式ではなくてPGM形式となる)のヘッダの最初の行は,そのままの文字列(P6)を出力するのではなく,かわりにP5を出力しましょう.なぜなら...PNM形式の仕様では,P6はカラーRGB画像(それをPPMと呼ぶ).P5はモノクロ画像(PGMと呼ぶ).
- ピクセルデータの出力(fwriteの部分)で,3バイト(プログラムの中ではBPP(byte per pixelの略)として定義されている)ではなく1バイトの出力としましょう.なぜなら...3バイトのうち最初の1バイトが赤.それを抜き出すとモノクロ(単色)画像になる.
- コンパイル結果をcolor_extractとし,入力画像lake.ppmと出力画像lake_red.pgmをリダイレクトで指定しましょう.
その結果,次のようにlake_red.pgmができますが,もとのlake.ppmに比べて,ヘッダー部分は除き,大きさが1/3になります.
-rw-r--r-- 1 xxxx xxxx 1440060 xx月 xx xx:xx lake.ppm -rw-r--r-- 1 xxxx xxxx 480060 xx月 xx xx:xx lake_red.pgm
←赤チャンネルを抜き出した結果.
同様に,緑,青も抜き出して,並べてみましょう. ヒント: ピクセルデータの出力で,dataをdata+1にすれば緑の抜き出しになります.
←赤チャンネル
←緑チャンネル
←青チャンネル
上の結果をみると,明らかに青チャンネルが他に比べて明るいですが,なぜでしょうか?
色の入れ換え
カラー画像の各ピクセルは,赤・緑・青の順番で1バイトづつ各色のデータが記述されていますが,この順番を,例えば青・緑・赤に入れ換えるとどうなるでしょうか? 以下の方針で,各自でプログラムしてみてください:
- 基本的な構造は上の"color_extract.c"と同じ.(ただし,チャンネル抽出はしないので,ヘッダーはP6のまま出力)
- ファイル名はcolor_swap.cとしよう.
- 各ピクセルにつき,fwriteを3回行うことで,青・緑・赤の順に1バイトづつ出力する.各fwriteの中で,データの位置をどのように指定するべきか,考えてください.
- コンパイル結果をcolor_swapとし,入力画像lake.ppmと出力画像lake_swap.ppmをリダイレクトで指定する.
←赤と青を入れ換えた結果.
同様に,赤・青・緑や緑・赤・青などの組み合わせ(ぜんぶで3!=6通りあり得る)を試してみましょう.
明るさの反転
各ピクセルの各色は0から255までの数字で,大きいほど明るい状況を表しています.そこで,これをひっくりかえして,大きな値ほど「暗くなる」ようにしてみましょう.
まず,ひとつのチャンネルのみに注目して,たとえば赤チャンネルだけ抜き出し,反転させてみましょう.方針は,
- 基本的な構造は上の"color_extract.c"と同じ.
- freadの直後で,以下の行を入れる.
data[0]=255-data[0]; data[1]=255-data[1]; data[2]=255-data[2];
←赤チャンネルを抽出して明るさを反転した結果.
こんどは,3つのチャンネルを全て反転した結果をカラーで出してみましょう.ヒントは無しです.自分で考えてやってみてください.
←全チャンネルの明るさを反転した結果.
Keyword(s):
References:[画像解析入門] [C言語による画像処理: 明るさの調整・GIFアニメ]