ImageMatrix<1> Segmentation::connectedComponents(ImageMatrix<1> &input) { size_t row_count = input.rows(); size_t col_count = input.cols(); m_labels = std::vector<std::vector<int> >(row_count, std::vector<int>(col_count)); Channel &in = input.grayscale(); int component = 0; for (size_t i = 0; i < row_count; ++i) { for (size_t j = 0; j < col_count; ++j) { if (!m_labels[i][j] && in[i][j]) { dfs(i, j, row_count, col_count, ++component, input); } } } int delta = 255 / component; ImageMatrix<1> output(row_count, col_count); Channel &out = output.grayscale(); for (size_t i = 0; i < row_count; ++i) { for (size_t j = 0; j < col_count; ++j) { int comp = m_labels[i][j]; out[i][j] = comp * delta; } } return output; }
/* EulerNumber The input image should be a binary image */ int EulerNumber(ImageMatrix *Im, int FeatureNumber) { int x,y,HolesNumber; ImageMatrix *cp; cp=Im->duplicate(); /* inverse the image */ for (y=0;y<cp->height;y++) for (x=0;x<cp->width;x++) if (cp->data[x][y].intensity>0) cp->data[x][y].intensity=0; else cp->data[x][y].intensity=1; HolesNumber=cp->BWlabel(8); delete cp; return(FeatureNumber-HolesNumber-1); }
/* 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); }
/** * Chebyshev Coefficients are calculated by performing a Chebyshev transform, * and generating a histogram of pixel intensities. * */ std::vector<double> ChebyshevCoefficients::calculate( ImageMatrix * IN_matrix ) { std::vector<double> coeffs; std::cout << "calculating " << name << std::endl; if( IN_matrix == NULL ) { return coeffs; } coeffs.reserve(n_features-1); double temp_vec [32]; ImageMatrix * temp = IN_matrix->duplicate(); for( int i = 0; i < n_features; i++ ) temp_vec[i] = 0; temp->ChebyshevStatistics2D(temp_vec, 0, 32); delete temp; coeffs.assign( temp_vec, temp_vec + n_features); return coeffs; }
/* 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); }
/* EulerNumber The input image should be a binary image */ int EulerNumber(ImageMatrix *Im, int FeatureNumber) { long x,y,z,HolesNumber; ImageMatrix *cp; cp=Im->duplicate(); /* inverse the image */ for (z=0;z<cp->depth;z++) for (y=0;y<cp->height;y++) for (x=0;x<cp->width;x++) { pix_data val=cp->pixel(x,y,z); if (cp->pixel(x,y,z).intensity>0) val.intensity=0; else val.intensity=1; cp->set(x,y,z,val); } HolesNumber=cp->BWlabel(8); delete cp; return(FeatureNumber-HolesNumber-1); }
void mb_zernike2D_OLD(const ImageMatrix &Im, double D, double R, double *zvalues, long *output_size) { double *Y,*X,*P,psum; double intensity; int x,y,size; *output_size=0; int rows = Im.height,cols = Im.width; if (D<=0) D=15; if (R<=0) R=rows/2; Y=new double[rows*cols]; X=new double[rows*cols]; P=new double[rows*cols]; readOnlyPixels I_pix_plane = Im.ReadablePixels(); /* Find all non-zero pixel coordinates and values */ size=0; psum=0; double moment10 = 0.0, moment00 = 0.0, moment01 = 0.0; for (y=0;y<rows;y++) for (x=0;x<cols;x++) { intensity = I_pix_plane(y,x); if (intensity != 0) { Y[size] = y+1; X[size] = x+1; P[size] = intensity; psum += intensity; size++; } // moments moment10 += (x+1) * intensity; moment00 += intensity; moment01 += (y+1) * intensity; // if (x < 10 && y < 10) printf ("(%d,%d) = %g\n",x,y,intensity); } /* Normalize the coordinates to the center of mass and normalize pixel distances using the maximum radius argument (R) */ double m10_m00 = moment10/moment00; double m01_m00 = moment01/moment00; mb_Znl (X,Y,P,size,D,m10_m00,m01_m00,R,psum,zvalues,output_size); delete Y; delete X; delete P; }
/* inputs: IM - image N - coefficient width - width of the image height - height of the image */ void Chebyshev2D(const ImageMatrix &Im, double *out, unsigned int N) { double *TjIn,*Tj; double *in; unsigned int a,i,j; // Make a default value for coeficient order if it was not given as an input // if (N< = 0) // N = min(Im.width,Im.height); TjIn = new double[Im.width]; for (a = 0; a < Im.width; a++) TjIn[a] = 2*(double)(a+1) / (double)Im.width -1; // Pre-compute Tj on x Tj = new double[Im.width*N]; TNx(TjIn,Tj,N,Im.width); in = new double[Im.width*Im.height]; readOnlyPixels Im_pix_plane = Im.ReadablePixels(); for (j = 0; j < Im.height; j++) for (i = 0; i < Im.width; i++) in[j*Im.width+i] = Im_pix_plane(j,i); getChCoeff(in,out,Tj,N,Im.width,Im.height); /* transpose the matrix "out" into "in" */ for (j = 0; j < N; j++) for (i = 0; i < Im.height/*Im.width*/; i++) in[j*Im.height+i] = out[i*N+j]; // If the height is different, re-compute Tj if (Im.height != Im.width) { delete [] Tj; delete [] TjIn; TjIn = new double[Im.height]; for (a = 0; a < Im.height; a++) TjIn[a] = 2*(double)(a+1) / (double)Im.height -1; // Pre-compute Tj on y Tj = new double[Im.height*N]; TNx(TjIn,Tj,N,Im.height); } getChCoeff(in,out,Tj,N,Im.height,N); delete [] in; delete [] TjIn; delete [] Tj; }
/* 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; }
void Segmentation::dfs(size_t x, size_t y, size_t h, size_t w, int currLabel, ImageMatrix<1> &input) { if (x < 0 || x >= h) { return; } if (y < 0 || y >= w) { return; } Channel &in = input.grayscale(); if (m_labels[x][y] || !in[x][y]) { return; } m_labels[x][y] = currLabel; for (int dir = 0; dir < 4; ++dir) { dfs(x + dx[dir], y + dy[dir], h, w, currLabel, input); } }
/* 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]; }
/* Algorithms for fast computation of Zernike moments and their numerical stability Chandan Singh and Ekta Walia, Image and Vision Computing 29 (2011) 251–259 Implemented from pseudo-code by Ilya Goldberg 2011-04-27 This code is 10x faster than the previous code, and 50x faster than previous unoptimized code. 200 x 200 image 2 GHz CoreDuo (ms): 3813 previous unoptimized 877 previous optimized 75 this implementation The values of the returned features are different, but their Fischer scores are slightly better on average than the previous version, and they produce better classification in problems where zernike features are useful. */ void mb_zernike2D (const ImageMatrix &Im, double order, double rad, double *zvalues, long *output_size) { int L, N, D; // N is the smaller of Im.width and Im.height N = Im.width < Im.height ? Im.width : Im.height; if (order > 0) L = (int)order; else L = 15; assert (L < MAX_L); if (! rad > 0.0) rad = N; D = (int)(rad * 2); static double H1[MAX_L][MAX_L]; static double H2[MAX_L][MAX_L]; static double H3[MAX_L][MAX_L]; static char init=1; double COST[MAX_L], SINT[MAX_L], R[MAX_L]; double Rn, Rnm, Rnm2, Rnnm2, Rnmp2, Rnmp4; double a,b,x, y, area, r, r2, f, const_t; int n,m,i,j; double AR[MAX_L][MAX_L], AI[MAX_L][MAX_L]; double sum = 0; int cols = Im.width; int rows = Im.height; readOnlyPixels I_pix_plane = Im.ReadablePixels(); // compute x/0, y/0 and 0/0 moments to center the unit circle on the centroid double moment10 = 0.0, moment00 = 0.0, moment01 = 0.0; double intensity; for (i = 0; i < cols; i++) for (j = 0; j < rows; j++) { intensity = I_pix_plane(j,i); sum += intensity; moment10 += (i+1) * intensity; moment00 += intensity; moment01 += (j+1) * intensity; } double m10_m00 = moment10/moment00; double m01_m00 = moment01/moment00; // Pre-initialization of statics if (init) { for (n = 0; n < MAX_L; n++) { for (m = 0; m <= n; m++) { if (n != m) { H3[n][m] = -(double)(4.0 * (m+2.0) * (m + 1.0) ) / (double)( (n+m+2.0) * (n - m) ) ; H2[n][m] = ( (double)(H3[n][m] * (n+m+4.0)*(n-m-2.0)) / (double)(4.0 * (m+3.0)) ) + (m+2.0); H1[n][m] = ( (double)((m+4.0)*(m+3.0))/2.0) - ( (m+4.0)*H2[n][m] ) + ( (double)(H3[n][m]*(n+m+6.0)*(n-m-4.0)) / 8.0 ); } } } init = 0; } // Zero-out the Zernike moment accumulators for (n = 0; n <= L; n++) { for (m = 0; m <= n; m++) { AR[n][m] = AI[n][m] = 0.0; } } area = PI * rad * rad; for (i = 0; i < cols; i++) { // In the paper, the center of the unit circle was the center of the image // x = (double)(2*i+1-N)/(double)D; x = (i+1 - m10_m00) / rad; for (j = 0; j < rows; j++) { // In the paper, the center of the unit circle was the center of the image // y = (double)(2*j+1-N)/(double)D; y = (j+1 - m01_m00) / rad; r2 = x*x + y*y; r = sqrt (r2); if ( r < DBL_EPSILON || r > 1.0) continue; /*compute all powers of r and save in a table */ R[0] = 1; for (n=1; n <= L; n++) R[n] = r*R[n-1]; /* compute COST SINT and save in tables */ a = COST[0] = x/r; b = SINT[0] = y/r; for (m = 1; m <= L; m++) { COST[m] = a * COST[m-1] - b * SINT[m-1]; SINT[m] = a * SINT[m-1] + b * COST[m-1]; } // compute contribution to Zernike moments for all // orders and repetitions by the pixel at (i,j) // In the paper, the intensity was the raw image intensity f = I_pix_plane(j,i) / sum; Rnmp2 = Rnm2 = 0; for (n = 0; n <= L; n++) { // In the paper, this was divided by the area in pixels // seemed that pi was supposed to be the area of a unit circle. const_t = (n+1) * f/PI; Rn = R[n]; if (n >= 2) Rnm2 = R[n-2]; for (m = n; m >= 0; m -= 2) { if (m == n) { Rnm = Rn; Rnmp4 = Rn; } else if (m == n-2) { Rnnm2 = n*Rn - (n-1)*Rnm2; Rnm = Rnnm2; Rnmp2 = Rnnm2; } else { Rnm = H1[n][m] * Rnmp4 + ( H2[n][m] + (H3[n][m]/r2) ) * Rnmp2; Rnmp4 = Rnmp2; Rnmp2 = Rnm; } AR[n][m] += const_t * Rnm * COST[m]; AI[n][m] -= const_t * Rnm * SINT[m]; } } } } int numZ=0; for (n = 0; n <= L; n++) { for (m = 0; m <= n; m++) { if ( (n-m) % 2 == 0 ) { AR[n][m] *= AR[n][m]; AI[n][m] *= AI[n][m]; zvalues[numZ] = fabs (sqrt ( AR[n][m] + AI[n][m] )); numZ++; } } } *output_size = numZ; }
//--------------------------------------------------------------------------- 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); }