/** * Execute plugin functionality: stack FFT with window function, max projection over all slices * (phase, Z angle), blank out central 1/8 circle (set to min value), display min-max. */ public ResultSet exec(ImagePlus... imps) { ImagePlus imp = imps[0]; Util_StackFFT2D stackFFT2D = new Util_StackFFT2D(); stackFFT2D.resultTypeChoice = Util_StackFFT2D.resultType[1]; ImagePlus impF = stackFFT2D.exec(imp); IJ.run(impF, "Z Project...", "projection=[Max Intensity]"); ImagePlus impProjF = ij.WindowManager.getCurrentImage(); maskCentralRegion(impProjF); if (impProjF.isComposite()) { // display grayscale, not colored composite CompositeImage ci = (CompositeImage) impProjF; ci.setMode(IJ.GRAYSCALE); impProjF.updateAndDraw(); } displayMinToMax(impProjF); impProjF.setTitle(I1l.makeTitle(imps[0], TLA)); String shortInfo = "Maximum intensity projection of log" + " (amplitude^2) 2D FFT stack, central region masked," + " rescaled (min-max) to improve contrast of the relevant" + " frequency range."; results.addImp(shortInfo, impProjF); results.addInfo( "How to interpret", "look for clean 1st & 2nd" + " order spots, similar across angles. Note that spot" + " intensity depends on image content."); return results; }
public void run(String arg) { int[] wList = WindowManager.getIDList(); if (wList == null) { IJ.error("No images are open."); return; } double thalf = 0.5; boolean keep; GenericDialog gd = new GenericDialog("Bleach correction"); gd.addNumericField("t½:", thalf, 1); gd.addCheckbox("Keep source stack:", true); gd.showDialog(); if (gd.wasCanceled()) return; long start = System.currentTimeMillis(); thalf = gd.getNextNumber(); keep = gd.getNextBoolean(); if (keep) IJ.run("Duplicate...", "title='Bleach corrected' duplicate"); ImagePlus imp1 = WindowManager.getCurrentImage(); int d1 = imp1.getStackSize(); double v1, v2; int width = imp1.getWidth(); int height = imp1.getHeight(); ImageProcessor ip1, ip2, ip3; int slices = imp1.getStackSize(); ImageStack stack1 = imp1.getStack(); ImageStack stack2 = imp1.getStack(); int currentSlice = imp1.getCurrentSlice(); for (int n = 1; n <= slices; n++) { ip1 = stack1.getProcessor(n); ip3 = stack1.getProcessor(1); ip2 = stack2.getProcessor(n); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { v1 = ip1.getPixelValue(x, y); v2 = ip3.getPixelValue(x, y); // =B8/(EXP(-C$7*A8)) v1 = (v1 / Math.exp(-n * thalf)); ip2.putPixelValue(x, y, v1); } } IJ.showProgress((double) n / slices); IJ.showStatus(n + "/" + slices); } // stack2.show(); imp1.updateAndDraw(); }
public void run() { while (!done) { synchronized (this) { try { wait(); } catch (InterruptedException e) { } reset(imp, ip); // GL apply(imp, ip); // GL imp.updateAndDraw(); // GL } } }
public void actionPerformed(ActionEvent e) { Button b = (Button) e.getSource(); if (b == null) return; boolean imageThere = checkImage(); if (imageThere) { if (b == originalB) { reset(imp, ip); filteredB.setEnabled(true); } else if (b == filteredB) { apply(imp, ip); } else if (b == sampleB) { reset(imp, ip); sample(); apply(imp, ip); } else if (b == stackB) { applyStack(); } else if (b == helpB) { IJ.showMessage( "Help", "Threshold Colour v1.0\n \n" + "Modification of Bob Dougherty's BandPass2 plugin by G.Landini to\n" + "threshold 24 bit RGB images based on Hue, Saturation and Brightness\n" + "or Red, Green and Blue components.\n \n" + "Pass: Band-pass filter (anything within range is displayed).\n \n" + "Stop: Band-reject filter (anything within range is NOT displayed).\n \n" + "Original: Shows the original image and updates the buffer when\n" + " switching to another image.\n \n" + "Filtered: Shows the filtered image.\n \n" + "Stack: Processes the rest of the slices in the stack (if any)\n" + " using the current settings.\n \n" + "Threshold: Shows the object/background in the foreground and\n" + " background colours selected in the ImageJ toolbar.\n \n" + "Invert: Swaps the fore/background colours.\n \n" + "Sample: (experimental) Sets the ranges of the filters based on the\n" + " pixel value componentd in a rectangular, user-defined, ROI.\n \n" + "HSB RGB: Selects HSB or RGB space and resets all the filters.\n \n" + "Note that the \'thresholded\' image is RGB, not 8 bit grey."); } updatePlot(); updateLabels(); imp.updateAndDraw(); } else { IJ.beep(); IJ.showStatus("No Image"); } notify(); }
/** * Execute the plugin functionality: duplicate and scale the given image. * * @return an Object[] array with the name and the scaled ImagePlus. Does NOT show the new, image; * just returns it. */ public Object[] exec( ImagePlus imp, String myMethod, int radius, double par1, double par2, boolean doIwhite) { // 0 - Check validity of parameters if (null == imp) return null; ImageProcessor ip = imp.getProcessor(); int xe = ip.getWidth(); int ye = ip.getHeight(); // int [] data = (ip.getHistogram()); IJ.showStatus("Thresholding..."); long startTime = System.currentTimeMillis(); // 1 Do it if (imp.getStackSize() == 1) { ip.snapshot(); Undo.setup(Undo.FILTER, imp); } // Apply the selected algorithm if (myMethod.equals("Bernsen")) { Bernsen(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Contrast")) { Contrast(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Mean")) { Mean(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Median")) { Median(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("MidGrey")) { MidGrey(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Niblack")) { Niblack(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Otsu")) { Otsu(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Phansalkar")) { Phansalkar(imp, radius, par1, par2, doIwhite); } else if (myMethod.equals("Sauvola")) { Sauvola(imp, radius, par1, par2, doIwhite); } // IJ.showProgress((double)(255-i)/255); imp.updateAndDraw(); imp.getProcessor().setThreshold(255, 255, ImageProcessor.NO_LUT_UPDATE); // 2 - Return the threshold and the image IJ.showStatus("\nDone " + (System.currentTimeMillis() - startTime) / 1000.0); return new Object[] {imp}; }
public void run(String arg) { int[] wList = WindowManager.getIDList(); if (wList==null) { IJ.error("No images are open."); return; } double kernel=3; double kernelsum = 0; double kernelvarsum =0; double kernalvar = 0; double sigmawidth = 2; int kernelindex, minpixnumber; String[] kernelsize = { "3�,"5�, "7�, "9�}; GenericDialog gd = new GenericDialog("Sigma Filter"); gd.addChoice("Kernel size", kernelsize, kernelsize[0]); gd.addNumericField("Sigma width",sigmawidth , 2); gd.addNumericField("Minimum number of pixels", 1, 0); gd.addCheckbox("Keep source:",true); gd.addCheckbox("Do all stack:",true); gd.addCheckbox("Modified Lee's FIlter:",true); gd.showDialog(); if (gd.wasCanceled()) return ; kernelindex = gd.getNextChoiceIndex(); sigmawidth = gd.getNextNumber(); minpixnumber = ((int)gd.getNextNumber()); boolean keep = gd.getNextBoolean(); boolean doallstack = gd.getNextBoolean(); boolean modified = gd.getNextBoolean(); if (kernelindex==0) kernel = 3; if (kernelindex==1) kernel = 5; if (kernelindex==2) kernel = 7; if (kernelindex==3) kernel = 9; long start = System.currentTimeMillis(); if (minpixnumber> (kernel*kernel)){ IJ.showMessage("Sigma filter", "There must be more pixels in the kernel than+\n" + "the minimum number to be included"); return; } double v, midintensity; int x, y, ix, iy; double sum = 0; double backupsum =0; int count = 0; int n = 0; if (keep) {IJ.run("Select All"); IJ.run("Duplicate...", "title='Sigma filtered' duplicate");} int radius = (int)(kernel-1)/2; ImagePlus imp = WindowManager.getCurrentImage(); ImageStack stack1 = imp.getStack(); int width = imp.getWidth(); int height = imp.getHeight(); int nslices = stack1.getSize(); int cslice = imp.getCurrentSlice(); double status = width*height*nslices; ImageProcessor ip = imp.getProcessor(); int sstart = 1; if (!doallstack) {sstart = cslice; nslices=sstart;status = status/nslices;}; for (int i=sstart; i<=nslices; i++) { imp.setSlice(i); for (x=radius;x<width+radius;x++) { for (y=radius;y<height+radius;y++) { midintensity = ip.getPixelValue(x,y); count = 0; sum = 0; kernelsum =0; kernalvar =0; kernelvarsum =0; backupsum = 0; //calculate mean of kernel value for (ix=0;ix<kernel;ix++) { for (iy=0;iy<kernel;iy++) { v = ip.getPixelValue(x+ix-radius,y+iy-radius); kernelsum = kernelsum+v; } } double sigmacalcmean = (kernelsum/(kernel*kernel)); //calculate variance of kernel for (ix=0;ix<kernel;ix++) { for (iy=0;iy<kernel;iy++) { v = ip.getPixelValue(x+ix-radius,y+iy-radius); kernalvar = (v-sigmacalcmean)*(v-sigmacalcmean); kernelvarsum = kernelvarsum + kernalvar; } } //double variance = kernelvarsum/kernel; double sigmacalcvar = kernelvarsum/((kernel*kernel)-1); //calcuate sigma range = sqrt(variance/(mean^2)) � sigmawidth double sigmarange = sigmawidth*(Math.sqrt((sigmacalcvar) /(sigmacalcmean*sigmacalcmean))); //calulate sigma top value and bottom value double sigmatop = midintensity*(1+sigmarange); double sigmabottom = midintensity*(1-sigmarange); //calculate mean of values that differ are in sigma range. for (ix=0;ix<kernel;ix++) { for (iy=0;iy<kernel;iy++) { v = ip.getPixelValue(x+ix-radius,y+iy-radius); if ((v>=sigmabottom)&&(v<=sigmatop)){ sum = sum+v; count = count+1; } backupsum = v+ backupsum; } } //if there are too few pixels in the kernal that are within sigma range, the //mean of the entire kernal is taken. My modification of Lee's filter is to exclude the central value //from the calculation of the mean as I assume it to be spuriously high or low if (!(count>(minpixnumber))) {sum = (backupsum-midintensity); count = (int)((kernel*kernel)-1); if (!modified) {sum = (backupsum); count = (int)(kernel*kernel);} } double val = (sum/count); ip.putPixelValue(x,y, val); n = n+1; double percentage = (((double)n/status)*100); IJ.showStatus(IJ.d2s(percentage,0) +"% done"); } // IJ.showProgress(i, status); }} imp.updateAndDraw(); IJ.showStatus(IJ.d2s((System.currentTimeMillis()-start)/1000.0, 2)+" seconds"); }
/** Ask for parameters and then execute. */ public void run(String arg) { // 1 - Obtain the currently active image: ImagePlus imp = IJ.getImage(); if (null == imp) { IJ.showMessage("There must be at least one image open"); return; } if (imp.getBitDepth() != 8) { IJ.showMessage("Error", "Only 8-bit images are supported"); return; } // 2 - Ask for parameters: GenericDialog gd = new GenericDialog("Auto Local Threshold"); String[] methods = { "Try all", "Bernsen", "Contrast", "Mean", "Median", "MidGrey", "Niblack", "Otsu", "Phansalkar", "Sauvola" }; gd.addMessage("Auto Local Threshold v1.5"); gd.addChoice("Method", methods, methods[0]); gd.addNumericField("Radius", 15, 0); gd.addMessage("Special paramters (if different from default)"); gd.addNumericField("Parameter_1", 0, 0); gd.addNumericField("Parameter_2", 0, 0); gd.addCheckbox("White objects on black background", true); if (imp.getStackSize() > 1) { gd.addCheckbox("Stack", false); } gd.addMessage("Thresholded result is always shown in white [255]."); gd.showDialog(); if (gd.wasCanceled()) return; // 3 - Retrieve parameters from the dialog String myMethod = gd.getNextChoice(); int radius = (int) gd.getNextNumber(); double par1 = (double) gd.getNextNumber(); double par2 = (double) gd.getNextNumber(); boolean doIwhite = gd.getNextBoolean(); boolean doIstack = false; int stackSize = imp.getStackSize(); if (stackSize > 1) doIstack = gd.getNextBoolean(); // 4 - Execute! // long start = System.currentTimeMillis(); if (myMethod.equals("Try all")) { ImageProcessor ip = imp.getProcessor(); int xe = ip.getWidth(); int ye = ip.getHeight(); int ml = methods.length; ImagePlus imp2, imp3; ImageStack tstack = null, stackNew; if (stackSize > 1 && doIstack) { boolean doItAnyway = true; if (stackSize > 25) { YesNoCancelDialog d = new YesNoCancelDialog( IJ.getInstance(), "Auto Local Threshold", "You might run out of memory.\n \nDisplay " + stackSize + " slices?\n \n \'No\' will process without display and\noutput results to the log window."); if (!d.yesPressed()) { // doIlog=true; //will show in the log window doItAnyway = false; } if (d.cancelPressed()) return; } for (int j = 1; j <= stackSize; j++) { imp.setSlice(j); ip = imp.getProcessor(); tstack = new ImageStack(xe, ye); for (int k = 1; k < ml; k++) tstack.addSlice(methods[k], ip.duplicate()); imp2 = new ImagePlus("Auto Threshold", tstack); imp2.updateAndDraw(); for (int k = 1; k < ml; k++) { imp2.setSlice(k); Object[] result = exec(imp2, methods[k], radius, par1, par2, doIwhite); } // if (doItAnyway){ CanvasResizer cr = new CanvasResizer(); stackNew = cr.expandStack(tstack, (xe + 2), (ye + 18), 1, 1); imp3 = new ImagePlus("Auto Threshold", stackNew); imp3.updateAndDraw(); MontageMaker mm = new MontageMaker(); mm.makeMontage(imp3, 3, 3, 1.0, 1, (ml - 1), 1, 0, true); // 3 columns and 3 rows } imp.setSlice(1); // if (doItAnyway) IJ.run("Images to Stack", "method=[Copy (center)] title=Montage"); return; } else { // single image try all tstack = new ImageStack(xe, ye); for (int k = 1; k < ml; k++) tstack.addSlice(methods[k], ip.duplicate()); imp2 = new ImagePlus("Auto Threshold", tstack); imp2.updateAndDraw(); for (int k = 1; k < ml; k++) { imp2.setSlice(k); // IJ.log("analyzing slice with "+methods[k]); Object[] result = exec(imp2, methods[k], radius, par1, par2, doIwhite); } // imp2.setSlice(1); CanvasResizer cr = new CanvasResizer(); stackNew = cr.expandStack(tstack, (xe + 2), (ye + 18), 1, 1); imp3 = new ImagePlus("Auto Threshold", stackNew); imp3.updateAndDraw(); MontageMaker mm = new MontageMaker(); mm.makeMontage(imp3, 3, 3, 1.0, 1, (ml - 1), 1, 0, true); return; } } else { // selected a method if (stackSize > 1 && doIstack) { // whole stack // if (doIstackHistogram) {// one global histogram // Object[] result = exec(imp, myMethod, noWhite, noBlack, doIwhite, doIset, doIlog, // doIstackHistogram ); // } // else{ // slice by slice for (int k = 1; k <= stackSize; k++) { imp.setSlice(k); Object[] result = exec(imp, myMethod, radius, par1, par2, doIwhite); } // } imp.setSlice(1); } else { // just one slice Object[] result = exec(imp, myMethod, radius, par1, par2, doIwhite); } // 5 - If all went well, show the image: // not needed here as the source image is binarised } }
ImageProcessor setup(ImagePlus imp) { ImageProcessor ip; int type = imp.getType(); if (type != ImagePlus.COLOR_RGB) return null; ip = imp.getProcessor(); int id = imp.getID(); int slice = imp.getCurrentSlice(); if ((id != previousImageID) | (slice != previousSlice) | (flag)) { flag = false; // if true, flags a change from HSB to RGB or viceversa numSlices = imp.getStackSize(); stack = imp.getStack(); width = stack.getWidth(); height = stack.getHeight(); numPixels = width * height; hSource = new byte[numPixels]; sSource = new byte[numPixels]; bSource = new byte[numPixels]; // restore = (int[])ip.getPixelsCopy(); //This runs into trouble sometimes, so do it the // long way: int[] temp = (int[]) ip.getPixels(); restore = new int[numPixels]; for (int i = 0; i < numPixels; i++) restore[i] = temp[i]; fillMask = new int[numPixels]; // Get hsb or rgb from image. ColorProcessor cp = (ColorProcessor) ip; IJ.showStatus("Gathering data"); if (isRGB) cp.getRGB(hSource, sSource, bSource); else cp.getHSB(hSource, sSource, bSource); IJ.showStatus("done"); // Create a spectrum ColorModel for the Hue histogram plot. Color c; byte[] reds = new byte[256]; byte[] greens = new byte[256]; byte[] blues = new byte[256]; for (int i = 0; i < 256; i++) { c = Color.getHSBColor(i / 255f, 1f, 1f); reds[i] = (byte) c.getRed(); greens[i] = (byte) c.getGreen(); blues[i] = (byte) c.getBlue(); } ColorModel cm = new IndexColorModel(8, 256, reds, greens, blues); // Make an image with just the hue from the RGB image and the spectrum LUT. // This is just for a hue histogram for the plot. Do not show it. // ByteProcessor bpHue = new ByteProcessor(width,height,h,cm); ByteProcessor bpHue = new ByteProcessor(width, height, hSource, cm); ImagePlus impHue = new ImagePlus("Hue", bpHue); // impHue.show(); ByteProcessor bpSat = new ByteProcessor(width, height, sSource, cm); ImagePlus impSat = new ImagePlus("Sat", bpSat); // impSat.show(); ByteProcessor bpBri = new ByteProcessor(width, height, bSource, cm); ImagePlus impBri = new ImagePlus("Bri", bpBri); // impBri.show(); plot.setHistogram(impHue, 0); splot.setHistogram(impSat, 1); bplot.setHistogram(impBri, 2); updateLabels(); updatePlot(); updateScrollBars(); imp.updateAndDraw(); } previousImageID = id; previousSlice = slice; return ip; }