⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zernike.java

📁 求图形Zernike矩的java程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

  if (inband.getType() != BufferedImage.TYPE_BYTE_GRAY)
    System.out.print( "zer_rec: Input pixel type must be unsigned byte.\n");
  if (outband.getType() != BufferedImage.TYPE_BYTE_GRAY)
    System.out.print("zer_rec: Output pixel type must be unsigned byte.\n");

  isize = inband.getWidth();
  jsize = inband.getHeight();

    int[] src_1d=new int[isize*jsize];

    Raster rt=inband.getData();
    rt.getSamples(0,0,isize,jsize,0,src_1d);

    double[] mt=ImageOps.mmt(inband);
    Point centroid=new Point((int)mt[1],(int)mt[2]);

  i_0 = (isize+1)/2.0;
  j_0 = (jsize+1)/2.0;
  i_scale = isize/2.0;
  j_scale = jsize/2.0;

  int[] box={0,isize-1,0,jsize-1};
  transformed = new DCOMPLEX[jsize+1][isize+1];//(IDC_BAND) Imake_band(Id_complex_typ, isize, jsize);

  for (i=1; i<=isize; i++)
    for (j=1; j<=jsize; j++)
      {
        transformed[j][i]=new DCOMPLEX();
	transformed[j][i].re = 0.0;
	transformed[j][i].im = 0.0;
      }
  for (n=1; n<=order; n++)
    {
      for (m=-n; m<=n; m++)
	{
	  if ((n-Math.abs(m)) %2 == 0)
	    {

//	      zer_mom(inband, n,m, a);
              zer_mom(src_1d,isize,jsize,centroid, n,m, a);

//              DCOMPLEX zer=Zernike2.MomentZernike(src_1d,isize,jsize,box,n,m);
//              a[0]=zer.clone2();
              System.out.print("zer_rec: A("+n+","+m+")=("+a[0].re+","+a[0].im+").\n");

	      for (i=1; i<=isize; i++)
		for (j=1; j<=jsize; j++)
		  {
		    x = (i-i_0)/i_scale;
		    y = (j-j_0)/j_scale;
		    /*if (x*x + y*y <= 1.0) */
		    /*printf ("zer_rec: x=%6.3f y=%6.3f i=%i j=%i\n", x,y,i,j);
		     */
		    zer_pol(n,m,x,y, v);
		    transformed[j][i].re += a[0].re*v[0].re - a[0].im*v[0].im;
		    transformed[j][i].im += a[0].re*v[0].im + a[0].im*v[0].re;
		    /*printf ("zer_con: x,y=(%6.3f,%6.3f), contr=(%9.6f,%9.6f),",
		      x,y,transformed[j][i].re,
		      transformed[j][i].im);*/
		    /*printf (" a=(%9.6f,%9.6f), v=(%9.6f,%9.6f)\n",
		      a.re, a.im, v.re, v.im);*/
		  }
	    }
	}
    }//end for
/*
 *  The following code fragment take imaginary of the complex into consideration

  double min, max,scale;
  for (i=1; i<=isize; i++)
    for (j=1; j<=jsize; j++)
      {
	transformed[j][i].re = Math.sqrt
	  (  transformed[j][i].re*transformed[j][i].re
	   + transformed[j][i].im*transformed[j][i].im);
	transformed[j][i].im = 0.0;
      }
  min = max = transformed[1][1].re;
  for (i=1; i<=isize; i++)
    for (j=1; j<=jsize; j++)
      {
	if (transformed[j][i].re > max)
	  max = transformed[j][i].re;
	if  (transformed[j][i].re < min)
	  min = transformed[j][i].re;
      }
  if (max == min)
    scale = 0.0;
  else
    scale = 255.0/(max-min);
  System.out.print("zer_rec: min="+min+", max="+max+", sacle="+scale+"\n");

 *  Code fragment ends here
 */

  int[] dest=new int[isize*jsize];
  int k=-1;
  for (i=1; i<=isize; i++)
    for (j=1; j<=jsize; j++)
      {
        k++;
	if (transformed[j][i].re <= 0.0)
          dest[k]=0;
        else dest[k]=(int)transformed[j][i].re;//255;
//	else if (transformed[j][i].re > 255.0)
//           dest[k]=255;
//	else dest[k]=(int)(transformed[j][i].re);
//	  outband.getRaster().setSample(j,i,0,(byte)(transformed[j][i].re));//outband[j][i] = (byte) (transformed[j][i].re);
/*	printf ("zer_con: outband[%3i][%3i]=%3i\n", j, i, outband[j][i]);*/
      }
  outband.getRaster().setSamples(0,0,isize,jsize,0,dest);
  return outband;
} /* zer_rec */

