import ij.*; import java.io.*; import ij.plugin.filter.PlugInFilter; import ij.gui.*; import ij.process.*; import java.awt.*; import java.awt.image.*; import ij.text.TextWindow; import java.util.*; /** Implements ImageJ's Analyze Particles command. */ public class Descriptor_Moment implements PlugInFilter { private RuffleParticle[][] m_nParticleRec; private RuffleParticle[] m_lstParticle; private ImageStack StackParticle; private ImagePlus StackImp; private int m_nHeight, m_nWidth; private double m_dMinThr, m_dMaxThr; private TextWindow tw; private static int staticMinSize = 25; private static int staticMaxSize = 10000; private static double staticMinAxisLen = 1; private static int staticLowerThr = 1; private int minSize; private int maxSize; private double MinAxisLen; private int LowerThr; public int setup(String arg, ImagePlus imp) { String Para = arg; if(Para.length()>3) { } if( !showDialog() ) return DONE; return DOES_8G+DOES_STACKS+SUPPORTS_MASKING; } /** Displays a modal options dialog. */ public boolean showDialog() { GenericDialog gd = new GenericDialog("Analyze Particles"); minSize = staticMinSize; maxSize = staticMaxSize; MinAxisLen = staticMinAxisLen; LowerThr = staticLowerThr; gd.addNumericField("Minimum Size (pixels):", minSize, 0); gd.addNumericField("Maximum Size (pixels):", maxSize, 0); gd.addNumericField("Min Axis Length:", MinAxisLen, 2); gd.addNumericField("Lower Threshold:", LowerThr, 0); gd.showDialog(); if (gd.wasCanceled()) return false; minSize = (int)gd.getNextNumber(); maxSize = (int)gd.getNextNumber(); MinAxisLen = (double)gd.getNextNumber(); LowerThr = (int)gd.getNextNumber(); if (gd.invalidNumber()) { IJ.error("Minimum Size, Maximum Size or Bins invalid."); return false; } staticMinSize = minSize; staticMaxSize = maxSize; staticMinAxisLen = MinAxisLen; staticLowerThr = LowerThr; return true; } boolean Initialize(ImageProcessor ip) { //The height and width of the image m_nHeight = ip.getHeight(); m_nWidth = ip.getWidth(); if(m_nHeight<=0 || m_nWidth<=0) { IJ.showMessage("Particle Analyzer", "Invalid Image size." ); return false; } m_nParticleRec = new RuffleParticle[m_nWidth][m_nHeight]; for(int i=0; i=m_nWidth || nPosY<0 || nPosY>=m_nHeight) { return 1; } int nBrightness = ip.getPixel(nPosX, nPosY); if( nBrightness= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } } //Left nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosX>=0; nNewPosX--) { nBrightness = ip.getPixel(nNewPosX, nNewPosY); if( nBrightness >= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } } //Upper nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosY= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } } //Lower nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosY>=0; nNewPosY--) { nBrightness = ip.getPixel(nNewPosX, nNewPosY); if( nBrightness >= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } } //Right-Upper nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosX= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } nNewPosY--; if(nNewPosY<0) break; } //Left-Upper nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosX>=0; nNewPosX--) { nBrightness = ip.getPixel(nNewPosX, nNewPosY); if( nBrightness >= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } nNewPosY--; if(nNewPosY<0) break; } //Right-Lower nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosX= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } nNewPosY++; if(nNewPosY>=m_nHeight) break; } //Left-Lower nNewPosX = nStartX; nNewPosY = nStartY; for(;nNewPosX>=0; nNewPosX--) { nBrightness = ip.getPixel(nNewPosX, nNewPosY); if( nBrightness >= m_dMinThr ) { m_nParticleRec[nNewPosX][nNewPosY] = particle; } else { break; } nNewPosY++; if(nNewPosY>=m_nHeight) break; } //Search for the point boolean bFound = false; for(int i=0; iminSize ) { if( nPixelCount>maxSize ) { nPos++; continue; } byte[] tmp = new byte[m_nWidth*m_nHeight]; System.arraycopy(pixels, 0, tmp, 0, m_nWidth*m_nHeight); StackParticle.addSlice("", tmp); bSliceExist = true; } //Update the loop controller nPos++; } if(bSliceExist) { StackImp = new ImagePlus("Particle", StackParticle); StackImp.show(); } else { byte[] tmp = new byte[m_nWidth*m_nHeight]; StackParticle.addSlice("", tmp); StackImp = new ImagePlus("Particle", StackParticle); StackImp.show(); } return bSliceExist; } int EvalPerimerter(RuffleParticle Particle) { int nPerimeter = 0; for(int i=0; i=m_nWidth || nPosY<0 || nPosY>=m_nHeight) { return -1; } if( m_nParticleRec[nPosX][nPosY]!=SelParticle ) return -1; int nNbX, nNbY; int nBndSide = 0; //Upper nNbX = nPosX; nNbY = nPosY-1; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( m_nParticleRec[nNbX][nNbY]!=SelParticle ) return 1; } //Lower nNbX = nPosX; nNbY = nPosY+1; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( m_nParticleRec[nNbX][nNbY]!=SelParticle ) return 1; } //Left nNbX = nPosX-1; nNbY = nPosY; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( m_nParticleRec[nNbX][nNbY]!=SelParticle ) return 1; } //Right nNbX = nPosX+1; nNbY = nPosY; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( m_nParticleRec[nNbX][nNbY]!=SelParticle ) return 1; } return 0; } void JudgeRuffle(ImageProcessor ip) { int nSlice = StackParticle.getSize(); String OutFile = "c:\\result.txt"; String Space = "\t"; String ColName ="No." + Space + "Area" + Space + "M1" + Space + "M2"; double[] dResultArray = new double[100]; try { PrintWriter q = new PrintWriter( new FileWriter(OutFile), true ); q.println(ColName); for(int i=1; i<=nSlice; i++) { for(int j=0; j<99; j++) dResultArray[j] = 0.0; byte[] pixels = (byte[])StackParticle.getPixels(i); if(pixels==null) break; ProcessOneParticle(pixels, dResultArray, ip); String RowData = i-1 + Space + dResultArray[0] + Space + dResultArray[5] + Space + dResultArray[6]; q.println(RowData); } } catch (Exception e) { e.printStackTrace(); // this will print the error to standard output } } void ProcessOneParticle(byte[] pixels, double[] dResultArray, ImageProcessor ip) { boolean[][] ImgOrg = new boolean [m_nWidth][m_nHeight]; int nPixelCount = 0; int nPos=0; for(int i=0; imaxSize || nPixelCount=m_nWidth || nPosY<0 || nPosY>=m_nHeight) { return -1; } if( Img[nPosX][nPosY]==false ) return -1; int nNbX, nNbY; int nBndSide = 0; //Upper nNbX = nPosX; nNbY = nPosY-1; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( Img[nNbX][nNbY]==false ) return 1; } //Lower nNbX = nPosX; nNbY = nPosY+1; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( Img[nNbX][nNbY]==false ) return 1; } //Left nNbX = nPosX-1; nNbY = nPosY; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( Img[nNbX][nNbY]==false ) return 1; } //Right nNbX = nPosX+1; nNbY = nPosY; if(nNbX<0 || nNbX>=m_nWidth || nNbY<0 || nNbY>=m_nHeight) { return 1; } else { if( Img[nNbX][nNbY]==false ) return 1; } return 0; } double find_moment( boolean[][] ImageX, int p, int q, int N1, int M1, int N2, int M2, double _x, double _y, ImageProcessor ip, double[] dEvalArea) { int i, j, k; double a=0, h; dEvalArea[0] = 0.0; for( i=N1, a=0.; i0.0) dAngleMod = dAngle; else dAngleMod = dAngle + Math.PI*2.0; double r = Math.sqrt(x0*x0 + y0*y0); double xr = x0 * Math.cos(dAngleMod) + y0 * Math.sin(dAngleMod); double yr = -( x0 * Math.sin(dAngleMod) ) + y0 * Math.cos(dAngleMod); if(bFirstEnter) { bFirstEnter = false; dMinX = dMaxX = xr; dMinY = dMaxY = yr; } if(dMinX>xr) dMinX = xr; if(dMaxXyr) dMinY = yr; if(dMaxY