実験7-1
画像処理基礎2
1 目的 画像をコンピュータ上で処理するサイの基本事項について学ぶ。画像の変換、画像 フィルタ、画像の特徴抽出とパターン分類などの具体的なプログラミングを試みるこ とにより、ディジタル画像処理の基本的な手順、手法及びシステム構成について理解 する。 2 解説 前回の実験と同様のため省略する。3 実験 実験3-1 【2値化-1】 ( ) 。 2値化処理を行って画像Fの中の明るい 暗い 領域を抽出することを考える P-タイル法によって2値化閾値選択を行い、画像を2値化するプログラムを作 成せよ。作成したプログラムが正しく動作していることを適当な画像を用いて検 証せよ。そして、画像Fに適用して2値化画像Gを作成し、モニターに表示して 確認せよ。いろいろなタイプの画像に適用して試し、作成したプログラムの機能 と効果を検証せよ。 実験3-2 【2値化-2】 ( ) 。 2値化処理を行って画像Fの中の明るい 暗い 領域を抽出することを考える モード法によって2値化閾値選択を行い、画像を2値化するプログラムを作成せ よ。作成したプログラムが正しく動作していることを適当な画像を用いて検証せ よ。そして、画像Fに適用して2値化画像Gを作成し、モニターに表示して確認 せよ。いろいろなタイプの画像に適用して試し、作成したプログラムの機能と効 果を検証せよ。 実験3-3 【2値化-3】 ( ) 。 2値化処理を行って画像Fの中の明るい 暗い 領域を抽出することを考える 微分ヒストグラム法によって2値化閾値選択を行い、画像を2値化するプログラ ムを作成せよ。作成したプログラムが正しく動作していることを適当な画像を用 いて検証せよ。そして、画像Fに適用して2値化画像Gを作成し、モニターに表 示して確認せよ。いろいろなタイプの画像に適用して試し、作成したプログラム の機能と効果を検証せよ。 実験3-4 【2値化-4】 ( ) 。 2値化処理を行って画像Fの中の明るい 暗い 領域を抽出することを考える 判別分析法によって2値化閾値選択を行い、画像を2値化するプログラムを作成 せよ。作成したプログラムが正しく動作していることを適当な画像を用いて検証 せよ。そして、画像Fに適用して2値化画像Gを作成し、モニターに表示して確 認せよ。いろいろなタイプの画像に適用して試し、作成したプログラムの機能と 効果を検証せよ。 実験3-5 【2値化-5】 ( ) 。 2値化処理を行って画像Fの中の明るい 暗い 領域を抽出することを考える 可変閾値法によって2値化閾値選択を行い、画像を2値化するプログラムを作成 せよ。作成したプログラムが正しく動作していることを適当な画像を用いて検証 せよ。そして、画像Fに適用して2値化画像Gを作成し、モニターに表示して確 認せよ。いろいろなタイプの画像に適用して試し、作成したプログラムの機能と 効果を検証せよ。
4 実験方法 今回の実習で使用した基本プログラムを以下に示す。また、これ以降に示すプログ ラムは変更箇所のみとする。 基本プログラム < > #include stdio.h < > #include stdlib.h #define MAX 400000 #define MOJI 4 ( ) int main void { FILE *fp; FILE *fp2; FILE *fp3; char c 1000 ;[ ] int data2 480 640 ;[ ][ ] int out 480 640 ;[ ][ ] int glf 480 640 ;[ ][ ] int hist 256 ;[ ] float inp; float sum; int line; int lib; int n,m; int nm=1000; // nma-ku int flg=0; int count1=0; int count2=0; int count3=0; int count4=0; //read (( ( )) ) {
if fp = fopen "sample01.pgm", "r" == NULL printf "file open error!!¥n¥n" ;( )
exit 1 ;( ) }
( < ){ for count1=0;count1 MAX;count1++
fscanf fp,"%c",&c count1 ;( [ ]) if c count1 =='¥n' count3++;( [ ] ) if count3 == MOJI break;( ) } ( < ){ for n=0;n 480;n++ ( < ){ for m=0;m 640;m++ fscanf fp,"%d",&data2 n m ;( [ ][ ]) } } fclose fp ;( ) printf "( よみこみ終了¥n¥n¥n" ;) ヒストグラムをデータで作成 // ( < ) for n=0;n 256;n++ hist n =0;[ ] ( < ){ for n=0;n 480;n++ ( < ){ for m=0;m 640;m++ lib=data2 n m ;[ ][ ] hist lib ++;[ ] glf n m =255;[ ][ ] } } ヒストグラムを画像で作成 // ( < ){ for n=50;n 255+50;n++ ( < [ ] ){ for m=45;m-45 hist n-50 /16;m++ glf n m =150;[ ][ ] } } 編集箇所 閾値 の計算 // line
printf "sikiiti=%d¥n",line ;( ) ( < ){ for n=0;n 480;n++ ( < ){ for m=0;m 640;m++ ( [ ][ ]> ) if data2 n m line out n m =255;[ ][ ] else out n m =0;[ ][ ] } } ( < ){ for n=50;n 255+50;n++ ( < [ ] ){ for m=45;m-45 hist n-50 /16;m++ ( ) if n-50 == line glf n m =0;[ ][ ] } } グラデーションの作成 // ( < ){ for n=50;n 255+50+1;n++ ( < ){ for m=0;m 40;m++ (( ) ) if n-50 %16==0 && m%4==0 glf n m =255;[ ][ ] ( ) else if n-50 == line nm=n-50; else if n-50==nm || n-50==nm+1 || n-50==nm-1 ||( ) n-50==nm+2 || n-50==nm-2 glf n m =255;[ ][ ] else glf n m =n-50;[ ][ ] ( ) if n==255+50 glf n m =0;[ ][ ] } glf n m =0;[ ][ ] }
//write1
(( ( )) ) {
if fp2 = fopen "out001.pgm", "w" == NULL printf "file open error!!" ;( )
exit 1 ;( ) }
( < ){
for count2=0;count2 count1;count2++ fprintf fp2,"%c",c count2 ;( [ ]) } fprintf fp2,"¥n" ;( ) ( < ){ for n=0;n 480;n++ ( < ){ for m=0;m 640;m++ fprintf fp2,"%4d",glf n m ;( [ ][ ]) } fprintf fp2,"¥n" ;( ) } fclose fp2 ;( ) printf "¥n¥n¥n( 書き込み1終了¥n¥n¥n" ;) //write2 (( ( )) ) {
if fp3 = fopen "out011.pgm", "w" == NULL printf "file open error!!" ;( )
exit 1 ;( ) }
( < ){
for count2=0;count2 count1;count2++ fprintf fp2,"%c",c count2 ;( [ ]) } fprintf fp2,"¥n" ;( ) ( < ){ for n=0;n 480;n++ ( < ){ for m=0;m 640;m++ fprintf fp2,"%4d",out n m ;( [ ][ ]) } fprintf fp2,"¥n" ;( ) } fclose fp2 ;( ) printf "¥n¥n¥n( 書き込み2終了¥n¥n¥n" ;) return 0; }
基本プログラムについて 入力ファイルから文字データと画素データを抽出し 出力する手順は前回の 画、 『 像処理基礎1』の実験で使用したプログラムと同様である。今回の実験ではどの 画素がどの程度使われているのかを示した、画素データのヒストグラムが必要に なる。グラフで出力する方法もあるが、今回は画像として出力することにした。 下図はモード法を使用したときにできたヒストグラムである。左側に示されて いる濃度の画素数がヒストグラムとして表れている。ヒストグラムで濃く表示さ れている部分は、モード法で使用された『山1』、『谷』、『山2 、それぞれであ』 る。これを出力することによって、どの程度の濃度が閾値なのかを確認出来るだ けでなく、プログラムが正常に閾値を決定している様子まで確認出来る。 モード法を使用した場合のヒストグラム out001:
実験3-1 【P-タイル法】 画像全体に対する対象物の面積の割合を入力することによって、閾値を決定す る。 入力された割合が黒、それ以外が白になるような閾値を計算する。 修正プログラム:P-タイル法 printf "( 画像全体に対する対象物の面積の割合を入力¥n" ;) scanf "%f",&inp ;( ) ( < ){ for n=0;n 256;n++ sum+=hist n ;[ ] (( ( ) ) > ) if sum/ 480*640 *100 = inp break; } line=n;
実験3-2 【モード法】
それぞれの画素の濃度をヒストグラムにしたとき、ヒストグラムの谷になる部 分を閾値とする。
今回使用するプログラムは一番高い山 top を基準として、それ以外の全ての 山 top2と top との間にある谷 be を検索する。top2 引く be が最大となった場 合に、 beを閾値とした。 修正プログラム:モード法 モード法 // ( < ){ for n=0;n 256;n++ ( [ ] > ){ if hist n histmax histmax=hist n ;[ ] histnmax=n; } } ( < ){ for n=1;n 255;n++ ( [ ] > [ ] [ ] > [ ] < if hist n hist n-1 && hist n hist n+1 && n ){ histnmax ( < ){ if n histnmax ( < ){ for m=n;m histnmax;m++ ( > [ ]){ if be hist m be=hist m ;[ ] be2=m; } } } { else ( > ){ for m=n;m histnmax;m--( > [ ]){ if be hist m be=hist m ;[ ] be2=m; } } } ( < [ ] ){ if hi hist n -be hi=hist n -be;[ ]
top=n; topbe=be2; } } } line=topbe; printf "sikiiti=%3d¥n",line ;( )
printf "max( =%3d¥n",histnmax ;) printf "max2( =%3d¥n",top ;)
ヒストグラムの画像を編集 // ( < ){ for n=50;n 255+50;n++ ( < [ ] ){ for m=45;m-45 hist n-50 /16;m++ ( ) if n-50 == histnmax glf n m =0;[ ][ ] ( ) if n-50 == top glf n m =0;[ ][ ] ( ) if n-50 == line glf n m =0;[ ][ ] } }
実験3-3 【微分ヒストグラム法】 、 。 ある画素を中心としたまわり8画素との差を合計し ヒストグラムを作成する 作成したヒストグラムで最大となる点を閾値とする。 3×3の範囲を右に示す。 eの場合の計算式は、 hist[e]=|e-a|+|e-b|+|e-c |+|e-d|+|e-f|+|e-g|+|e-h|+|e -i|+|e-j| となる。 修正プログラム:微分ヒストグラム法 配列の初期化 // ( < ) for n=0;n 256;n++ hist n =255;[ ] 微分ヒストグラム法 // ( < ){ for n=1;n 479;n++ ( < ){ for m=1;m 639;m++ lib=data2 n m ;[ ][ ] ( < ){
for count5=0;count5 3;count5++
( < ){
for count6=0;count6 3;count6++
( [ ][ ] [ ][ ] < if data2 n m -data2 n+count5-1 m+count6-1 )
0
[ ] ( [ ] [ ] [ ]
hist lib += data2 n m -data2 n+count5-1 m+count6-1 * -1 ;
[ ]) ( ) else
[ ] [ ] [ ] [ ]
hist lib +=data2 n m -data2 n+count5-1 m+count6-1 ;
[ ]
} }
( [ ]> ){ if hist lib histmax
histmax=hist lib ;[ ] libm=lib; } } line=topbe; }
実験3-4 【判別分析法】 画像中の全画素を2つのクラス分け、2つのクラス間の分離が最大になるに閾値を 計算する。 画素値の平均がμ、分散がδ の画像を、閾値tで2値化したとき、2 画素値がt以上の画素の平均μ 、分散δ1 12 画素値がt未満の画素の平均μ 、分散δ2 12 δ ={ μ -μ) +(μ -μ) }/2a2 ( 1 2 2 2 δb2 = δ +δ12 12 δa2 /δb2 が最大となるtを計算する。 編集プログラム:判別分析法 max = -1.0; ( < ) { for t = 0; t t_limit; t++ n1 = n2 = 0; ave1 = ave2 = 0; var1 = var2 = 0; tmp= 0; ( < ) { for i = 0; i t; i++ n1 = n1 + hist i ;[ ] tmp = tmp + hist i *i;[ ] } クラス について平均を求める // 1 ( ) { if n1 != 0
ave1 = (double tmp / double n1;) ( ) }
( < ) { for i = 0; i t; i++
var1 = var1 + i-ave1 * i-ave1 *hist i ;( ) ( ) [ ] }
クラス について分散を求める
// 1
( ) {
if n1 != 0
var1 = var1/ double n1;( ) }
tmp = 0;
( < ) {
for i = t; i t_limit; i++ n2 = n2 + hist i ;[ ] tmp = tmp + hist i *i;[ ] }
クラス について平均を求める
// 2
( ) {
if n2 != 0
ave2 = double tmp / double n2;( ) ( ) }
( < ) {
for i = t; i t_limit; i++
var2 = var2 + i-ave2 * i-ave2 *hist i ;( ) ( ) [ ] }
クラス について分散を求める
// 2
( ) {
if n2 != 0
var2 = var2/ double n2;( ) }
var_w = n1*var1 + n2*var2 ;( )
var_b = n1* ave1-ave * ave1-ave( ) ( ) + n2* ave2-ave *( ) ave2-ave ; ( ) r = var_b / var_w; ( > ) { if r max max = r; max_t = t; } } line=max_t;
3-5 【可変閾値法】 画像を適当な個数に分割し、それぞれの画像で閾値を計算する。閾値の計算は最も 綺麗だった判別分析法を使用した。 編集プログラム:可変閾値法 printf "( 分割数の入力¥n縦: )" ; scanf "%d",&tate ;( ) printf "( 横: )" ; scanf "%d",&yoko ;( ) ( < ){
for count1=0;count1 tate;count1++
( < ){
for count2=0;count2 yoko;count2++ ヒストグラムをデータで作成 // sum=0; ( < ) for n=0;n 256;n++ hist n =0;[ ] ( < ( ) ){
for n=480/tate*count1;n 480/tate* count1+1 ;n++
( < ( ) ){
for m=640/yoko*count2;m 640/yoko* count2+1 ;m++ lib=data2 n m ;[ ][ ]
hist lib ++;[ ] sum+=lib; }
}
ave=sum/ 480/tate * 640/yoko ;(( ) ( )) 判別分析法省略
//
line=max_t;
( < ( ) ){
for n=480/tate*count1;n 480/tate* count1+1 ;n++
( < ( ) ){
for m=640/yoko*count2;m 640/yoko* count2+1 ;m++ ( [ ][ ]> ) if data2 n m line out n m =255;[ ][ ] else out n m =0;[ ][ ] } } printf "%3d-%3d:%3d¥n",count1,count2,line ;( ) } }
5 実験結果 下に示す画像を元の画像として、それぞれの2値化処理をおこなう。 グラフ1-1~1-4及び画像1-1~1-4は以下のように処理する。 ①P-タイル法 ① ② ②モード法 ③微分ヒストグラム法 ③ ④ ④判別分析法 元の画像:画像1
それぞれのヒストグラム:グラフ1-1 ~ グラフ1-4
inp = 40 top = 127 top2 = 46
line = 120 line = 102
line = 0 line = 103
可変閾値法 対象物は左上、右下、左下、の3つ。それぞれの閾値を分けるためには、 2×2以上の分割が必要。背景については、画像上部が濃く、下へ下がるほ ど薄くなっているグラデーションが存在する。このグラデーションの中から 文字を取り出すには縦の分割数を増やす必要がある。分割ラインを赤の点線 で、それぞれの領域の左上に閾値を示す。 分割数:2×2 分割数:5×2 画像1-5-1 画像1-5-2 分割数:8×2 分割数:10×2 画像1-5-3 画像1-5-4
分割数:30×40 画像1-5-5
5 考察 (4)実験3-1~実験3-5の結果について詳しく説明せよ。特に、画像データを いろいろと変えて試した結果について詳しく考察せよ。 -タイルについて P 対象物の面積は把握出来ないので、適当な値を探すしかない。何度か 数値を変え、対象物が見える値に設定。今回行った手法の中で唯一入力 によって閾値を求めるが、対象物が複雑な場合は何度も入力し、出力を 確認する必要性がある。 モード法について グラフに山も谷も存在するので、設定は比較的簡単である。 微分ヒストグラム法について 閾値は0だが、失敗ではない。微分ヒストグラムを見て貰えば正しい ことは確認出来る。つまり、値”0”を境界線と判断し ”0”だけを、 、 ( ) 。 、 黒とし それ以外を全て白 255 とした状態である これによって もともと”0”だった場所しか残らないため、他の画像と比べると画像 が綺麗でないことは明らかである。 判別分析法について この画像ではモード法との違いが表れなかった。これは画素のヒスト グラムに山も谷も綺麗に存在するからである。 可変閾値法について 分割数5×2の段階で閾値の境界線が確認出来てしまう。この境界線 は数を増やしていっても変わらず、綺麗な画像とは言い難い。結果とし て出力された画像は2×2分割が綺麗だが、30×40分割のような画 像を境界線無しで出力出来れば最も綺麗な画像になることは間違いな い。
(5)実験3-1~実験3-5の各々の手法の特徴、長所と短所について比較検討せ 。 、 。 よ また 各々の手法がどのような画像に適している/適していないか考察せよ -タイルについて 【資料1 P.22~23参照】 P 対象物が分かりやすい画像にて、対象物の面積を大まかに求め、入力 値にしたが、綺麗な画像にはならなかった。それは必要なのは対象物の 面積ではなく、対象物を2値化したときに黒になるであろう場所の面積 が必要だからだ。そもそもそんな面積が分かっている場合とはどんな場 合だろうか。あれこれ考え、いくつか値を変えて実行し、最終的に一番 綺麗だと、思える値を設定した。しかし、最終的に決まった値は、判別 分析法によって求められた値と変わりなかった。 数値を入力することで、自由性、汎用性は生まれるが、折角のプログ ラミングなので、コンピュータに処理させたいのが本心である。 モード法について 【資料2 P.24~25参照】 画像から画素のヒストグラムを作成したときに、山と谷がはっきりと 表れる場合は有効な方法だと思われる。P-タイル以外の方法と比べる と、処理も単純で、結果も分かりやすい。しかし、ヒストグラムが複雑 だった場合、おかしな値が出てくる。これを解決するのは難しく、ヒス トグラムが複雑だと、プログラムに判断させるのも困難である。 微分ヒストグラム法について 【実験結果参照】 どの画像でも極端な処理をしてくれる。方法からも想像は出来るが、 。 、 2値化というよりエッジ検出向きの処理だと思われる アウトラインや アンチエイリアスが存在した場合、一番濃いものを抽出してしまうのも 欠点といえる。 判別分析法について 。 。 他の処理に比べると格段に性能が良い モード法の欠点も補っている いろいろな画像を試してみたが、失敗したといえる画像はなかった。 可変閾値法について 【資料3 P.26~28参照】 画像を分割し、閾値を決定することにより、複数の対象物を判別させ る方式だが、分割数を増やすと境界線が見えてしまう。この改善方法は 見つからなかった。逆に、分割数を限界近くまで増やすことによって、 境界線を目立たなくするようにも考えたが、うまくはいかなかった。 自分は2値化処理を、今回の分割数を増やした場合に出来る画像の境 界線を無くしたようなものと想像していたが、どちらかというとエッジ 検出に近い画像になってしまった。
資料1 対象物がはっきりした画像
2値化後の画像 P-タイル 閾値:136 入力: 5% モード法 閾値:39 微分ヒストグラム法 閾値: 10 判別分析法 閾値:139
資料2 画素のヒストグラムが複雑な画像 元の画像
2値化後の画像 ヒストグラム
モード法 閾値: 39
判別分析法 閾値:139
資料3 2つの対象物がある画像 元の画像 薄い 背景の濃さ 濃い 対象物B 対象物A
2値化後の画像 P-タイル法 閾値:210 判別分析法 閾値:151 可変閾司法 2×2分割 閾値=164 閾値=151 閾値=170 閾値=151
可変閾値法 30×40分割
6 感想 全体的にあまり満足出来る結果とは言い難い。これは、自分が考えていた2値 化と実際の2値化にずれがあったからなのかもしれない。可変閾値の境界線を取 ろうと努力するほど、エッジ検出に近づいていき、本来の目的の2値化から外れ てしまう。思いこみを無くすためにも、実習を行う前の段階で考えなくてはいけ ない点、調べなくてはいけない点、があるとおもう。