//int main(int argc, char[][] argv)
//{
//  int order;
//  char infile[], outfile[], args[], title[];
//  BufferedImage inband, outband, tempband;
//  IMAGE inimage, outimage;
//  int xsize, ysize;
//  long start_time, elapsed_time;
//  int reconstruct;
//  int status;
//
//  Iset_message(TRUE);
//  Iset_abort(TRUE);
//  InitMessage(argc, argv, xite_app_std_usage_text(
//    "Usage: %s [-n <n>] [-r] [-t <title>] <inimage> <outimage>\n"));
//
//  if (argc == 1) Usage(1, NULL);
//
//  args = argvOptions(argc, argv); /* Save command-line arguments. */
//
//  order       = read_iswitch(argc, argv, "-n", 0);
//  reconstruct = read_bswitch(argc, argv, "-r");
//  title       = read_switch(argc, argv, "-t", 1,
//			    reconstruct ? "zernike reconstructed" : "zernike");
//
//  if (argc < 3) Usage(2, "Illegal number of arguments.\n");
//
//  infile  = argv[argc-2];
//  outfile = argv[argc-1];
//
//  /* Start the clock */
//
//  start_time = clock();
//
//  /* Read input image from file */
//
//  inimage = Iread_image(infile);
//  inband  = (BufferedImage)inimage[1]; /* First band only is used. */
//
//  xsize = inband.getWidth();
//  ysize = inband.getHeight();
//
//  /* Make data structure for output image */
//
//  outimage = Icopy_init(inimage);
//  Iset_title(outimage, title);
//  outband  = (BufferedImage) outimage[1];
//
//  if (reconstruct) {
//    zer_rec (order, inband, outband);
//    /* histoEq(tempband, outband, 256);*/
//  } else {
//    tempband = Imake_band(Iu_byte_typ, xsize, ysize);
//    zer_con (order, inband, tempband);
//    histoEq(tempband, outband, 256);
//    Idel_band (tempband);
//  }
//
//  elapsed_time = clock() - start_time;
//  System.out.print("Time used (CPU) : %fs\n", elapsed_time / 1e6);
//
//  Ihistory(outimage, argv[0], args);
//  status = Iwrite_image(outimage, outfile);
//
//  return 0; /* Unix commands should return 0 */
//
//} /* main() */
/**
 *  return all zernike moments less or equal than the order
 */
  public static Vector zer_mmts(int order, BufferedImage inband)
  {
    Vector mmts=new Vector();
    int n, m;
    int i, j;
    double i_0, j_0;
    double i_scale, j_scale;
    int isize, jsize;
    double x, y;
    if(order<=0) return null;
    DCOMPLEX[][] A=new DCOMPLEX[order+1][order+1];


    if (inband.getType() != BufferedImage.TYPE_BYTE_GRAY)
      System.out.print( "zer_rec: Input pixel type must be unsigned byte.\n");

    isize = inband.getWidth();
    jsize = inband.getHeight();
    int[] src_1d=new int[isize*jsize];

    Raster rt=inband.getData();
    rt.getSamples(0,0,isize,jsize,0,src_1d);

    double[] mt=ImageOps.mmt(inband);
    Point centroid=new Point((int)mt[1],(int)mt[2]);

//    i_0 = (isize+1)/2.0;
//    j_0 = (jsize+1)/2.0;
//    i_scale = isize/2.0;
//    j_scale = jsize/2.0;
/**
 * Only consider order above 2
 * Notice |A(p,q)|=|A(p,-q)|
 */
    for (n=0; n<=order; n++)
        for (m=0; m<=n; m++)
          {
            if ((n-Math.abs(m)) %2 == 0)
              {
                DCOMPLEX[] a=new DCOMPLEX[1];
                a[0]=new DCOMPLEX();
                zer_mom(src_1d,isize,jsize,centroid, n,m, a);
                A[n][m]=a[0];//.getModulus();
                mmts.add(a[0]);
                System.out.print("zer_mmts: A("+n+","+m+")=("+a[0].re+","+a[0].im+").\n");
              }
          }//end for



    utility.save2DArray(A,"mmt1.mat");
    DCOMPLEX[][] B=normalize(A);
//    utility.save2DArray(B,"mmt2.mat");
    DCOMPLEX[][] ZMI=getZMI(B);
    utility.save2DArray(ZMI,"mmt3.mat");
    Vector ZMIS=new Vector();

    //we don't want to judge inside for loop
    if(zernikeFea.fea_index!=null && zernikeFea.fea_index[0]==null){
      int k=0;
      for(i=0; i<ZMI.length;i++)
        for(j=0;j<ZMI[i].length;j++)
          if(ZMI[i][j]!=null){
            ZMIS.add(ZMI[i][j]);
            if(k>=2)
            zernikeFea.fea_index[k-2]=new Point(i,j);
            k++;
          }
    }
    else{
      for(i=0; i<ZMI.length;i++)
          for(j=0;j<ZMI[i].length;j++)
            if(ZMI[i][j]!=null){
              ZMIS.add(ZMI[i][j]);
            }
    }//endif
    //ignore A[0][0] and A[1][1]
    ZMIS.removeElementAt(0);
    ZMIS.removeElementAt(0);

    return ZMIS;


//    return mmts;
  }//end of zer_mmts



