pタイル法の課題が出て難しい解説ばかりだったので今日は簡単に思えるように説明していきます。
pタイル法とは
pタイル法は簡単に説明すると上のような画像の画素値分布のグラフがあったときに、グラフを見ていい感じのところを閾値に設定するという方法です。
この場合だと大体90くらいに設定するのが良いと思います。
このようにグラフを見れば簡単な方法ですが、プログラムするとなると少しむずかしいですよね。
その手順を解説します。
実装手順
まず関数の入力は「入力画像」と「2値化の基準とする値の画素全体に対する割合」
出力は出力画像となります。
そして求めたいのが、「2値化の基準とする値の画素全体に対する割合」のときの画素値です。
①入力画像に対して、それぞれの画素値に対して何個の画素があるか計算する。
とてもわかりにくいこと言ってますが、
画素値が0の画素は15個
画素値が1の画素は30個
画素値が2の画素は56個
・・・
画素値が255の画素は4個
というように計算していきます。
プログラムではこの部分に当たります。
for(y=0;y<img1->s.y;y++){
for(x=0;x<img1->s.x;x++){
for(i=0;i<=255;i++){ //輝度のループ
if(img1->val[x][y]==i){ //輝度のカウント
kido[i]=kido[i]+1;
}
}
}
}
できた値をprintfでもして書き出してエクセルなどでグラフにするとこのようになります。
グラフを見れば閾値にするべき値は簡単にわかりますが、プログラムですのでそう簡単にはいきません。
②画素の総和の計算をする
次に画素の総和の計算をします。
for(i=0;i<=255;i++){ //すべての画素値の合計の計算,画素値は255までだからそこまでループ
printf("画素値\t%d\t数\t%d\t総和\t%d\n",i,kido[i],allData); //デバッグ用
allData =allData + kido[i];
}
この部分ですね。alldataをループの度にprintfすればその値でこのようなグラフがかけます。
このようにかけます。
プログラムではこのグラフを見て、画素値が90の場所の割合を見てそれを入力値とします。
ただし、この90というのは結果論なのでもともとはわかっていないことに注意してください。(自分でも何言ってるかわからなくなってきた)
つまりその割合がrateの値になります。
まあグラフをみてもらえばわかるでしょう。
③画素値が(今回の場合だと)90以下の画素数を記録する。
画素値が90以下のものを記録します。このときに入力値であるrateつまり90あたりの割合が役に立ちます。
th1 =allData*rate; //rateまでの合計
これで計算できます。
④th1になるときの画素値を記録する。
allData=0;
/*th1より大きくなるときの画素値を閾値にする*/
for(i=0;i<=255;i++){
allData =allData + i*kido[i];if(allData > th1){ //th1より大きくなったら、その時の画素値をth2に記録し、ループから抜ける。
th2 = i;
break;
}
}
こんな漢字にします。
こうすることでやっと割合から閾値にしたい画素値を求めることができました。
⑤求めた閾値で2値化
後はいつもどおり2値化するだけです。
最後にコードを載せておきます。
実際のコード
以上です。
お役に立つと嬉しいです。