「細線化処理プログラムサンプル」の編集履歴(バックアップ)一覧はこちら

細線化処理プログラムサンプル」(2005/10/24 (月) 10:36:18) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p>私は Hilditch の細線化手法を用いて2値画像を細線化するプログラムを作成したのですが、アルゴリズムは次のような感じです。</p> <p>// 無限ループ<br> while(1){<br> // 画像をラスタスキャン<br> for(y=0 ; y &lt; ymax ; y++){<br> for(x=0 ; x &lt; xmax ; x++){<br> // 注目画素が対象領域なら<br> if( data[y][x] == 1 ){<br> 背景画素にできる画素か判定する・・・①<br> }<br> }<br> }</p> <p>// 背景にできる画素を背景画素にする<br> count = 0;// 背景にできる画素の個数カウント<br> for(y=0 ; y &lt; ymax ; y++){<br> for(x=0 ; x &lt; 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 &lt; 8 ; n+=2){<br> sum += !( data[ y+py[n] ][ x+px[n] ] );<br> }<br> if( !( sum &gt;= 1 ) ){<br>   return( data[y][x] );<br> }</p> <p>// 条件3 - 端点を削除しない条件<br> sum = 0;<br> for(int n=0; n &lt; 8 ; n++){<br>   sum += abs( data[ y+py[n] ][ x+px[n] ] );<br> }<br> if( !( sum &gt;= 2 ) ){<br>   return( data[y][x] );<br> }</p> <p>// 条件4 - 孤立点を保存する条件<br> sum = 0;<br> for(int n=0; n &lt; 8 ; n++){<br>   if( data[ y+py[n] ][ x+px[n] ] == 1 ){<br>     sum++;<br>   }<br> }<br> if( !( sum&gt;=1 ) ){<br>   return( data[y][x] );<br> }</p> <p>// 条件5 - 連結性を保存する条件<br> sum = 0;<br> for(int n=0; n &lt; 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 &lt; 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 &lt; 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 &lt; 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>

表示オプション

横に並べて表示:
変化行の前後のみ表示:
記事メニュー
目安箱バナー