/**
 * Normalize the absolute value of Zernike moments
 * According to the  reference [2]
 */
  static DCOMPLEX[][] normalize(DCOMPLEX[][] A){
        int order=A.length-1;
        DCOMPLEX[][] B=new DCOMPLEX[order+1][order+1];


        B[0][0]=A[0][0].clone2();
        B[1][1]=A[1][1].clone2();

        for (int n=2; n<=order; n++)
          for (int m=0; m<=n; m++)
            if ((n-Math.abs(m)) %2 == 0){
               B[n][m]=A[n][m].clone2();
              if(n!=m && A[n-2][m].getModulus()!=0) {
                B[n][m].mo=A[n][m].getModulus()/A[n-2][m].getModulus();
//                System.out.print("B["+n+"]"+"["+m+"]="+"A["+n+"]["+m+"]/A["+(n-2)+"]["+m+"]\n");
              }
//               System.out.print("B["+n+"]"+"["+m+"]="+B[n][m]+"\n");
            }
      return B;

  }//end of normalize

  /**
   * Compute the ZMIs(NZMIs) according to reference [2]
   */
   static DCOMPLEX[][] getZMI(DCOMPLEX[][] A){
      int order=A.length-1;
      DCOMPLEX[][] B=new DCOMPLEX[order+1][2*order+1];


      for (int n=0; n<=order; n++){
        for (int m=0; m<=n; m++)
          if ((n-Math.abs(m)) %2 == 0){
             B[n][m]=A[n][m].clone2();
            }

        if(n%2==0 && n>=4){
          double degree;
          for(int L=4;L<=n;L+=2){
            int z=L/2;
            int p=2/L;
            degree=p*A[n][L].theta-A[n][2].theta;

            B[n][n+z]=new DCOMPLEX();

            B[n][n+z].mo=2*A[n][2].getModulus()*Math.pow(A[n][L].getModulus(),p)*Math.cos(degree);
            if(B[n][n+z].mo<0) B[n][n+z].mo=-B[n][n+z].mo;
          }

          degree=A[n-2][2].theta-A[n][2].theta;

          B[n][n+1]=new DCOMPLEX();

          B[n][n+1].mo=2*A[n-2][2].getModulus()*A[n][2].getModulus()*Math.cos(degree);
          if(B[n][n+1].mo<0) B[n][n+1].mo=-B[n][n+1].mo;
        }//endif

        if(n%2==1 && n>=3){
          double degree;
          for(int L=3;L<=n;L+=2){

            double p=1/L;
            degree=p*A[n][L].theta-A[n][1].theta;

            B[n][n+L]=new DCOMPLEX();

            B[n][n+L].mo=2*A[n][1].getModulus()*Math.pow(A[n][L].getModulus(),p)*Math.cos(degree);
            if(B[n][n+L].mo<0) B[n][n+L].mo=-B[n][n+L].mo;
          }

          degree=A[n-2][1].theta-A[n][1].theta;
          B[n][n+1]=new DCOMPLEX();
          B[n][n+1].mo=2*A[n-2][1].getModulus()*A[n][1].getModulus()*Math.cos(degree);
          if(B[n][n+1].mo<0) B[n][n+1].mo=-B[n][n+1].mo;

        }//endif

      }//end for


      return B;

  }//end of normalize


}//end of zernike

