ある基準値を求めて、それより高いか低いかで白黒を決めるということをすればいいということはわかったのですが、それをプログラムにしようとしてもうまくいきません。
コメントの「ここで2値化」というところに当てはまる形の2値化のプログラムを教えてください。
よろしくお願いします。
環境:Linux c言語
画像: http://www.dotup.org/uploda/www.dotup.org2134415.jpg
/* Hilditch の細線化のプログラム */
#include<stdio.h>
#include<stdlib.h>
#include"mypgm.h"
#define GRAY 128
int func_nc8( int *b )
/* 注目画素の連結度(4連結)を求める関数 */
{
int n_odd[4] = { 1, 3, 5, 7 }; /* 奇数の近傍番号 */
int i, j, sum, d[10]; /* 制御変数,計算途中を代入する変数 */
for ( i = 0; i <= 9; i ++ ){
j = i; if (i==9) j = 1;
if ( abs( *( b + j ) ) == 1 ) d[i] = 1;
else d[i] = 0;
}
sum = 0;
for ( i = 0; i < 4; i ++ ){
j = n_odd[i];
sum = sum + d[j] - d[j] * d[j+1] * d[j+2];
}
return( sum );
}
void thinning( img1,img2, x_sz, y_sz)
unsigned char img1[MAX_SIZE][MAX_SIZE];
unsigned char img2[MAX_SIZE][MAX_SIZE];
int x_sz, y_sz;
/* 2値画像の細線化処理(img2[y][x] を最初は作業領域として使う)*/
/* ( = MAX_BRIGHTNESS --> 1, GRAY --> -1, 0 --> 0 とみなす) */
/* 原画像img1[y][x] ===> 処理後の画像img2[y][x] */
{
int offset[9][2] = {{0,0},{1,0},{1,-1},{0,-1},{-1,-1},
{-1,0},{-1,1},{0,1},{1,1} }; /* 近傍画素へのオフセット値 */
int n_odd[4] = { 1, 3, 5, 7 }; /* 近傍番号(奇数) */
int px, py; /* 近傍画素の(x,y)絶対座標 */
int b[9]; /* 自分を含む9近傍の値 */
int condition[6]; /* 条件1~6:=1のとき“成立” */
int counter; /* ラベルに変化が生じた画素の数 */
int i, x, y, copy, sum; /* 制御変数など */
int path; /* 画像の走査回数を表す変数 */
printf("Begin thinning processing.\n");
/* 作業配列の初期化 */
for ( y = 0; y < y_sz; y ++ )
for ( x = 0; x < x_sz; x ++ )
img2[y][x] = img1[y][x];
/* 処理開始 */
path = 1;
do {
printf("path : %d\n", path);
counter = 0;
for ( y = 0; y < y_sz; y ++ ){
for ( x = 0; x < x_sz; x ++ ){
/* (x,y)を含む9近傍にデータを代入する */
for ( i = 0; i < 9; i ++ ){
b[i] = 0;
px = x + offset[i][0]; py = y + offset[i][1];
if ( px >= 0 && px < x_sz &&
py >= 0 && py < y_sz )
if ( img2[py][px] == MAX_BRIGHTNESS )
b[i] = 1;
else if ( img2[py][px] == GRAY ) b[i] = -1;
}
for ( i = 0; i < 6; i ++ ) condition[i] = 0;
/* 条件1:図形画素である */
if ( b[0] == 1 ) condition[0] = 1;
/* 条件2:境界点である */
sum = 0;
for ( i = 0; i < 4; i ++ )
sum = sum + 1 - abs( b[ n_odd[i] ] );
if ( sum >= 1 ) condition[1] = 1;
/* 条件3:端点を除去しない */
sum = 0;
for ( i = 1; i <= 8; i ++ )
sum = sum + abs( b[i] );
if ( sum >= 2 ) condition[2] = 1;
/* 条件4:孤立点を保存する */
sum = 0;
for ( i = 1; i <= 8; i ++ )
if ( b[i] == 1 ) sum++;
if ( sum >= 1 ) condition[3] = 1;
/* 条件5:連結性を保存する */
if ( func_nc8( b ) == 1 ) condition[4] = 1;
/* 条件6:線幅2の線分の片側だけを削除する */
sum = 0;
for ( i = 1; i <= 8; i ++ )
if ( b[i] != -1 ) sum ++;
else {
copy = b[i];
b[i] = 0;
if ( func_nc8( b ) == 1 ) sum ++;
b[i] = copy;
}
if ( sum == 8 ) condition[5] = 1;
/* 最終判定 */
if ( condition[0] && condition[1] && condition[2] &&
condition[3] && condition[4] && condition[5] ){
img2[y][x] = GRAY; /* = -1 を表している */
counter ++;
}
} /* end of x */
} /* end of y */
if ( counter != 0 ){
for ( y=0; y<y_sz; y++)
for ( x=0; x<x_sz; x++)
if ( img2[y][x] == GRAY ) img2[y][x] = 0;
}
path ++;
} while ( counter != 0 );
}
main( )
{
/* ここで2値化*/
int x, y;
load_image_data( image1, "test.pgm");
for(y = 0; y<y_size; y++)
for(x = 0; x <x_size; x++){
if (image1[y][x] > 190)
image1[y][x] = 255;
else
image1[y][x] = 0;
}
save_image_data(image1, x_size, y_size);
thinning(image1, image2, x_size, y_size );
save_image_data(image2, x_size, y_size);
return 0;
}