伊達
>>
情報工学序説
>>
課題一覧
>>
演習(画像)
『マウスを右クリック→リンク先を名前をつけて保存』.
ファイルを保存したディレクトリに移動し,以下の操作をおこなう.
% ls -l ics001.jpg -rw-r--r-- 1 date date 162281 2006-04-03 22:58 ics001.jpgこの jpgファイルのサイズは 162281 byte.(日付,ファイルの所有者は人によって異なる)
% eog ics001.jpg
「ズーム時に画像を補正する」に x が入っていれば,はずす.
その1: od というコマンドを使い,ファイルに書き込まれている 内容(数字)を16進数で表示する. (コマンドのオプションがややこしいので,以下のコマンドは,マウスでコピーして,そのまま張り付ければよい)
% od -t x1z -A x ics001.jpgx1z とかは,とりあえず,おまじないだと思っていい.
16進数でかかれた数字の列が見えるはず. 流れが早いので,止めてみたいときは,
% od -t x1z -A x ics001.jpg | moreスペースキーで,次の画面にすすむ.q でおしまい.
その2: C言語から画像ファイルを読み,画像データをプリントアウトする.
次のプログラムをダウンロードする
(右クリック→リンク先を名前をつけて保存):
irl_imlib_printout.c
次のコマンドは長いので,このページからコピーして張り付ければいい.
% gcc `imlib-config --cflags-gdk --libs-gdk` irl_imlib_printout.c % ./a.outしばらく数字が表示される. そのうち終わるのであせらず待つ.
... 92 41 33 120 69 48 128 75 66 139 86 88 152 102 112 168 123 136 182 145 127 171 136 95 158 111 106 167 125 121 176 144 122 175 149 103 155 132 75 130 101 84 144 106 74 137 94 43 113 59 62 148 99 13 125 75 23 125 78 40 134 82 45 135 84 32 81 52 22 48 37 17 61 34 3 103 53 28 90 43 55 101 54 73 123 72 92 112 75 102 128 93 117 143 114 87 123 85 48 67 47 25 54 36 20 81 47 19 86 51 15 58 41 17 58 40 39 99 63 %数字の意味: 画像の左上から順に,各ピクセルの R G B の値が,0-255 の整数の値で指定されている.
プログラム irl_imlib_printout.c をみてみる.
% less irl_imlib_printout.cもしくは
% emacs irl_imlib_printout.cそのうち,以下の部分だけが重要 (いまのところ,気分だけ分かればよい).
guchar *data = im->rgb_data; /* 配列 data[] に画像データを格納 */
length = im->rgb_width * im->rgb_height * 3;
for (i=0; i<length; i++){
printf("%3d ", data[i]); /* 数字の表示 */
}
カラー画像を白黒化して別のファイルに保存する例. 以下のgccコマンドでプログラムをコンパイルしている. 長いので,このページからコピーして張り付けて使えばよい.
% gcc `imlib-config --cflags-gdk --libs-gdk` irl_imlib_color2gray.c % ./a.out % eog ics001bw.jpg
アルゴリズム: カラー画像 (R,G,B) → モノクロ: 0.299*R + 0.587*G + 0.114B
for (i=0; i<length; i +=3){
ave = 0.299*(gfloat)data[i] +0.587*(gfloat)data[i+1] + 0.114*(gfloat)data[i+2];
data[i]=data[i+1]=data[i+2]=(guchar)ave;
}
% gcc `imlib-config --cflags-gdk --libs-gdk` irl_imlib_linedraw.c % ./a.out % eog ics001edges.jpg
アルゴリズム:
横x 縦y の位置にあるのピクセル値 := (x,y)のピクセル値ー((x,y)の上下左右の4ピクセル値の平均)
for (y=1; y<h-1; y++){
for (x=1; x<w-1; x++){
j=y*w+x;
i=j*3;
data[i] = data[i+1] = data[i+2]
= 255 - (guchar)(buf[j]-(buf[j-w]+buf[j-1]+buf[j+1]+buf[j+w])/4);
}
}
% gcc `imlib-config --cflags-gdk --libs-gdk` irl_imlib_sepia.c % ./a.out % eog ics001sepia.jpg
エラー処理などもしているので,書こうと思えばもっと 短くコードは書けます.
プログラムの仕方はまだ習っていないので, ちんぷんかんぷんだとは思いますが, 画像処理をするプログラムを書くとは, こういうことの積み重ねです.
char in_file[]="ics001.jpg"; /* 入力画像のファイル名 */ char out_file[]="ics001sepia.jpg"; /* 出力ファイル名 */