|
Thresholder |
|
package ij.plugin; import ij.*; import ij.gui.*; import ij.process.*; import ij.measure.*; import ij.plugin.frame.Recorder; import ij.plugin.filter.PlugInFilter; import java.awt.*; /** This plugin implements the Proxess/Binary/Threshold command. */ public class Thresholder implements PlugIn, Measurements { private int slice; private double minThreshold; private double maxThreshold; boolean autoThreshold; boolean skipDialog; ImageStack stack1; static boolean fill1 = true; static boolean fill2 = true; static boolean useBW = true; public void run(String arg) { skipDialog = arg.equals("skip"); ImagePlus imp = WindowManager.getCurrentImage(); if (imp==null) {IJ.noImage(); return;} if (imp.getStackSize()==1) { Undo.setup(Undo.COMPOUND_FILTER, imp); applyThreshold(imp); Undo.setup(Undo.COMPOUND_FILTER_DONE, imp); } else { Undo.reset(); applyThreshold(imp); } } void applyThreshold(ImagePlus imp) { if (!imp.lock()) return; imp.killRoi(); ImageProcessor ip = imp.getProcessor(); double saveMinThreshold = ip.getMinThreshold(); double saveMaxThreshold = ip.getMaxThreshold(); double saveMin = ip.getMin(); double saveMax = ip.getMax(); if (ip instanceof ByteProcessor) {saveMin =0; saveMax = 255;} autoThreshold = saveMinThreshold==ImageProcessor.NO_THRESHOLD; boolean useBlackAndWhite = true; if (skipDialog) fill1 = fill2 = useBlackAndWhite = true; else if (!autoThreshold) { GenericDialog gd = new GenericDialog("Apply Lut"); gd.addCheckbox("Thresholded pixels to foreground color", fill1); gd.addCheckbox("Remaining pixels to background color", fill2); gd.addMessage(""); gd.addCheckbox("Black foreground, white background", useBW); gd.showDialog(); if (gd.wasCanceled()) {imp.unlock(); return;} fill1 = gd.getNextBoolean(); fill2 = gd.getNextBoolean(); useBW = useBlackAndWhite = gd.getNextBoolean(); } else fill1 = fill2 = true; if (!(imp.getType()==ImagePlus.GRAY8)) convertToByte(imp); ip = imp.getProcessor(); if (autoThreshold) autoThreshold(imp); else { if (Recorder.record) Recorder.record("setThreshold", (int)saveMinThreshold, (int)saveMaxThreshold); minThreshold = ((saveMinThreshold-saveMin)/(saveMax-saveMin))*255.0; maxThreshold = ((saveMaxThreshold-saveMin)/(saveMax-saveMin))*255.0; } int fcolor, bcolor; ip.resetThreshold(); int savePixel = ip.getPixel(0,0); if (useBlackAndWhite) ip.setColor(Color.black); else ip.setColor(Toolbar.getForegroundColor()); ip.drawPixel(0,0); fcolor = ip.getPixel(0,0); if (useBlackAndWhite) ip.setColor(Color.white); else ip.setColor(Toolbar.getBackgroundColor()); ip.drawPixel(0,0); bcolor = ip.getPixel(0,0); ip.setColor(Toolbar.getForegroundColor()); ip.putPixel(0,0,savePixel); int[] lut = new int[256]; for (int i=0; i<256; i++) { if (i>=minThreshold && i<=maxThreshold) lut[i] = fill1?fcolor:(byte)i; else { lut[i] = fill2?bcolor:(byte)i; } } int result = IJ.setupDialog(imp, 0); if (result==PlugInFilter.DONE) { if (stack1!=null) imp.setStack(null, stack1); imp.unlock(); return; } if (result==PlugInFilter.DOES_STACKS) new StackProcessor(imp.getStack(), ip).applyTable(lut); else ip.applyTable(lut); if (fill1=true && fill2==true && ((fcolor==0&&bcolor==255)||(fcolor==255&&bcolor==0))) imp.getProcessor().setThreshold(fcolor, fcolor, ImageProcessor.NO_LUT_UPDATE); imp.updateAndDraw(); imp.unlock(); } void convertToByte(ImagePlus imp) { ImageProcessor ip = imp.getProcessor(); double min = ip.getMin(); double max = ip.getMax(); int currentSlice = imp.getCurrentSlice(); stack1 = imp.getStack(); ImageStack stack2 = imp.createEmptyStack(); int nSlices = imp.getStackSize(); String label; for(int i=1; i<=nSlices; i++) { label = stack1.getSliceLabel(i); ip = stack1.getProcessor(i); ip.setMinAndMax(min, max); stack2.addSlice(label, ip.convertToByte(true)); } imp.setStack(null, stack2); imp.setSlice(currentSlice); imp.setCalibration(imp.getCalibration()); //update calibration } void autoThreshold(ImagePlus imp) { ImageStatistics stats = imp.getStatistics(MIN_MAX+MODE); ImageProcessor ip = imp.getProcessor(); int threshold = ((ByteProcessor)ip).getAutoThreshold(); if ((stats.max-stats.mode)<(stats.mode-stats.min)) { minThreshold = stats.min; maxThreshold = threshold; } else { minThreshold = threshold; maxThreshold = stats.max; } } }
|
Thresholder |
|