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