3.グラフ描画基礎
そろそろ画像処理に慣れてきた頃でしょうか.少し画像処理を離れて一休憩します.
研究をやっている時や論文を書いている時に,グラフを書きたいことが多々あります.その時にはどんなソフトを使えばいいでしょうか? Windows の場合は Excel でしょうか.確かにそれも選択肢の一つです.ただ研究用には昔から使われている gunuplot が一番いいと思います.自由度が高くて使いやすいです.まずはインストールしてみましょう.
www.gnuplot.info に情報が載っていますが, http://sourceforge.net/project/showfiles.php?group_id=2055 からソースコードや実行ファイルをダウンロードできます.現在(2009/4)の最新バージョンは4.2.5です.Windows の場合は gp425win32.zip をダウンロードします.同時に gnuplot-4.2.5.pdf を印刷して手元に置いておきましょう.ファイルを解凍すると gnuplot というディレクトリができますので,C:\Program Files に移動して bin\wgnuplot.exe のショートカットをデスクトップにコピーするか,スタートメニューに登録しておくと便利です. Linux の場合も上記のサイトからダウンロードできますが,ディストリビューションによっては Debian なら aptitude install gnuplot でパッケージがインストールされます.
使い方は Windows の場合は bin\wgnuplot.exe のアイコンをクリックします.この時,Windows版ではなぜかフォントが小さくて見にくいので,窓上でマウスを右クリック Choose Font でフォントのサイズを 10 か 14 あたりにしておきましょう.フォントを選んだ後は再び右クリックで Update しておきます. Linux の場合はコマンドで gnuplot と打つだけです.これでグラフ描画環境が整いました.
窓内で plot 0.5, x, sin(x) と打ってみましょう. の3つのグラフが表示されるはずです.gnuplotでは定義域や値域は自動的に決められるので,強制的に1周期分だけ出したいなどという時には plot [-pi:pi][-2:2] 0.5, x, sin(x) と打ちます.
また,は sqrt(x) ,は 2**x ,は exp(x) で表現できます.gnuplot に関して分からないことがあればこのページを調べると大体が載っています.ここでは3次元プロットなどについては採り上げませんので,先ほどのページを参考にすると良いと思います.
演習3−1
式をグラフにしましたが,次はファイルを使ってグラフを書く方法を説明します.
31 53
25 44
42 23
54 41
と書いたファイルを作り,test.txt と名前をつけます.そして test.txt があるディレクトリに cd '\tmp' のように移動して下さい.Windows の場合は ChDir ボタンでも移動できるようです.
次に,plot "test.txt" u 1 と打つとグラフがでます.見にくいときは plot [-1:4][0:70] "test.txt" u 1 のように変域を指定しましょう.plot "test.txt" u 1 は plot "test.txt" u 1 with points を略したものです. plot "test.txt" u 1 with lines で折れ線に,plot "test.txt" u 1 with linespoints で折れ線にポイントがついたグラフに変更できます.これらは順に plot "test.txt" u 1 w p や plot "test.txt" u 1 w l や plot "test.txt" u 1 w lp と略すこともできます.分かるとは思いますが with を w に,points を p に lines を l に略しているのです.
さてグラフと test.txt を見比べてみましょう.これは何をグラフにしていることになるのでしょうか.よく考えて見ましょう.
そうです,ファイルの一列目の 31, 25, 42, 54 がグラフになっています. plot "test.txt" u 1 はファイルの一列目のデータを使ってグラフを描けという意味で plot "test.txt" using 1 を意味しているのです.では二列目の 53, 44, 23, 41 をグラフにしたければどうすれば良いでしょうか.簡単です.plot "test.txt" u 2 でいいのです.2つのグラフを書きたければ plot "test.txt" u 1 w lp, "test.txt" u 2 w lp と打つと左下のようなグラフを書くことができます(変域は適当に設定).
一列目と二列目を足したグラフを書きたければどうすればいいでしょうか. plot "test.txt" u 1+2 ではどうでしょうか.残念ながらエラーになります.この場合は u ($1+$2) と書きます.単に (1+2) だと 3 になってしまいますので,$ を付けて『?番目の数字』を意味するようにします.plot [-1:4][0:110] "test.txt" u 1 w lp, "test.txt" u 2 w lp, "test.txt" u ($1+$2) w lp で三つのグラフが表示されます.
さて,u 1 は,文字通り『一列目を使え』で, y 軸に一列目の値を持つグラフが描かれます.では x 軸は何ですか?
これはファイルの行数ですね.つまり (x,y) において (0,31) (1,25) (2,42) (3,54) をグラフにしているのです. ファイルの行数が0列目に書かれていると考え plot "test.txt" u 1 は plot "test.txt" u 0:1 を略したものになっています.u 0:1 は『 x 軸にファイルの0列目(つまり行数),y 軸にファイルの一列目を使え』という意味なんです.
では, plot "test.txt" u 1:2 あるいは plot "test.txt" u 1:2 w lp と書けばどんなグラフになるでしょうか.描いたグラフとファイルを見比べてよく考えてみて下さい.
演習3−2
1円玉,5円玉,10円玉,50円玉,100円玉,500円玉が入る箱があって,それぞれの箱には30枚,200枚,450枚,300枚,200枚,100枚入っているとします.この箱の様子をグラフで表現する場合には,
30
200
450
300
200
100
というファイルを作ってグラフにすると,どの箱に硬貨が何枚入っているか分かります.このような箱の集合をヒストグラムといいます.一つ一つの箱のことをビンといいます(瓶ではないです…).ヒストグラムを gnuplot w boxes を使って棒グラフにしてみました.一目で3番目(2)のビンに硬貨がたくさん入っていることが分かります.
さて画像処理に戻りましょう.下の花の写真を見て下さい.道端でよく見かけるツツジの写真ですが,ぱっと見て『緑色の葉の中に紫の花がある』と感じるでしょう.これを画像処理的に説明するにはどうすればよいでしょうか.それぞれの画素のRGBを HSI に変換します.そして,H をビンとしたヒストグラムを作るのです.ただし, H は0〜2πなので,それを360度の角度に変換し,1度刻みのビンを作りましょう.ビンの中にはその色を持つ画素数が入ります.プログラムは次のようになります.画像は flower.zip を使って下さい.
main(){ float H; int h; int bin[360]; image = malloc(sizeof(char)*640*480*3); ppm_read("flower3.ppm", image); //ファイルの読み込み for(x=0;x<360;x++) bin[x] = 0; //初期化 for(y=0;y<480;y++){ for(x=0;x<640;x++){ //HSI の H を計算する ・・・ h = (int)(H*360/(float)(2.0*PI)); //ラジアン H (0〜2π)を度 h (0〜359)に変換 bin[h]++; } } for(x=0;x<360;x++) fprintf(fp,"%d\n",bin[x]); //ビンの書き出し } |
演習3−3