デジタル画像とC言語 画像の表現 • 一般的に、画像は2次元配列で表現される 例:320x240(240行、320列)画素の濃淡画像 unsigned char image[240][320]; 説明: unsigned = 符号なし char = 文字型 unsigned char = 符号なしの文字型で 8 0~255 (= 2 1 )の値が表現できる 画像の操作(1) 位置が(x,y)である画素は, y行、x列にある画素である。 0列 1列 2列 x列 0 行 1 行 2 行 y行 画素値の読出し: 例: (x,y)の画素の値を変数vに代入する。 (変数vは既に定義しているものとする) v = image[y][x]; 画像の操作(2) 0列 1列 2列 x列 0 行 1 行 2 行 y行 画素値の設定: 例: (x,y)の画素の値を128にセットする。 image[y][x] = 128; 画像操作の例:90度回転(1) y x y’ x H x’ y W W H 元画像の(x,y)の画素が回転した後の位置(x’,y’)とする。 x’= H -1 – y; y’= x; 元画像を表す配列: image 回転した後の画像を表す配列: image_new とすると、 image_new[x][H-1-y] = image[y][x]; で回転したあとの画素値が設 定できる。 画像操作の例:90度回転(2) y x y’ x H y x’ W W int x,y; for (y = 0; y < H; y++) for (x = 0; x < W ; x++) image_new[x][H-1-y] = image[y][x]; H 画像の移動(1) y Δy Δy + y Δx x H H Δx + x W 画像をX方向にΔx, Y方向にΔyを移動する。 (x,y)の画素が移動後に (x’,y’)なるとすると、 x’= x + Δx; y’= y + Δy; W 画像の移動(2) y Δy Δy + y Δx x H H Δx + x W W 元画像を表す配列: image 回転した後の画像を表す配列: image_new とすると、 image_new[y+Δy][x+Δx] = image[y][x]; で移動したあとの画素値が設定できる。 画像内の移動(3) (x0,y0) h dy w dx 画像を表す配列: image 移動する矩形部分の左上の角の座標: (x0,y0) 横幅、縦幅: w, h 水平、垂直方向の移動量、dx, dy とすると、 int x, y; for (y = y0; y < y0+h; y++) for (x = x0; x < x0+w; x++) { xnew = x + dx; ynew = y + dy; image[ynew][xnew] = image[y][x]; } で図に示すように矩形部分の画像を移動することが できる。 しかし 画像内の移動(1) (x0,y0) dy 移動元 と 移動先 と 重なる 部分があると、 処理は難しくなる。 h dx dy h (x0,y0) dx 画像内の移動 移動の順序(1) int x, xnew; for (x= 0; x < 4; x++) { xnew = x + 2; image[xnew] = image[x]; } 移動前 正しい結果 1 2 3 4 5 6 7 8 9 1 1 2 1 4 5 6 7 8 9 x: 0, xnew: 2 image[2] = image[0] 1 2 1 2 5 6 7 8 9 x: 1, xnew: 3 image[3] = image[1] 1 2 1 2 1 9 x: 2, xnew: 4 image[4] = image[2] 1 2 1 2 1 2 7 8 9 x: 3, xnew: 5 image[5] = image[3] 6 7 8 2 1 間違った! 2 3 4 7 8 9 画像内の移動 移動の順序(2) int x, xnew; for (x= 3; x >= 0; x--) { /* 逆の順でコピーする */ xnew = x + 2; image[xnew] = image[x]; } 移動前 1 2 3 4 5 6 7 8 9 1 1 2 3 4 5 4 7 8 9 x: 3, xnew: 5 image[5] = image[3] 1 2 3 4 3 4 7 8 9 x: 2, xnew: 4 image[4] = image[2] 1 2 3 2 3 4 7 8 9 x: 1, xnew: 3 image[3] = image[1] 1 2 1 2 3 4 7 8 9 x: 0, xnew: 2 image[2] = image[0] 正解! 2 正しい結果 1 2 3 4 7 8 9 画像内の移動 移動範囲 (x0,y0) 移動した後の矩形領域は画像の範囲を超えること がある。 dy dx この場合、移動しようとする矩形の画像範囲から はみ出す部分を削り、移動した後も画像の範囲内に なるようにする。 (削り=矩形の形を変える) (x0,y0) dy dx 実際にプログラムを書いてみよう • 画像処理のプログラムを書くために、画像処理用の ライブラリが要る。 理由: 下記の機能が必要である。 ① 処理しようとする画像の読込み (ファイルなどから) ② 処理結果を保存する画像の用意 ③ 処理結果をファイルに保存する が、これらの部分を作るのは面倒で、難しい。 RASLIB:画像処理演習用ライブラリ RASLIBは、私(陳謙)が画像処理のプログラムを簡単に書けるため に作ったライブラリである。 Linux版とWindows版両方あるが、Linux版をお勧めする。 以降の説明はLinux版に関するものである。 RASLIBのダウンロード ① ダウンロード:RASLIBのWEBページ http://www.wakayama-u.ac.jp/~chen/RASLIB/raslib.htm からダウンロードできます。 そのページの“RASLIBの入手”の章から、raslib.tgzという ファイルをダウンロードしてください。 (firefoxのデフォールトのダウンロード先は $HOME/Desktop です。) RASLIB:画像処理演習用ライブラリ RASLIBのインストール 1.端末ウィンドウを開く。 2.端末ウィンドウで次の命令を入力することにより、 ダウンロードした raslib.tgz ファイルを自分のホームに 移動する。 cd mv $HOME/Desktop/raslib.tgz . 3.以下の命令を実行して、必要なディレクトリを作ってください。 mkdir include lib 4.ダウンロードしたファイルを解凍します。 tar xvzf raslib.tgz 5.ソフトウェアをコンパイルし、インストールします。 cd RASLIB make clean make PREFIX=$HOME install これでインストールが完了します。 RASLIBを使って画像を生成する(1) 0 1 2 15 16 17 ... ... 15 31 32 33 34 ... 47 240 241 242 . . . 255 16x16画素 256x256画素の濃淡画像: 中身は16x16個=256個の正方形の領域である。 1個の領域の大きさは16x16画素で、画素値は全部同じである。 /* Begin grey_image_16x16.c */ #include “raslib.h” /* RASLIBを使うプログラムにはこれが必要 */ int main(int argc, char **argv) /* main関数はこのように書く */ { Rasimg *img; /* 画像を現す関数。RASLIBでは、画像は Rasimg *型の変数で表現される。*/ RASLIBを使って画像を生成する(2) int block_x; /* 横のブロックの番号 */ int block_y; /* 横のブロックの番号 */ int v; /* ブロックの画素値 */ int x0, y0; /* ブロックの左上の角の座標 */ int x, y; unsigned char **image; /* 画像の中身を現す変数,画像を現す2次元配列のように使える */ img = ras_alloc(256, 256, 8); /* 256x256画素の濃淡画像(8bit)を用意する */ /* ras_alloc(横, 縦, ビット数) は 「横」x「縦」 画素で、 1画素が「ビット数」ビットの画像を用意するための関数である。*/ image = ras_lnidx(img); /* Rasimg *型の変数から、画像の中身を現す変数を取り出す。 その後、imageは2次元配列のように使える */ RASLIBを使って画像を生成する(3) /* 画素値をセットする */ for (block_x = 0; block_x < 16; block_x++) { x0 = block_x * 16; for (block_y = 0; block_y < 16; block_y++) { y0 = block_y * 16; v = block_y * 16 + block_x; for (x = 0; x < 16; ++x) for (y = 0; y < 16; ++y) image[y+y0][x+x0] = v; } } pnm_save(“grey256.pgm", img); return 0; } /* End */ RASLIBを使って画像を生成する(4) コンパイルと実行 1.grey_image_16x16.c を作ります emacs を使って、“ /* Begin grey_image_16x16.c */ から/* End */ までの部分の内容の「grey_image_16x16.c」というファイルを作る。 2 コンパイル grey_image_16x16.c は次のようにコンパイルする。 cc -I$HOME/include -L$HOME/lib grey_image_16x16.c -o grey_image_16x16 -lras 3 コンパイルしたプログラムを実行する ./grey_image_16x16 4 実行結果を確認する gimp grey256.pgm 練習問題1: grey_image_16x16.cを改造して(pnm_saveの前に追加)、作ったグレーブロック の画像を90度回転するプログラムを作りなさい。
© Copyright 2024 ExpyDoc