float h_measure(int t_m) { switch (t_m) { /* Angular Second Moment */ case 1: return (f1_asm()); break; /* Contrast */ case 2: return (f2_contrast()); break; /* Correlation */ case 3: return (f3_corr()); break; /* Variance */ case 4: return (f4_var()); break; /* Inverse Diff Moment */ case 5: return (f5_idm()); break; /* Sum Average */ case 6: return (f6_savg()); break; /* Sum Variance */ case 7: return (f7_svar()); break; /* Sum Entropy */ case 8: return (f8_sentropy()); break; /* Entropy */ case 9: return (f9_entropy()); break; /* Difference Variance */ case 10: return (f10_dvar()); break; /* Difference Entropy */ case 11: return (f11_dentropy()); break; /* Measure of Correlation-1 */ case 12: return (f12_icorr()); break; /* Measure of Correlation-2 */ case 13: return (f13_icorr()); break; } return 0; }
TEXTURE * Extract_Texture_Features(int distance, register gray **grays, int rows, int cols, TEXTURE_FEATURE_MAP *feature_usage) { FILE *ifp; register gray *gP; int tone[PGM_MAXMAXVAL+1], R0, R45, R90, R135, angle, d = 1, x, y; int argn, bps, padright, row, col, i; int itone, jtone, tones,g_val; float **P_matrix0, **P_matrix45, **P_matrix90, **P_matrix135; float ASM[4], contrast[4], corr[4], var[4], idm[4], savg[4]; float sentropy[4], svar[4], entropy[4], dvar[4], dentropy[4]; float icorr[4], maxcorr[4]; float *Tp; gray nmaxval, maxval; char *usage = "[-d <d>] [pgmfile]"; TEXTURE *Texture; Texture = (TEXTURE *) calloc(1,sizeof(TEXTURE)); if(!Texture) { printf("\nERROR in TEXTURE structure allocate\n"); exit(1); } d = distance; /* Determine the number of different gray scales (not maxval) */ for (row = PGM_MAXMAXVAL; row >= 0; --row) tone[row] = -1; for (row = rows - 1; row >= 0; --row) for (col = 0; col < cols; ++col) { /* if (grays[row][col]) If gray value equal 0 don't include */ tone[grays[row][col]] = grays[row][col]; } for (row = PGM_MAXMAXVAL, tones = 0; row >= 0; --row) if (tone[row] != -1) tones++; /* fprintf (stderr, "(Image has %d graylevels.)\n", tones); */ /* Collapse array, taking out all zero values */ for (row = 0, itone = 0; row <= PGM_MAXMAXVAL; row++) if (tone[row] != -1) tone[itone++] = tone[row]; /* Now array contains only the gray levels present (in ascending order) */ /* Allocate memory for gray-tone spatial dependence matrix */ P_matrix0 = pgm_matrix (0, tones, 0, tones); P_matrix45 = pgm_matrix (0, tones, 0, tones); P_matrix90 = pgm_matrix (0, tones, 0, tones); P_matrix135 = pgm_matrix (0, tones, 0, tones); for (row = 0; row < tones; ++row) for (col = 0; col < tones; ++col) { P_matrix0[row][col] = P_matrix45[row][col] = 0; P_matrix90[row][col] = P_matrix135[row][col] = 0; } R0 = 0; R45 = 0; R90 = 0; R135 = 0; /* Find gray-tone spatial dependence matrix */ /* fprintf (stderr, "(Computing spatial dependence matrix..."); */ for (row = 0; row < rows; ++row) for (col = 0; col < cols; ++col) /* if (grays[row][col]) */ for (x = 0, angle = 0; angle <= 135; angle += 45) { while (tone[x] != grays[row][col]) x++; /* M. Boland if (angle == 0 && col + d < cols) */ /* M. Boland - include neighbor only if != 0 */ if (angle == 0 && col + d < cols && grays[row][col + d]) { y = 0; while (tone[y] != grays[row][col + d]) y++; P_matrix0[x][y]++; P_matrix0[y][x]++; /* R0++; M. Boland 25 Nov 98 */ R0+=2 ; } /* M. Boland if (angle == 90 && row + d < rows) */ /* M. Boland - include neighbor only if != 0 */ else if (angle == 90 && row + d < rows && grays[row + d][col]) { y = 0; while (tone[y] != grays[row + d][col]) y++; P_matrix90[x][y]++; P_matrix90[y][x]++; /* R90++; M. Boland 25 Nov 98 */ R90+=2 ; } /* M. Boland if (angle == 45 && row + d < rows && col - d >= 0) */ /* M. Boland - include neighbor only if != 0 */ else if (angle == 45 && row + d < rows && col - d >= 0 && grays[row + d][col - d]) { y = 0; while (tone[y] != grays[row + d][col - d]) y++; P_matrix45[x][y]++; P_matrix45[y][x]++; /* R45++; M. Boland 25 Nov 98 */ R45+=2 ; } /* M. Boland if (angle == 135 && row + d < rows && col + d < cols) */ else if (angle == 135 && row + d < rows && col + d < cols && grays[row + d][col + d]) { y = 0; while (tone[y] != grays[row + d][col + d]) y++; P_matrix135[x][y]++; P_matrix135[y][x]++; /* R135++; M. Boland 25 Nov 98 */ R135+=2 ; } } /* Gray-tone spatial dependence matrices are complete */ /* Find normalizing constants */ /* R0 = 2 * rows * (cols - 1); R45 = 2 * (rows - 1) * (cols - 1); R90 = 2 * (rows - 1) * cols; R135 = R45; */ /* Normalize gray-tone spatial dependence matrix */ for (itone = 0; itone < tones; ++itone) for (jtone = 0; jtone < tones; ++jtone) { P_matrix0[itone][jtone] /= R0; P_matrix45[itone][jtone] /= R45; P_matrix90[itone][jtone] /= R90; P_matrix135[itone][jtone] /= R135; } /* fprintf (stderr, " done.)\n"); */ /* fprintf (stderr, "(Computing textural features"); */ /* fprintf (stdout, "\n"); */ /* DOT; */ /* fprintf (stdout, "%s 0 45 90 135 Avg Range\n", BL); */ if (feature_usage->ASM) { ASM[0] = f1_asm (P_matrix0, tones); ASM[1] = f1_asm (P_matrix45, tones); ASM[2] = f1_asm (P_matrix90, tones); ASM[3] = f1_asm (P_matrix135, tones); } Tp = &Texture->ASM[0]; results (Tp, F1, ASM); if (feature_usage->contrast) { contrast[0] = f2_contrast (P_matrix0, tones); contrast[1] = f2_contrast (P_matrix45, tones); contrast[2] = f2_contrast (P_matrix90, tones); contrast[3] = f2_contrast (P_matrix135, tones); } Tp = &Texture->contrast[0]; results (Tp, F2, contrast); if (feature_usage->correlation) { corr[0] = f3_corr (P_matrix0, tones); corr[1] = f3_corr (P_matrix45, tones); corr[2] = f3_corr (P_matrix90, tones); corr[3] = f3_corr (P_matrix135, tones); } Tp = &Texture->correlation[0]; results (Tp, F3, corr); if (feature_usage->variance) { var[0] = f4_var (P_matrix0, tones); var[1] = f4_var (P_matrix45, tones); var[2] = f4_var (P_matrix90, tones); var[3] = f4_var (P_matrix135, tones); } Tp = &Texture->variance[0]; results (Tp, F4, var); if (feature_usage->IDM) { idm[0] = f5_idm (P_matrix0, tones); idm[1] = f5_idm (P_matrix45, tones); idm[2] = f5_idm (P_matrix90, tones); idm[3] = f5_idm (P_matrix135, tones); } Tp = &Texture->IDM[0]; results (Tp, F5, idm); if (feature_usage->sum_avg) { savg[0] = f6_savg (P_matrix0, tones); savg[1] = f6_savg (P_matrix45, tones); savg[2] = f6_savg (P_matrix90, tones); savg[3] = f6_savg (P_matrix135, tones); } Tp = &Texture->sum_avg[0]; results (Tp, F6, savg); if (feature_usage->sum_var) { sentropy[0] = f8_sentropy (P_matrix0, tones); sentropy[1] = f8_sentropy (P_matrix45, tones); sentropy[2] = f8_sentropy (P_matrix90, tones); sentropy[3] = f8_sentropy (P_matrix135, tones); } if (feature_usage->sum_entropy) { svar[0] = f7_svar (P_matrix0, tones, sentropy[0]); svar[1] = f7_svar (P_matrix45, tones, sentropy[1]); svar[2] = f7_svar (P_matrix90, tones, sentropy[2]); svar[3] = f7_svar (P_matrix135, tones, sentropy[3]); } Tp = &Texture->sum_var[0]; results (Tp, F7, svar); Tp = &Texture->sum_entropy[0]; results (Tp, F8, sentropy); if (feature_usage->entropy) { entropy[0] = f9_entropy (P_matrix0, tones); entropy[1] = f9_entropy (P_matrix45, tones); entropy[2] = f9_entropy (P_matrix90, tones); entropy[3] = f9_entropy (P_matrix135, tones); } Tp = &Texture->entropy[0]; results (Tp, F9, entropy); if (feature_usage->diff_var) { dvar[0] = f10_dvar (P_matrix0, tones); dvar[1] = f10_dvar (P_matrix45, tones); dvar[2] = f10_dvar (P_matrix90, tones); dvar[3] = f10_dvar (P_matrix135, tones); } Tp = &Texture->diff_var[0]; results (Tp, F10, dvar); if (feature_usage->diff_entropy) { dentropy[0] = f11_dentropy (P_matrix0, tones); dentropy[1] = f11_dentropy (P_matrix45, tones); dentropy[2] = f11_dentropy (P_matrix90, tones); dentropy[3] = f11_dentropy (P_matrix135, tones); } Tp = &Texture->diff_entropy[0]; results (Tp, F11, dentropy); if (feature_usage->meas_corr1) { icorr[0] = f12_icorr (P_matrix0, tones); icorr[1] = f12_icorr (P_matrix45, tones); icorr[2] = f12_icorr (P_matrix90, tones); icorr[3] = f12_icorr (P_matrix135, tones); } Tp = &Texture->meas_corr1[0]; results (Tp, F12, icorr); if (feature_usage->meas_corr2) { icorr[0] = f13_icorr (P_matrix0, tones); icorr[1] = f13_icorr (P_matrix45, tones); icorr[2] = f13_icorr (P_matrix90, tones); icorr[3] = f13_icorr (P_matrix135, tones); } Tp = &Texture->meas_corr2[0]; results (Tp, F13, icorr); if (feature_usage->max_corr_coef) { maxcorr[0] = f14_maxcorr (P_matrix0, tones); maxcorr[1] = f14_maxcorr (P_matrix45, tones); maxcorr[2] = f14_maxcorr (P_matrix90, tones); maxcorr[3] = f14_maxcorr (P_matrix135, tones); } /* M. Boland - 24 Nov 98 */ else { maxcorr[0] = 0 ; maxcorr[1] = 0 ; maxcorr[2] = 0 ; maxcorr[3] = 0 ; } Tp = &Texture->max_corr_coef[0]; results (Tp, F14, maxcorr); for (i=0; i<=tones; i++) free(P_matrix0[i]); for (i=0; i<=tones; i++) free(P_matrix45[i]); for (i=0; i<=tones; i++) free(P_matrix90[i]); for (i=0; i<=tones; i++) free(P_matrix135[i]); free(P_matrix0); free(P_matrix45); free(P_matrix90); free(P_matrix135); /* fprintf (stderr, " done.)\n"); */ return (Texture); /* exit (0);*/ }
TEXTURE * Extract_Texture_Features(int distance, int angle, register u_int8_t **grays, int rows, int cols, int max_val) { int tone_LUT[PGM_MAXMAXVAL+1]; /* LUT mapping gray tone(0-255) to matrix indicies */ int tone_count=0; /* number of tones actually in the img. atleast 1 less than 255 */ int itone; int row, col, i; double **P_matrix; double sum_entropy; TEXTURE *Texture; Texture = (TEXTURE *) calloc(1,sizeof(TEXTURE)); if (!Texture) { printf("\nERROR in TEXTURE structure allocate\n"); exit(1); } /* Determine the number of different gray tones (not maxval) */ for (row = PGM_MAXMAXVAL; row >= 0; --row) tone_LUT[row] = -1; for (row = rows - 1; row >= 0; --row) for (col = 0; col < cols; ++col) tone_LUT[grays[row][col]] = grays[row][col]; for (row = PGM_MAXMAXVAL, tone_count = 0; row >= 0; --row) if (tone_LUT[row] != -1) tone_count++; /* Use the number of different tones to build LUT */ for (row = 0, itone = 0; row <= PGM_MAXMAXVAL; row++) if (tone_LUT[row] != -1) tone_LUT[row] = itone++; /* compute gray-tone spatial dependence matrix */ if (angle == 0) P_matrix = CoOcMat_Angle_0 (distance, grays, rows, cols, tone_LUT, tone_count); else if (angle == 45) P_matrix = CoOcMat_Angle_45 (distance, grays, rows, cols, tone_LUT, tone_count); else if (angle == 90) P_matrix = CoOcMat_Angle_90 (distance, grays, rows, cols, tone_LUT, tone_count); else if (angle == 135) P_matrix = CoOcMat_Angle_135 (distance, grays, rows, cols, tone_LUT, tone_count); else { fprintf (stderr, "Cannot created co-occurence matrix for angle %d. Unsupported angle.\n", angle); return NULL; } /* compute the statistics for the spatial dependence matrix */ Texture->ASM = f1_asm (P_matrix, tone_count); Texture->contrast = f2_contrast (P_matrix, tone_count); Texture->correlation = f3_corr (P_matrix, tone_count); Texture->variance = f4_var (P_matrix, tone_count); Texture->IDM = f5_idm (P_matrix, tone_count); Texture->sum_avg = f6_savg (P_matrix, tone_count); /* T.J.M watch below the cast from float to double */ sum_entropy = f8_sentropy (P_matrix, tone_count); Texture->sum_entropy = sum_entropy; Texture->sum_var = f7_svar (P_matrix, tone_count, sum_entropy); Texture->entropy = f9_entropy (P_matrix, tone_count); Texture->diff_var = f10_dvar (P_matrix, tone_count); Texture->diff_entropy = f11_dentropy (P_matrix, tone_count); Texture->meas_corr1 = f12_icorr (P_matrix, tone_count); Texture->meas_corr2 = f13_icorr (P_matrix, tone_count); Texture->max_corr_coef = f14_maxcorr (P_matrix, tone_count); return (Texture); }