import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.plugin.*; import java.io.*; /** Reconstructs a 3D image of a spherical object from six different 2D views. * Where each of the six 2D views corresponds one side of a cube. * @author Chris Tsang and Gurinder Kler * @version 1.0.0 * @date March 7, 2002 */ public class Run3D_ implements PlugIn{ /** Run in an ImageJ plugin corresponds to main in a java program * @param arg a string argument, is not used in this program */ public void run(String arg) { CenterImage centered= new CenterImage(); XYZ coordinates = new XYZ(); ImageRadius calcradius= new ImageRadius(); int radius=0; int centerX=0; int centerY=0; /*int radius=98; int centerX=160; int centerY=120;*/ int view; int[] idlist=WindowManager.getIDList(); IntVariables intVars = new IntVariables(0,0,0); int validCount=0; //counts the number of validVoxels int countVoxels=0; //number of voxels in sphereVoxels long time=System.currentTimeMillis(); long time2=time; //Finds Count of Valid Voxels //validCount = surfaceVoxelCount(h, w, centerX, centerY, radius); validCount = surfaceVoxelCount(radius*2, radius*2, radius, radius, radius); //IJ.showMessage("validCount is "+validCount); //Creates a Voxel array of size of validCount, ie the valid number of voxels //initializes voxelValue coordinates to 0,0,0 //voxelValue are the pixels for one of the six views Voxel[] voxelValue = new Voxel[validCount]; for (int a = 0; a_top,_bottom ....etc."); }//catch }//orderProjections /** Determines the position title of the image * @param workpic is an Imageplus whose title is wanted * @return returns the title type of the image, ie top, bottom, left, right, front, back */ public String positionTitle( ImagePlus workpic){ String pictitle= new String(); int index; int index2; String[] titles={ "top","bottom","left","right","front","back"}; boolean found=false; pictitle=workpic.getTitle(); index=pictitle.indexOf('_'); index2=pictitle.indexOf('.'); index++; try{ pictitle=pictitle.substring(index,index2); } catch(StringIndexOutOfBoundsException e){ pictitle=("none"); } return pictitle; }//positionTitle /** Determines the weight of greyscales of image with Voxels voxelValue and stores * date in image with Voxels sphereVoxels * @param voxelValue Are the voxels of one of the six original views to have its greyscales weighted * @param sphereVoxels Is where the voxels of the sphere are stored with its new calculated greyscales * @param radius Is the radius of the sphere * @param validCount Is the number of valid pixels in each of the six views * @param view Is the current view being calculated, 0 to 5 * @param intVars Is a class which is used to pass integer variables, in this case intA is * countVoxels, which keeps track of the number of voxels in sphereVoxels */ public void weight(Voxel[] voxelValue, Voxel[] sphereVoxels, int radius, int validCount, int view, IntVariables intVars){ byte currentGrey; int index=0; int i; int countVoxels=intVars.getA(); double temp1=0; double temp2=0; //IJ.setColumnHeadings("x \t y \t z \t origGrey \t newGrey \t weight"); temp2=radius*radius; //validCount=100; for (int a=0; a0) XShiftRight(xshift,ip,height,width); else XShiftLeft(xshift,ip,height,width); if(yshift!=0) if(yshift<0) YShiftUp(yshift,ip,height,width); else YShiftDown(yshift,ip,height,width); }//run /** * The AverageCenterX function finds the number of valid pixels within a picture based on a threshold value. * * @param ip current ImageProcessor that is opened * @param height height of the current image * @param width width of the current image * @return the average center of the spherical object in the horizontal direction */ public int AverageCenterX(ImageProcessor ip,int height,int width){ byte[] pixels = (byte[])ip.getPixels(); //returns reference to all the pixels in an image int offset, i; int centerx=width/2; int centery=height/2; int valid, //valid is a count of all valid pixels in a row cvalid, //cvalid is a count of consecutive valid pixels cvalidmax; //cvalidmax is the max of the consecutive valid pixels in a row int sumco; //sumco is the sum of the valid pixel locations int[] centers=new int[height]; //stores the calculated center for each row. int totalcenter=0; //the sum of all calculated centers int avgcenter=0, //average of all the centers numrows=0, //the number of rows with valid pixels xshift=0, //difference of avgcenter and centerx of picture yshift=0; //difference of avgcenter and centery of picture //int validb, valida; //IJ.setColumnHeadings("row \t validb \t sumco \t valida \t cvalidmax \t average"); //for each row of pixels determine how many valid pixels fall within the threshold for (int y=0; y23){ valid++; cvalid++; sumco+=x; if(cvalid>cvalidmax) cvalidmax=cvalid; } else cvalid=0; } //valida=valid; //if the value of valid pixels is greater than 10 calculate the center of the object within that row if(cvalidmax >10){ centers[y]=sumco/valid; totalcenter+=centers[y]; numrows++; } else centers[y]=0; // IJ.write(y+"\t"+validb+"\t"+sumco+"\t"+valida +"\t"+cvalidmax+"\t"+centers[y]+"\t"); } if (numrows>0) avgcenter=totalcenter/numrows; else IJ.showMessage("Error \n numrows is "+numrows); IJ.write("Valid number of rows: "+numrows+"\n"+ "Average center of object: "+avgcenter+"\n"+ "Midpoints of picture(wxh): "+width/2+" "+height/2); return avgcenter; }//AverageCenterX /** * The AverageCenterY function finds the number of valid pixels within a picture based on a threshold value. * * @param ip current ImageProcessor that is opened * @param height height of the current image * @param width width of the current image * @return the average center of the spherical object in the horizontal direction */ public int AverageCenterY(ImageProcessor ip,int height,int width){ byte[] pixels = (byte[])ip.getPixels(); //returns reference to all the pixels in an image int offset, i; int centerx=width/2; int centery=height/2; int valid, //valid is a count of all valid pixels in a row cvalid, //cvalid is a count of consecutive valid pixels cvalidmax; //cvalidmax is the max of the consecutive valid pixels in a row int sumco; //sumco is the sum of the valid pixel locations int[] centers=new int[width]; //stores the calculated center for each column. int totalcenter=0; //the sum of all calculated centers int avgcenter=0, //average of all the centers numrows=0, //the number of rows with valid pixels xshift=0, //difference of avgcenter and centerx of picture yshift=0; //difference of avgcenter and centery of picture //int validb=0, valida=0; //for each column of pixels determine how many valid pixels fall within the threshold for(int x=0;x23){ valid++; cvalid++; sumco+=y; if(cvalid>cvalidmax) cvalidmax=cvalid; } else cvalid=0; } //valida=valid; //if the value of valid pixels is greater than 10 calculate the center of the object within that row if(cvalidmax >10){ centers[x]=sumco/valid; totalcenter+=centers[x]; numrows++; } else centers[x]=0; } if (numrows>0) avgcenter=totalcenter/numrows; else IJ.showMessage("Error \n numrows is "+numrows); IJ.write("Valid number of rows: "+numrows+"\n"+ "Average center of object: "+avgcenter+"\n"+ "Midpoints of picture(wxh): "+width/2+" "+height/2); return avgcenter; }//AverageCenterY /* The XShiftRight method shifts the pixels in the picture 'shiftx' times * towards the horizontal center of the image window. * * @param shiftx number of right shifts required to shift image to center * @param ip current ImageProcessor that is opened * @param height height of the current image * @param width width of the current image */ public void XShiftRight(int shiftx,ImageProcessor ip,int height,int width){ byte[] pixels = (byte[])ip.getPixels(); int offset=0; byte tempixel=0, prevpixel=0; int i=0; for(int shifts=0;shifts=0; x--) { i = offset + x; if(x==width-1){ nextpixel=(byte)pixels[i]; pixels[i]=(byte)pixels[offset]; } else{ tempixel=(byte)pixels[i]; pixels[i]=(byte)nextpixel; nextpixel=(byte)tempixel; } } } } }//XshiftRight /* The YShiftUp method shifts the pixels in the picture 'shiftx' times * towards the vertical center of the image window. * * @param shiftx number of left shifts required to shift image to center * @param ip current ImageProcessor that is opened * @param height height of the current image * @param width width of the current image */ public void YShiftUp(int shifty,ImageProcessor ip,int height,int width){ byte[] pixels = (byte[])ip.getPixels(); int offset=0; byte tempixel=0,nextpixel=0; int i=0; for(int shifts=0;shifts=0; y--) { i = width*y+x; if(y==height-1){ nextpixel=(byte)pixels[i]; pixels[i]=(byte)pixels[x]; } else{ tempixel=(byte)pixels[i]; pixels[i]=(byte)nextpixel; nextpixel=(byte)tempixel; } } } } }//YShiftUp /* The YShiftDown method shifts the pixels in the picture 'shiftx' times * towards the vertical center of the image window. * * @param shiftx number of left shifts required to shift image to center * @param ip current ImageProcessor that is opened * @param height height of the current image * @param width width of the current image */ public void YShiftDown(int shifty,ImageProcessor ip,int height,int width){ byte[] pixels = (byte[])ip.getPixels(); int offset=0; byte tempixel=0,nextpixel=0; int i=0; for(int shifts=0;shifts3) break; } if(lastpoint[number]>maxradius) maxradius=lastpoint[number]; IJ.write("lastpoint "+lastpoint[number]); number++; } //check to see if the lastpoint is valid (maxradius-3) for(int k=0;k=(maxradius-3)){ validradii++; totalradii+=lastpoint[k]; } /* if(lastpoint>90){ validradii++; totalradii+=lastpoint; //IJ.write("lastpoint "+lastpoint); } */ } averageradii=totalradii/validradii; IJ.write("Radius of spherical object:"+averageradii); //IJ.write("number"+number); //IJ.write("maxradius"+maxradius); }//run }//imageradius