// public class DCOMPLEX{
//  double re, im;
//  public DCOMPLEX() {
//    re=0.0;
//    im=0.0;
//  }
//};



/*P:zernike*

________________________________________________________________

		zernike
________________________________________________________________

Name:		zernike - zernike moment image of a gray scale
                or binary image

Syntax:		zernike [-n <n>] [-r] [-t <title>] <inimage> <outimage>

Description:	The Zernike moment of order 'n' and repetition 'm' of
                an image f(x,y) is defined as follows:
		|          n+1                             *
                | A(n,m) = ---- Sum Sum f(x,y)[V(n,m, x,y)]
		|           pi   x   y
		|
		| where x^2+y^2 <= 1
		|
		The image V(n,m, x,y) is the Zernike basis images of
		order 'n' and repetition 'm'. These basis images are
		complex and orthogonal. The Zernike moments are
		essentially the projections of the input image onto
		these basis images.

		The original image can be reconstructed from the
		Zernike moments. The N-th order approximation is given
		by
		|  ^         N
		|  f(x,y) = Sum Sum A(n,m) V(n,m, x,y)
		|           n=0  m
		|
		The contribution or information content of the n-th
		order moments is
		|
		|  I(x,y, n) = Sum A(n,m) V(n,m, x,y)
		|              m

Restrictions:   'inimage' must be single-band with pixel type unsigned byte.

Options:	&-n n
                Use moment order 'n'. Default 0.

                &-r
                Reconstruct image from moments. Default: Compute the absolute
		value of I(x,y, n).

		&-t title
		Use 'title' for 'outimage'.

See also:       zer_mom(3), zer_con(3), zer_rec(3), zer_pol(3)

References:     &[1] 'A. Khotanzad and Y.H. Hong'
                "Invariant image recognition by Zernike Moments",
		IEEE trans. on Pattern Analysis and Machine Intelligence,
                vol.12, no.5, pp.489-487, May 1990.

                &[2] 'A. Khotanzad and Y.H. Hong'
                "Rotation invariant image recognition using features
		selected via a systematic method",
		Pattern Recognition, vol.23, no.10, pp.1089-1101, 1990.

		&[3] 'Thomas H. Reiss'
		"Recognizing Planar Objects Using Invariant Image Features",
		Lecture Notes in Computer Science, volume 676, pp. 17-20,
		Springer-Verlag, 1993.

Return value:   0 : OK
Files:          | xite/src/zernike/zernike.c
Author:		豬vind Due Trier, Ifi, UiO.
________________________________________________________________

*/

/**
 *  The experiments results:
 *     1. n must be less than 14, or noise will appear in the reconstructed image
 *     2. when reconstruct, only uses the real part
 *     3. the result will be better when original image is 64*64 and is binary
 *     4. the image size seems doesn't matter, while the larger the slower
 *     5. at most two char together in  one image will be recognized
 *     6. the content in the center of the image is more easily recognized
 */





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -