プログラミング演習Ⅱ 課題4第3週 画像処理 (1) ビット演算子
全体の流れ 画像ファイルを開き,画像データをメモリ上にロード(済) ロードした画像データに処理を加える (第3・4週) 処理後のデータを出力ファイルに書き出す (済) 画像データ用に確保したメモリを解放 (済)
画像バッファの様子(再確認) ysize個 → i ↓ j pImage->pBuffer[0][0] xsize 256 ysize 192 pImage->pBuffer[0][0] PIXEL構造体, {R, G, B} level 255 pBuffer → i ↓ j 位置[0][0]のRにアクセス: pImage->pBuffer[0][0].r ysize個 pImage->pBuffer[j] xsize個
iioMallocImageBuffer 画像の90度回転 ipRotateImage [0][ysize – 1] [0][0] → i ↓ j xsize個 ysize個 xsize個 ysize個 関数内で作業用の画像バッファメモリを確保し, 順に画素を埋めていけばよい. iioMallocImageBuffer iioFreeImageBuffer
ビットマスクを用いた 画像の減色処理 ipBitMask 原画像 RGB各色 0~255 2563 = 16,777,216 色 減色画像の例 0, 16, 32,...,240 163 = 4096色 下位4bitは全て0
ビット演算 (1) unsigned char A = 113; /* 0111 0001 */ unsigned char B = 15; /* 0000 1111 */ unsigned char D; D = A & B; /* AND: 0000 0001 */ D = A | B; /* OR: 0111 1111 */ D = A >> 3; /* SHIFT: 0000 1110 */ 他にもXOR(^), 左シフト(<<),NOT(~)がある
ビット演算 (2) unsigned char A = 113; /* 0111 0001 */ char C = -64; /* 1100 0000 */ char D; D = A >> 3; /* 0000 1110, 14 */ D = C >> 3; /* 1111 1000, -8 */ 符号なし変数のシフト: 隙間は0で埋められる (論理シフト) 符号あり変数のシフト: 隙間は最上位ビットで埋められる* (算術シフト) *注意: 符号あり変数のシフト結果は環境によって異なることがあるため, 負の数のビットシフトは極力避けるようにする
練習問題 (1) 式 結果 2進 16進 10進 D = A & B A: 0000 0011 (0x03, 3) 変数の型と初期値 unsigned char A = 3; unsigned char B = 33; unsigned char D = 0; 式 結果 2進 16進 10進 D = A & B A: 0000 0011 (0x03, 3) B: 0010 0001 (0x21, 33) D: D = A | B A: B:
練習問題 (2) 式 結果 D = A ^ B A: B: D: D = B << 2 D = B >> 3
練習問題 (3) 式 結果 D = ~A A: D: B >>= 3 実行前 B: 実行後
画素のビットマスク ipBitMask 各画素値の下位6ビットを0にしたい場合 pImage->pBuffer[j][i].r &= 0xC0; pImage->pBuffer[j][i].g &= 0xC0; pImage->pBuffer[j][i].b &= 0xC0; 16進: C0 2進:1100 0000 例: r = 100 rの2進表現 1 0xC0の2進表現 r & 0xC0 下位6ビットが0のマスク(0xC0)と&を取ることで,画素値の 階調を制限している (結果,画素値は0, 64, 128, 192のいずれかになる)
第3週目の目標 ビット演算の練習問題を解く コマンドライン引数の最初のmodeによって画像処理の種類を指定できるようにせよ. > ex4_2.exe [mode] [inputfile] [outputfile] modeが0の場合: 画像を90度回転 modeが1の場合: 画像の各画素の下位”4”ビットを0でマスク(6ではないので注意) 上記以外: 画像処理を行わない(ファイルのコピー)