コード例 #1
0
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;
}
コード例 #2
0
/* 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);
}
コード例 #3
0
/* 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);
}
コード例 #4
0
/**
 * 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;
}
コード例 #5
0
/* 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);
}
コード例 #6
0
/* 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);
}
コード例 #7
0
ファイル: zernike.cpp プロジェクト: HunterUSF/wnd-charm
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;

}
コード例 #8
0
ファイル: chebyshev.cpp プロジェクト: HunterUSF/wnd-charm
/* 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;
}
コード例 #9
0
/* 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);
}
コード例 #10
0
/* 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;
}
コード例 #11
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);
    }
}
コード例 #12
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);
}
コード例 #13
0
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];
}
コード例 #14
0
ファイル: zernike.cpp プロジェクト: HunterUSF/wnd-charm
/*
  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;

}
コード例 #15
0
//---------------------------------------------------------------------------
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);
}