int main (int argc, const char ** argv) { FILE * ifP; gray ** grays; unsigned int tone[PGM_MAXMAXVAL+1]; unsigned int r0, r45, r90; unsigned int d; unsigned int x, y; unsigned int row; int rows, cols; int argn; unsigned int itone; unsigned int toneCt; float ** p_matrix0, ** p_matrix45, ** p_matrix90, ** p_matrix135; float a2m[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]; gray maxval; unsigned int i; const char * const usage = "[-d <d>] [pgmfile]"; pm_proginit(&argc, argv); argn = 1; /* Check for flags. */ if ( argn < argc && argv[argn][0] == '-' ) { if ( argv[argn][1] == 'd' ) { ++argn; if ( argn == argc || sscanf( argv[argn], "%u", &d ) != 1 ) pm_usage( usage ); } else pm_usage( usage ); ++argn; } if ( argn < argc ) { ifP = pm_openr( argv[argn] ); ++argn; } else ifP = stdin; if ( argn != argc ) pm_usage( usage ); d = 1; grays = pgm_readpgm(ifP, &cols, &rows, &maxval); pm_close (ifP); /* Determine the number of different gray scales (not maxval) */ for (i = 0; i <= PGM_MAXMAXVAL; ++i) tone[i] = -1; for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) tone[grays[row][col]] = grays[row][col]; } for (i = 0, toneCt = 0; i <= PGM_MAXMAXVAL; ++i) { if (tone[i] != -1) ++toneCt; } pm_message("(Image has %u gray levels.)", toneCt); /* 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 = matrix (0, toneCt, 0, toneCt); p_matrix45 = matrix (0, toneCt, 0, toneCt); p_matrix90 = matrix (0, toneCt, 0, toneCt); p_matrix135 = matrix (0, toneCt, 0, toneCt); for (row = 0; row < toneCt; ++row) { unsigned int col; for (col = 0; col < toneCt; ++col) { p_matrix0 [row][col] = p_matrix45 [row][col] = 0; p_matrix90[row][col] = p_matrix135[row][col] = 0; } } if (d > cols) pm_error("Image is narrower (%u columns) " "than specified distance (%u)", cols, d); /* Find gray-tone spatial dependence matrix */ pm_message("Computing spatial dependence matrix..."); for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { unsigned int angle; for (angle = 0, x = 0; angle <= 135; angle += 45) { while (tone[x] != grays[row][col]) ++x; if (angle == 0 && col + d < cols) { y = 0; while (tone[y] != grays[row][col + d]) ++y; ++p_matrix0[x][y]; ++p_matrix0[y][x]; } if (angle == 90 && row + d < rows) { y = 0; while (tone[y] != grays[row + d][col]) ++y; ++p_matrix90[x][y]; ++p_matrix90[y][x]; } if (angle == 45 && row + d < rows && col >= d) { y = 0; while (tone[y] != grays[row + d][col - d]) ++y; ++p_matrix45[x][y]; ++p_matrix45[y][x]; } if (angle == 135 && row + d < rows && col + d < cols) { y = 0; while (tone[y] != grays[row + d][col + d]) ++y; ++p_matrix135[x][y]; ++p_matrix135[y][x]; } } } } /* Gray-tone spatial dependence matrices are complete */ /* Find normalizing constants */ r0 = 2 * rows * (cols - d); r45 = 2 * (rows - d) * (cols - d); r90 = 2 * (rows - d) * cols; /* Normalize gray-tone spatial dependence matrix */ for (itone = 0; itone < toneCt; ++itone) { unsigned int jtone; for (jtone = 0; jtone < toneCt; ++jtone) { p_matrix0[itone][jtone] /= r0; p_matrix45[itone][jtone] /= r45; p_matrix90[itone][jtone] /= r90; p_matrix135[itone][jtone] /= r45; } } pm_message(" ...done."); pm_message("Computing textural features ..."); fprintf(stdout, "\n"); fprintf(stdout, "%s 0 45 90 135 Avg\n", BL); a2m[0] = f1_a2m(p_matrix0, toneCt); a2m[1] = f1_a2m(p_matrix45, toneCt); a2m[2] = f1_a2m(p_matrix90, toneCt); a2m[3] = f1_a2m(p_matrix135, toneCt); results(F1, a2m); contrast[0] = f2_contrast(p_matrix0, toneCt); contrast[1] = f2_contrast(p_matrix45, toneCt); contrast[2] = f2_contrast(p_matrix90, toneCt); contrast[3] = f2_contrast(p_matrix135, toneCt); results(F2, contrast); corr[0] = f3_corr(p_matrix0, toneCt); corr[1] = f3_corr(p_matrix45, toneCt); corr[2] = f3_corr(p_matrix90, toneCt); corr[3] = f3_corr(p_matrix135, toneCt); results(F3, corr); var[0] = f4_var(p_matrix0, toneCt); var[1] = f4_var(p_matrix45, toneCt); var[2] = f4_var(p_matrix90, toneCt); var[3] = f4_var(p_matrix135, toneCt); results(F4, var); idm[0] = f5_idm(p_matrix0, toneCt); idm[1] = f5_idm(p_matrix45, toneCt); idm[2] = f5_idm(p_matrix90, toneCt); idm[3] = f5_idm(p_matrix135, toneCt); results(F5, idm); savg[0] = f6_savg(p_matrix0, toneCt); savg[1] = f6_savg(p_matrix45, toneCt); savg[2] = f6_savg(p_matrix90, toneCt); savg[3] = f6_savg(p_matrix135, toneCt); results(F6, savg); svar[0] = f7_svar(p_matrix0, toneCt, savg[0]); svar[1] = f7_svar(p_matrix45, toneCt, savg[1]); svar[2] = f7_svar(p_matrix90, toneCt, savg[2]); svar[3] = f7_svar(p_matrix135, toneCt, savg[3]); results(F7, svar); sentropy[0] = f8_sentropy(p_matrix0, toneCt); sentropy[1] = f8_sentropy(p_matrix45, toneCt); sentropy[2] = f8_sentropy(p_matrix90, toneCt); sentropy[3] = f8_sentropy(p_matrix135, toneCt); results(F8, sentropy); entropy[0] = f9_entropy(p_matrix0, toneCt); entropy[1] = f9_entropy(p_matrix45, toneCt); entropy[2] = f9_entropy(p_matrix90, toneCt); entropy[3] = f9_entropy(p_matrix135, toneCt); results(F9, entropy); dvar[0] = f10_dvar(p_matrix0, toneCt); dvar[1] = f10_dvar(p_matrix45, toneCt); dvar[2] = f10_dvar(p_matrix90, toneCt); dvar[3] = f10_dvar(p_matrix135, toneCt); results(F10, dvar); dentropy[0] = f11_dentropy(p_matrix0, toneCt); dentropy[1] = f11_dentropy(p_matrix45, toneCt); dentropy[2] = f11_dentropy(p_matrix90, toneCt); dentropy[3] = f11_dentropy(p_matrix135, toneCt); results (F11, dentropy); icorr[0] = f12_icorr(p_matrix0, toneCt); icorr[1] = f12_icorr(p_matrix45, toneCt); icorr[2] = f12_icorr(p_matrix90, toneCt); icorr[3] = f12_icorr(p_matrix135, toneCt); results(F12, icorr); icorr[0] = f13_icorr(p_matrix0, toneCt); icorr[1] = f13_icorr(p_matrix45, toneCt); icorr[2] = f13_icorr(p_matrix90, toneCt); icorr[3] = f13_icorr(p_matrix135, toneCt); results(F13, icorr); maxcorr[0] = f14_maxcorr(p_matrix0, toneCt); maxcorr[1] = f14_maxcorr(p_matrix45, toneCt); maxcorr[2] = f14_maxcorr(p_matrix90, toneCt); maxcorr[3] = f14_maxcorr(p_matrix135, toneCt); results(F14, maxcorr); pm_message(" ...done."); return 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); }