/* EulerNumber The input image should be a binary image */ long EulerNumber(const ImageMatrix &Im, int mode) { unsigned long x, y; size_t i; // quad-pixel match patterns unsigned char Px[] = { // P1 - single pixel (1 << 3) | (0 << 2) | (0 << 1) | (0 << 0), (0 << 3) | (1 << 2) | (0 << 1) | (0 << 0), (0 << 3) | (0 << 2) | (1 << 1) | (0 << 0), (0 << 3) | (0 << 2) | (0 << 1) | (1 << 0), // P3 - 3-pixel (0 << 3) | (1 << 2) | (1 << 1) | (1 << 0), (1 << 3) | (0 << 2) | (1 << 1) | (1 << 0), (1 << 3) | (1 << 2) | (0 << 1) | (1 << 0), (1 << 3) | (1 << 2) | (1 << 1) | (0 << 0), // Pd - diagonals (1 << 3) | (0 << 2) | (0 << 1) | (1 << 0), (0 << 3) | (1 << 2) | (1 << 1) | (0 << 0) }; unsigned char Imq; // Pattern match counters long C1 = 0, C3 = 0, Cd = 0; readOnlyPixels pix_plane = Im.ReadablePixels(); assert ( (mode == 4 || mode == 8) && "Calling EulerNumber with mode other than 4 or 8"); // update pattern counters by scanning the image. for (y = 1; y < Im.height; y++) { for (x = 1; x < Im.width; x++) { // Get the quad-pixel at this image location Imq = 0; if (pix_plane(y-1,x-1) > 0) Imq |= (1 << 3); if (pix_plane(y-1,x ) > 0) Imq |= (1 << 2); if (pix_plane(y ,x-1) > 0) Imq |= (1 << 1); if (pix_plane(y ,x ) > 0) Imq |= (1 << 0); // find the matching pattern for (i = 0; i < 10; i++) if (Imq == Px[i]) break; if (i >= 0 && i <= 3) C1++; else if (i >= 4 && i <= 7) C3++; else if (i == 8 && i == 9) Cd++; } } if (mode == 4) return ( (C1 - C3 + (2*Cd)) / 4); else return ( (C1 - C3 - (2*Cd)) / 4); }
/* the number of pixels that are above the threshold the input image is a binary image */ unsigned long area(const ImageMatrix &Im) { unsigned int x,y,w = Im.width, h = Im.height; unsigned long sum=0; readOnlyPixels pix_plane = Im.ReadablePixels(); for (y = 0; y < h; y++) for (x = 0; x < w; x++) sum += (pix_plane(y,x) > 0 ? 1 : 0); return(sum); }
/* find the centroid of a certain feature the input image should be a bwlabel transform of a binary image the retruned value is the area of the feature */ unsigned long FeatureCentroid(const ImageMatrix &Im, double object_index,double *x_centroid, double *y_centroid) { unsigned int x,y,w = Im.width, h = Im.height; unsigned long x_mass=0,y_mass=0,mass=0; readOnlyPixels pix_plane = Im.ReadablePixels(); for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (pix_plane(y,x) == object_index) { x_mass=x_mass+x+1; /* the "+1" is only for compatability with matlab code (where index starts from 1) */ y_mass=y_mass+y+1; /* the "+1" is only for compatability with matlab code (where index starts from 1) */ mass++; } if (x_centroid) *x_centroid=(double)x_mass/(double)mass; if (y_centroid) *y_centroid=(double)y_mass/(double)mass; return(mass); }
/* the input should be a binary image */ void GlobalCentroid(const ImageMatrix &Im, double *x_centroid, double *y_centroid) { unsigned int x,y,w = Im.width, h = Im.height; double x_mass=0,y_mass=0,mass=0; readOnlyPixels pix_plane = Im.ReadablePixels(); for (y = 0; y < h; y++) for (x = 0; x < w; x++) if (pix_plane(y,x) > 0) { x_mass=x_mass+x+1; /* the "+1" is only for compatability with matlab code (where index starts from 1) */ y_mass=y_mass+y+1; /* the "+1" is only for compatability with matlab code (where index starts from 1) */ mass++; } if (mass) { *x_centroid=x_mass/mass; *y_centroid=y_mass/mass; } else *x_centroid=*y_centroid=0; }
/* BWlabel label groups of 4-connected pixels. This is an implementation of the Matlab function bwlabel */ unsigned long bwlabel(ImageMatrix &Im, int level) { long x, y, base_x,base_y,stack_count, w = Im.width, h = Im.height; unsigned long group_counter = 1; point *stack=new point[w*h]; pixData &pix_plane = Im.WriteablePixels(); for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if ( pix_plane(y,x) == 1) { /* start a new group */ group_counter++; pix_plane(y,x) = group_counter; stack[0].x=x; stack[0].y=y; stack_count=1; while (stack_count > 0) { base_x=stack[0].x; base_y=stack[0].y; if (base_x > 0 && pix_plane(base_y,base_x-1) == 1) { pix_plane(base_y,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y; stack_count++; } if (base_x < w-1 && pix_plane(base_y,base_x+1) == 1) { pix_plane(base_y,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y; stack_count++; } if (base_y > 0 && pix_plane(base_y-1,base_x) == 1) { pix_plane(base_y-1,base_x) = group_counter; stack[stack_count].x=base_x; stack[stack_count].y=base_y-1; stack_count++; } if (base_y < h-1 && pix_plane(base_y+1,base_x) == 1) { pix_plane(base_y+1,base_x) = group_counter; stack[stack_count].x=base_x; stack[stack_count].y=base_y+1; stack_count++; } /* look for 8 connected pixels */ if (level==8) { if (base_x > 0 && base_y > 0 && pix_plane(base_y-1,base_x-1) == 1) { pix_plane(base_y-1,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y-1; stack_count++; } if (base_x < w-1 && base_y > 0 && pix_plane(base_y-1,base_x+1) == 1) { pix_plane(base_y-1,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y-1; stack_count++; } if (base_x > 0 && base_y < h-1 && pix_plane(base_y+1,base_x-1) == 1) { pix_plane(base_y+1,base_x-1) = group_counter; stack[stack_count].x=base_x-1; stack[stack_count].y=base_y+1; stack_count++; } if (base_x < w-1 && base_y < h-1 && pix_plane(base_y+1,base_x+1) == 1) { pix_plane(base_y+1,base_x+1) = group_counter; stack[stack_count].x=base_x+1; stack[stack_count].y=base_y+1; stack_count++; } } stack_count-=1; memmove(stack,&(stack[1]),sizeof(point)*stack_count); } } } } /* now decrease every non-zero pixel by one because the first group was "2" */ for (y=0;y<h;y++) for (x=0;x<w;x++) if (pix_plane(y,x) != 0) pix_plane(y,x) -= 1; delete [] stack; return(group_counter-1); }
void haralick2D(ImageMatrix &Im, double distance, double *out) { unsigned int a,x,y; unsigned char **p_gray; TEXTURE *features; int angle; double min[14],max[14],sum[14]; double min_value,max_value; double scale255; readOnlyPixels pix_plane = Im.ReadablePixels(); if (distance <= 0) distance = 1; p_gray = new unsigned char *[Im.height]; for (y = 0; y < Im.height; y++) p_gray[y] = new unsigned char[Im.width]; Im.BasicStatistics(NULL, NULL, NULL, &min_value, &max_value, NULL, 0); scale255 = (255.0/(max_value-min_value)); for (y = 0; y < Im.height; y++) for (x = 0; x < Im.width; x++) p_gray[y][x] = (unsigned char)((pix_plane(y,x) - min_value) * scale255); for (a = 0; a < 14; a++) { min[a] = INF; max[a] = -INF; sum[a] = 0; } for (angle = 0; angle <= 135; angle = angle+45) { features = Extract_Texture_Features((int)distance, angle, p_gray, Im.height,Im.width); /* (1) Angular Second Moment */ sum[0] += features->ASM; if (features->ASM < min[0]) min[0] = features->ASM; if (features->ASM > max[0]) max[0] = features->ASM; /* (2) Contrast */ sum[1] += features->contrast; if (features->contrast < min[1]) min[1] = features->contrast; if (features->contrast > max[1]) max[1] = features->contrast; /* (3) Correlation */ sum[2] += features->correlation; if (features->correlation < min[2]) min[2] = features->correlation; if (features->correlation > max[2]) max[2] = features->correlation; /* (4) Variance */ sum[3] += features->variance; if (features->variance < min[3]) min[3] = features->variance; if (features->variance > max[3]) max[3] = features->variance; /* (5) Inverse Diffenence Moment */ sum[4] += features->IDM; if (features->IDM < min[4]) min[4] = features->IDM; if (features->IDM > max[4]) max[4] = features->IDM; /* (6) Sum Average */ sum[5] += features->sum_avg; if (features->sum_avg < min[5]) min[5] = features->sum_avg; if (features->sum_avg > max[5]) max[5] = features->sum_avg; /* (7) Sum Variance */ sum[6] += features->sum_var; if (features->sum_var < min[6]) min[6] = features->sum_var; if (features->sum_var > max[6]) max[6] = features->sum_var; /* (8) Sum Entropy */ sum[7] += features->sum_entropy; if (features->sum_entropy < min[7]) min[7] = features->sum_entropy; if (features->sum_entropy > max[7]) max[7] = features->sum_entropy; /* (9) Entropy */ sum[8] += features->entropy; if (features->entropy < min[8]) min[8] = features->entropy; if (features->entropy > max[8]) max[8] = features->entropy; /* (10) Difference Variance */ sum[9] += features->diff_var; if (features->diff_var < min[9]) min[9] = features->diff_var; if (features->diff_var > max[9]) max[9] = features->diff_var; /* (11) Diffenence Entropy */ sum[10] += features->diff_entropy; if (features->diff_entropy < min[10]) min[10] = features->diff_entropy; if (features->diff_entropy > max[10]) max[10] = features->diff_entropy; /* (12) Measure of Correlation 1 */ sum[11] += features->meas_corr1; if (features->meas_corr1 < min[11]) min[11] = features->meas_corr1; if (features->meas_corr1 > max[11]) max[11] = features->meas_corr1; /* (13) Measure of Correlation 2 */ sum[12] += features->meas_corr2; if (features->meas_corr2 < min[12]) min[12] = features->meas_corr2; if (features->meas_corr2 > max[12]) max[12] = features->meas_corr2; /* (14) Maximal Correlation Coefficient */ sum[13] += features->max_corr_coef; if (features->max_corr_coef < min[13]) min[13] = features->max_corr_coef; if (features->max_corr_coef > max[13]) max[13] = features->max_corr_coef; free(features); } for (y = 0; y < Im.height; y++) delete [] p_gray[y]; delete [] p_gray; /* copy the values to the output vector in the right output order */ double temp[28]; for (a = 0; a < 14; a++) { temp[a] = sum[a]/4; temp[a+14] = max[a]-min[a]; } out[ 0] = temp[ 0]; out[ 1] = temp[14]; out[ 2] = temp[ 1]; out[ 3] = temp[15]; out[ 4] = temp[ 2]; out[ 5] = temp[16]; out[ 6] = temp[ 9]; out[ 7] = temp[23]; out[ 8] = temp[10]; out[ 9] = temp[24]; out[10] = temp[ 8]; out[11] = temp[22]; out[12] = temp[11]; out[13] = temp[25]; out[14] = temp[ 4]; out[15] = temp[18]; out[16] = temp[13]; out[17] = temp[27]; out[18] = temp[12]; out[19] = temp[26]; out[20] = temp[ 5]; out[21] = temp[19]; out[22] = temp[ 7]; out[23] = temp[21]; out[24] = temp[ 6]; out[25] = temp[20]; out[26] = temp[ 3]; out[27] = temp[17]; }
//--------------------------------------------------------------------------- int CombFirst4Moments2D(const ImageMatrix &Im, std::vector<double> vec) { double **I,**J,**J1,z4[4]={0,0,0,0},z[4]; double matr4moments[4][N_COMB_SAMPLES]; long m,n,n2,m2; long a,x,y,ii; int matr4moments_index; int vec_count=0; readOnlyPixels pix_plane = Im.ReadablePixels(); long step; Moments4 tmpMoments; for (a = 0; a < 4; a++) /* initialize */ for (matr4moments_index = 0; matr4moments_index < N_COMB_SAMPLES; matr4moments_index++) matr4moments[a][matr4moments_index] = 0; m=Im.height; n=Im.width; I=new double*[n]; J=new double*[n]; J1=new double*[n]; for (a = 0; a < n; a++) { I[a] = new double[m]; J[a] = new double[m]; J1[a] = new double[m]; } for (y = 0; y < m; y++) { for (x = 0; x < n; x++) { I[x][y] = y+1; J[x][y] = x+1; } } n2 = (int)(round(n/2)); m2 = (int)(round(m/2)); /* major diag -45 degrees */ matr4moments_index=0; step = (int)(round((double)m/10)); if (step < 1) step = 1; for (ii = 1-m; ii <= m; ii = ii+step) { for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index]=z4[a]; tmpMoments.reset(); for (y = 0; y < m; y++) { for (x = 0; x < n; x++) { if (fabs(I[x][y] + ii - J[x][y]) < 1) tmpMoments.add (pix_plane(y,x)); } } tmpMoments.momentVector(z); for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index] = z[a]; matr4moments_index++; } vec_count=matr4moments_to_hist(matr4moments,vec,vec_count); /* major diag +45 degrees */ /* fliplr J */ for (y = 0; y < m; y++) for (x = 0; x < n; x++) J1[x][y] = J[n-1-x][y]; matr4moments_index=0; step = (int)(round((double)m/10)); if (step < 1) step = 1; for (ii = 1-m; ii <= m; ii = ii+step) { for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index]=z4[a]; tmpMoments.reset(); for (y = 0; y < m; y++) { for (x = 0; x < n; x++) { if (fabs(I[x][y] + ii - J1[x][y]) < 1) tmpMoments.add (pix_plane(y,x)); } } tmpMoments.momentVector(z); for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index] = z[a]; matr4moments_index++; } vec_count=matr4moments_to_hist(matr4moments,vec,vec_count); /* vertical comb */ matr4moments_index=0; step = (int)(round((double)n/10)); if (step < 1) step = 1; for (ii = 1-n; ii <= n; ii = ii+step) { for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index]=z4[a]; tmpMoments.reset(); for (y = 0; y < m; y++) { for (x = 0; x < n; x++) { if (fabs(J[x][y] + ii - n2) < 1) tmpMoments.add (pix_plane(y,x)); } } tmpMoments.momentVector(z); for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index] = z[a]; matr4moments_index++; } vec_count=matr4moments_to_hist(matr4moments,vec,vec_count); /* horizontal comb */ matr4moments_index=0; step = (int)(round((double)m/10)); if (step < 1) step = 1; for (ii = 1-m; ii <= m; ii = ii+step) { for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index] = z4[a]; tmpMoments.reset(); for (y = 0; y < m; y++) { for (x = 0; x < n; x++) { if (fabs(I[x][y] + ii - m2) < 1) tmpMoments.add (pix_plane(y,x)); } } tmpMoments.momentVector(z); for (a = 0; a < 4; a++) matr4moments[a][matr4moments_index] = z[a]; matr4moments_index++; } vec_count=matr4moments_to_hist(matr4moments,vec,vec_count); /* free the memory used by the function */ for (a=0;a<n;a++) { delete [] I[a]; delete [] J[a]; delete [] J1[a]; } delete [] I; delete [] J; delete [] J1; return(vec_count); }