#include#include #include /* 抽出した点に関する情報を格納するための構造体 */ struct point { int rsize; /* 赤色の球の面積 */ int gsize; /* 緑色の球の面積 */ int row_r; /* 赤色の球の重心のy座標 */ int col_r; /* 赤色の球の重心のx座標 */ int row_g; /* 緑色の球の重心のy座標 */ int col_g; /* 緑色の球の重心のx座標 */ int left_r; /* 赤色の球の直径の左端の点のx座標 */ int right_r; /* 赤色の球の直径の右端の点のx座標 */ int up_r; /* 赤色の球の直径の上端の点のy座標 */ int down_r; /* 赤色の球の直径の下端の点のy座標 */ int left_g; /* 緑色の球の直径の左端の点のx座標 */ int right_g; /* 緑色の球の直径の右端の点のx座標 */ int up_g; /* 緑色の球の直径の上端の点のy座標 */ int down_g; /* 緑色の球の直径の下端の点のy座標 */ }; int compare(int *, int *); int calc_thres(int *, int); void makeborder(int *, int *, int); int calc_length(int *, int *, int*, int *); int calc_size(int, int, int *,int *, int *, int *, int *, int *, int *, int *); struct point sample_point(int, int, int *, int *, int *, int *); /* 比較関数 */ int intcompare(int *a, int *b) { return(*a - *b); } /* しきい値を計算をする関数 */ int calc_thres(int hist[], int setsize) { int kari[500]; int i,j=0; int count = 0,sum = 0; int thres; /* しきい値を格納 */ /* 初期化 */ for(i=0; i = 0) && (count < 10)) { sum = sum + kari[j--]; count++; } thres = sum / (count*10); if (thres == 0) thres = 1; return(thres); } /* ノイズを除去する関数 */ void makeborder(int hist[], int border[], int setsize) { int i=0; int thres; int x; /* しきい値の計算 */ thres = calc_thres(hist, setsize); for(x = 1; x hist[x]) ? x-1 : x; else if ((hist[x-1]-thres)*(hist[x]-thres) == 0) /* 隣あう2点のうちどちらか1点がしきい値と一致する場合 */ if (hist[x-1] != hist[x]) { if ((hist[x-1] < thres) || (hist[x] < thres)) if (hist[x-1] == thres) border[i++] = x-1; else border[i++] = x; else if (hist[x-1] == thres && x == 1) border[i++] = x-1; else if (hist[x] == thres && x == setsize-1) border[i++] = x; } else { /* 2点ともしきい値と一致する場合 */ if ((hist[x-1] != 0) && (hist[x] != 0)) { if (x == 1) border[i++] = 0; if (x == setsize-1) border[i++] = x; } } /* 2点ともしきい値より大きい場合 */ else if ((hist[x-1] > thres) && (hist[x] > thres)) if (x == 1) border[i++] = 0; else if (x == setsize-1) border[i++] = x; } /* 球の直径を計算する関数 */ int calc_length(int border[],int *left, int *right, int *center) { int i=0; int dif,original_i; int max=0; /* 最大区間の計算 */ while(border[i+1] != -1) { original_i = i; while ((i != 0) && ((dif = border[i] - border[i-1]) <= 3)) i = i-2; if (max < (border[original_i+1]-border[i]+1)) { max = border[original_i+1]-border[i]+1; *left = border[i]; *right = border[original_i+1]; } i = original_i + 2; } /* 重心の計算 */ *center = *left + (*right-*left) / 2; return(max); } /* 球の面積を計算する関数 */ int calc_size(int xsize, int ysize, int histrow[], int histcol[], int *left, int *right, int *up, int *down, int *row, int *col) { int i,size; int rborder[200],cborder[200]; int length_row,length_col; /* 初期化 */ for( i = 0; i <= xsize/2; i++) rborder[i] = -1; for( i = 0; i <= ysize/2; i++) cborder[i] = -1; /* ノイズの除去 */ makeborder(histrow,rborder,ysize); makeborder(histcol,cborder,xsize); /* 球の直径の計算 */ length_row = calc_length(rborder,up,down,row); length_col = calc_length(cborder,left,right,col); /* 球の面積の計算 */ size = length_row * length_col; return(size); } /* 識別子の特徴抽出 */ struct point sample_point(int xsize, int ysize, int histrow_r[], int histcol_r[], int histrow_g[], int histcol_g[]) { /* 新しく抽出した点に関する情報を格納するための構造体 */ struct point newpoint = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* 赤色の球を抽出 */ newpoint.rsize= calc_size(xsize, ysize, histrow_r, histcol_r, &(newpoint.left_r), &(newpoint.right_r), &(newpoint.up_r), &(newpoint.down_r), &(newpoint.row_r), &(newpoint.col_r)); /* 緑色の球を抽出 */ newpoint.gsize = calc_size(xsize, ysize, histrow_g, histcol_g, &(newpoint.left_g), &(newpoint.right_g), &(newpoint.up_g), &(newpoint.down_g), &(newpoint.row_g), &(newpoint.col_g)); return(newpoint); }