/* make_dic_dir_all.c */ /* 各数字の輪郭方向分布特徴の辞書作成 */ /* learn.pat 全部を使用 */ #include #include #include #include "mypgm.h" #define BLACK 0 #define WHITE 255 #define RADIUS 25.0 #define HEI 120 #define WID 80 #define SIDE 20 #define BLOCKS 24 #define DIRECTION 4 /* prototype declaration */ void bilinear_normal_image(double); int dircode(int, int); main( ) { FILE *fp; double dic[10][BLOCKS][DIRECTION]; char filename[MAX_FILENAME]; int digit, serial; int code; int i, j, k; int ok; int sample = 0; static int n_pat[10] = {2535, 1691, 1658, 1736, 1188, 1996, 1977, 1410, 2366, 1428}; for (digit = 0; digit <=9; digit++) { for (i = 0; i < BLOCKS; i++) { for (j = 0; j < DIRECTION; j++) { dic[digit][i][j] = 0.0; } } } for (digit = 0; digit <= 9; digit++) { for (serial = 1; serial <= n_pat[digit]; serial++) { sprintf(filename, "./cdrom1b/ldg%d_%04d.pgm", digit, serial); load_image_file(filename); bilinear_normal_image(RADIUS); printf("sample = %d\n", ++sample); for (j = 0; j < y_size2; j++) { for (i = 0; i < x_size2; i++) { if (image2[j][i] == BLACK) image1[j][i] = 1; else image1[j][i] = 0; } } for (j = 0; j < y_size2 - 1; j++) { for (i = 0; i < x_size2 - 1; i++) { code = dircode(j, i); if (code != -1) { k = j/SIDE*(WID/SIDE) + i/SIDE; dic[digit][k][code]++; } } } } for (i = 0; i < BLOCKS; i++) { for (j = 0; j < DIRECTION; j++) { dic[digit][i][j] /= (double)SIDE * SIDE * n_pat[digit]; } } } while (1) { printf("\nCheck the content of dic_dir (1/0) ? "); scanf("%d", &ok); if (ok != 1) break; printf("Input digit : "); scanf("%d", &digit); printf("\n"); for (i = 0; i < BLOCKS; i++) { for (j = 0; j < DIRECTION; j++) { printf("%3d", (int)(SIDE * SIDE * dic[digit][i][j])); } printf(" "); if (i % 4 == 3) printf("\n\n"); } } fp = fopen("dic_dir_all", "wb"); fwrite(dic, sizeof(dic), 1, fp); fclose(fp); return 0; } void bilinear_normal_image(double norm_radius) { int x, y; int count; double gx, gy; double rad, ratio; double x_new, y_new, x_frac, y_frac; double gray_new; int gv_new; int m, n; gx = gy = 0.0; count = 0; for (y = 0; y < y_size1; y++) { for (x = 0; x < x_size1; x++) { if (image1[y][x] == BLACK) { gx += (double)x; gy += (double)y; count++; } } } gx /= (double)count; gy /= (double)count; rad = 0.0; for (y = 0; y < y_size1; y++) { for (x = 0; x < x_size1; x++) { if (image1[y][x] == BLACK) { rad += sqrt(pow((double)x - gx, 2) + pow((double)y - gy, 2)); } } } rad /= (double)count; if (rad == 0.0) exit(1); ratio = norm_radius / rad; x_size2 = x_size1; y_size2 = y_size1; for (y = 0; y < y_size2; y++) { for (x = 0; x < x_size2; x++) { x_new = (x - x_size2/2) / ratio + gx; y_new = (y - y_size2/2) / ratio + gy; m = (int)floor(x_new); n = (int)floor(y_new); x_frac = x_new - m; y_frac = y_new - n; if (m >= 0 && m+1 < x_size2 && n >= 0 && n+1 < y_size2) { gray_new = (1.0 - y_frac)*((1.0 - x_frac)*image1[n][m] + x_frac *image1[n][m+1]) + y_frac *((1.0 - x_frac)*image1[n+1][m] + x_frac *image1[n+1][m+1]); gv_new = gray_new >= MAX_BRIGHTNESS/2.0 ? MAX_BRIGHTNESS : 0; } else { gv_new = MAX_BRIGHTNESS; } image2[y][x] = (unsigned char)gv_new; } } } int dircode(int y, int x) { int peri[4], sum; peri[0] = image1[y][x]; peri[1] = image1[y][x+1]; peri[2] = image1[y+1][x]; peri[3] = image1[y+1][x+1]; sum = peri[0] + peri[1] + peri[2] + peri[3]; if (sum == 2) { if (peri[0] * peri[1] == 1 || peri[2] * peri[3] == 1) { return 0; /* Horizontal */ } if (peri[0] * peri[2] == 1 || peri[1] * peri[3] == 1) { return 2; /* Vertical */ } return -1; } else if (sum == 1) { if (peri[0] == 1 || peri[3] == 1) { return 1; /* Right-diagonal */ } if (peri[1] == 1 || peri[2] == 1) { return 3; /* Left-diagonal */ } return -1; } else { return -1; } }