「細線化処理プログラムサンプル」の編集履歴(バックアップ)一覧はこちら
「細線化処理プログラムサンプル」(2005/10/24 (月) 10:36:18) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p>私は Hilditch
の細線化手法を用いて2値画像を細線化するプログラムを作成したのですが、アルゴリズムは次のような感じです。</p>
<p>// 無限ループ<br>
while(1){<br>
// 画像をラスタスキャン<br>
for(y=0 ; y < ymax ; y++){<br>
for(x=0 ; x < xmax ; x++){<br>
// 注目画素が対象領域なら<br>
if( data[y][x] == 1 ){<br>
背景画素にできる画素か判定する・・・①<br>
}<br>
}<br>
}</p>
<p>// 背景にできる画素を背景画素にする<br>
count = 0;// 背景にできる画素の個数カウント<br>
for(y=0 ; y < ymax ; y++){<br>
for(x=0 ; x < xmax ; x++){<br>
if( data[y][x] == -1 ){<br>
data[y][x] = 0;<br>
count++;<br>
}<br>
}<br>
}<br>
// 背景にできる画素がなかったので細線化処理の終了<br>
if( count == 0 ){<br>
break;<br>
}<br>
}</p>
<p><br>
①の部分は関数化する<br>
注目画素が以下の6つの条件をみたす場合削除してもいい画素<br>
として、値を -1 にしておく</p>
<p>条件1:対象領域の画素である<br>
条件2:境界画素である<br>
条件3:端点を削除しない<br>
条件4:孤立点を保存する<br>
条件5:連結性を保存する<br>
条件6:線幅が2の線分に対して、その片側のみを削除する</p>
<p>
あんまり詳しい説明になりませんでしたが、このような感じです。条件の部分についてはソースを載せたらいいんでしょうが、私のプログラムはきたないので今回は載せませんでした。<br>
それでもよければ載せますが(^^;)</p>
<p><br>
[259] ありがとうございます。 返信 削除<br>
▽ 2003/12/18 (木) 13:48:53 ▽ murakami<br>
p2005-ipbffx01daianji.nara.ocn.ne.jp / Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1)</p>
<p>いっくんさんレスありがとうございます。<br>
数日頭を悩ませていますので。<br>
ソースをのせていただければ参考にしたいと思っています。<br>
お願いします。</p>
<p><br>
[260] ソースです(^^;) 返信 削除<br>
▽ 2003/12/18 (木) 14:08:12 ▽ いっくん<br>
ufproxy.osakac.ac.jp / Mozilla/5.0 (Windows; U; Win98; ja-JP; rv:1.0.1)
Gecko/20020823 Netscape/7.0</p>
<p>
/****************************************************************************<br>
* ThinLineJudge()<br>
* [ 処理概要 ]<br>
* 対象画素に対して消してもいい画素かどうか判断する<br>
* [ 引数の説明 ]<br>
* char **data // 2値データ(0,1)が格納された2次元配列<br>
* int x // x座標<br>
* int y // y座標<br>
* [ 戻り値 ]<br>
* -1 // 削除してもいい画素<br>
* data[y][x] // 削除してはダメな画素(元の値)<br>
****************************************************************************/<br>
char ThinLineJudge(char **data, int x, int y)<br>
{<br>
// px,py配列は注目画素と8近傍画素との位置関係を示す<br>
int px[8] = { 1, 1, 0,-1,-1,-1, 0, 1};<br>
int py[8] = { 0,-1,-1,-1, 0, 1, 1, 1};<br>
int sum,sum2,c1,c2,c3;<br>
char sub[3][3] = {{0}};</p>
<p>// 条件2 - 境界画素である条件<br>
sum = 0;<br>
for(int n=0; n < 8 ; n+=2){<br>
sum += !( data[ y+py[n] ][ x+px[n] ] );<br>
}<br>
if( !( sum >= 1 ) ){<br>
return( data[y][x] );<br>
}</p>
<p>// 条件3 - 端点を削除しない条件<br>
sum = 0;<br>
for(int n=0; n < 8 ; n++){<br>
sum += abs( data[ y+py[n] ][ x+px[n] ] );<br>
}<br>
if( !( sum >= 2 ) ){<br>
return( data[y][x] );<br>
}</p>
<p>// 条件4 - 孤立点を保存する条件<br>
sum = 0;<br>
for(int n=0; n < 8 ; n++){<br>
if( data[ y+py[n] ][ x+px[n] ] == 1 ){<br>
sum++;<br>
}<br>
}<br>
if( !( sum>=1 ) ){<br>
return( data[y][x] );<br>
}</p>
<p>// 条件5 - 連結性を保存する条件<br>
sum = 0;<br>
for(int n=0; n < 8 ; n+=2){<br>
c1 = ( abs( data[ y+py[n] ][ x+px[n] ] ) == 1 )? 1 : 0;<br>
c2 = ( abs( data[ y+py[n+1] ][ x+px[n+1] ] ) == 1 )? 1 : 0;<br>
c3 = ( abs( data[ y+py[(n+2)%8] ][ x+px[(n+2)%8] ] ) == 1 )? 1 : 0;<br>
sum += !(c1) - !(c1) * !(c2) * !(c3);<br>
}<br>
if( !( sum == 1 ) ){<br>
return( data[y][x] );<br>
}</p>
<p>// 条件6 -
線幅が2の線分に対して、その片側のみを削除する条件<br>
sum2 = 0;<br>
for(int i=0 ; i < 8 ; i++){<br>
if( data[ y+py[i] ][ x+px[i] ] != -1 ){<br>
sum2++;<br>
continue;<br>
}<br>
// subに対象画素の8近傍を格納<br>
for(int n=0 ; n < 8 ; n++){<br>
sub[ 1+py[n] ][ 1+px[n] ] = data[ y+py[n] ][ x+px[n] ];<br>
}<br>
sub[ 1+py[i] ][ 1+px[i] ] = 0;</p>
<p> sum = 0;<br>
for(int n=0; n < 8 ; n+=2){<br>
c1 = ( abs( sub[ 1+py[n] ][ 1+px[n] ] ) == 1 )? 1 : 0;<br>
c2 = ( abs( sub[ 1+py[n+1] ][ 1+px[n+1] ] ) == 1 )? 1 : 0;<br>
c3 = ( abs( sub[ 1+py[(n+2)%8] ][ 1+px[(n+2)%8] ] ) == 1 )? 1 :
0;<br>
sum += !(c1) - !(c1) * !(c2) * !(c3);<br>
}<br>
if( !(sum == 1) ){<br>
break;<br>
}<br>
sum2++;<br>
}<br>
return( (sum2 == 8)? (char)-1 : data[y][x] );<br>
}<br></p>
表示オプション
横に並べて表示:
変化行の前後のみ表示: