ようやくlibpngの話が終わって、グラフの解析に。まずやるべきは、グラフの枠線の範囲を特定することでしょう。本当は決めうちでハードコーディングしたかったんだけど、どうやらグラフによって枠線の範囲が違ってくるようなので、毎回測定することにします。
原理は簡単で、上下(横方向)左右(縦方向)の端から画像を見ていって、長い線があれば枠線と判断する・・・というもの。
#define SEQ_TO_REGARD_AS_BORDER 50 typedef struct _graph_area{ png_bytepp image; int width; int height; int top; int left; int bottom; int right; } graph_area; void get_graph_border(graph_area *g) { int i, j; png_bytep buf = (png_bytep)malloc(g->height * sizeof(png_byte)); /* buffer for column */ for(i=0, g->top=-1; i<g->height; i++){ if(find_sequence(g->image[i], g->width, SEQ_TO_REGARD_AS_BORDER)){ g->top = i; break; } } for(i=g->height-1, g->bottom=-1; i>=0; i--){ if(find_sequence(g->image[i], g->width, SEQ_TO_REGARD_AS_BORDER)){ g->bottom = i; break; } } for(i=0, g->left=-1; i<g->width; i++){ for(j=0; j<g->height; j++){ buf[j]=g->image[j][i]; } if(find_sequence(buf, g->height, SEQ_TO_REGARD_AS_BORDER)){ g->left = i; break; } } for(i=g->width-1, g->right=-1; i>=0; i--){ for(j=0; j<g->height; j++){ buf[j]=g->image[j][i]; } if(find_sequence(buf, g->height, SEQ_TO_REGARD_AS_BORDER)){ g->right = i; break; } } free(buf); printf("graph border: t=%d b=%d l=%d r=%d\n", g->top, g->bottom, g->left, g->right); } int find_sequence(png_bytep image, int size, int n) { int i, cnt, prev=image[0]; for(i=1; i<size; i++){ if(image[i] != 0){ if(prev == 0) cnt = 0; if(++cnt >= n) return 1; } prev = image[i]; } return 0; }
今後役立ちそうなのでgraph_area構造体を定義しました。
実行結果は次の通り。ディレクトリ"../l/"には、リストアップした声優のグラフ画像が保存されてます。ファイル名はキーワードをURIエスケープした文字列で、例えば後藤邑子なら「%B8%E5%C6%A3%CD%B8%BB%D2」がファイル名に付いてます。
$ ls ../l/*.png | while read file > do > echo $file | perl ../../decode.pl > ./png $file > echo > done > border.list
最後のechoは、paragraphに区切ることでパラグラフ単位のgrepをするため。
$ grep "^graph border:" border.list | sort | uniq -c | sort -r 285 graph border: t=17 b=161 l=32 r=389 191 graph border: t=17 b=161 l=21 r=389 136 graph border: t=17 b=161 l=27 r=389 120 graph border: t=17 b=161 l=26 r=389 3 graph border: t=17 b=161 l=31 r=389
ほう。上下はみんな同じだけど、左右の幅が違うようですが、これは後述の縦軸のMAX値と関係しています。それよりも、3つしか出てない枠線を持つグラフが気になりますが・・・。
$ pgrep "graph border: t=17 b=161 l=31 r=389" border.list ../l/茅原実里.html.png input file: [../l/%B3%FD%B8%B6%BC%C2%CE%A4.html.png] png signature: 89 50 4e 47 0d 0a 1a 0a graph border: t=17 b=161 l=31 r=389 ../l/後藤邑子.html.png input file: [../l/%B8%E5%C6%A3%CD%B8%BB%D2.html.png] png signature: 89 50 4e 47 0d 0a 1a 0a graph border: t=17 b=161 l=31 r=389 ../l/田村ゆかり.html.png input file: [../l/%C5%C4%C2%BC%A4%E6%A4%AB%A4%EA.html.png] png signature: 89 50 4e 47 0d 0a 1a 0a graph border: t=17 b=161 l=31 r=389
いずれもMAXが100の声優さんたちのようです。ちなみにpgrepはプロセスのgrepじゃなくてgrep -pへのエイリアス*1。