|
ImageCalculator |
|
package ij.plugin; import ij.*; import ij.gui.*; import ij.process.*; import ij.plugin.filter.*; import ij.measure.Calibration; import ij.plugin.frame.Recorder; /** This plugin implements the Process/Image Calculator command. */ public class ImageCalculator implements PlugIn { private static String[] operators = {"Add","Subtract","Multiply","Divide", "AND", "OR", "XOR", "Min", "Max", "Average", "Difference", "Copy"}; private static String[] lcOperators = {"add","sub","mul","div", "and", "or", "xor", "min", "max", "ave", "diff", "copy"}; private static int operator; private static String title1 = ""; private static String title2 = ""; private static boolean createWindow = true; private static boolean floatResult; private boolean processStack; public void run(String arg) { int[] wList = WindowManager.getIDList(); if (wList==null) { IJ.noImage(); return; } IJ.register(ImageCalculator.class); String[] titles = new String[wList.length]; for (int i=0; i<wList.length; i++) { ImagePlus imp = WindowManager.getImage(wList[i]); if (imp!=null) titles[i] = imp.getTitle(); else titles[i] = ""; } GenericDialog gd = new GenericDialog("Image Calculator", IJ.getInstance()); String defaultItem; if (title1.equals("")) defaultItem = titles[0]; else defaultItem = title1; gd.addChoice("Image1:", titles, defaultItem); gd.addChoice("Operation:", operators, operators[operator]); if (title2.equals("")) defaultItem = titles[0]; else defaultItem = title2; gd.addChoice("Image2:", titles, defaultItem); //gd.addStringField("Result:", "Result", 10); gd.addCheckbox("Create New Window", createWindow); gd.addCheckbox("32-bit Result", floatResult); gd.showDialog(); if (gd.wasCanceled()) return; int index1 = gd.getNextChoiceIndex(); title1 = titles[index1]; operator = gd.getNextChoiceIndex(); int index2 = gd.getNextChoiceIndex(); //String resultTitle = gd.getNextString(); createWindow = gd.getNextBoolean(); floatResult = gd.getNextBoolean(); title2 = titles[index2]; ImagePlus img1 = WindowManager.getImage(wList[index1]); ImagePlus img2 = WindowManager.getImage(wList[index2]); calculate(img1, img2, false); } public void calculate(String params, ImagePlus img1, ImagePlus img2) { if (img1==null || img2==null || params==null) return; params = params.toLowerCase(); int op= -1; if (params.indexOf("xor")!=-1) op = 6; if (op==-1) { for (int i=0; i<lcOperators.length; i++) { if (params.indexOf(lcOperators[i])!=-1) { op = i; break; } } } if (op==-1) {IJ.error("Image Calclulator", "No valid operator"); return;} operator = op; createWindow = params.indexOf("create")!=-1; floatResult= params.indexOf("32")!=-1 || params.indexOf("float")!=-1; processStack = params.indexOf("stack")!=-1; calculate(img1, img2, true); } void calculate(ImagePlus img1, ImagePlus img2, boolean apiCall) { if (img1.getCalibration().isSigned16Bit() || img2.getCalibration().isSigned16Bit()) floatResult = true; if (floatResult) createWindow = true; int size1 = img1.getStackSize(); int size2 = img2.getStackSize(); if (apiCall) { if (processStack && (size1>1||size2>1)) doStackOperation(img1, img2); else doOperation(img1, img2); return; } boolean stackOp = false; if (size1>1) { int result = IJ.setupDialog(img1, 0); if (result==PlugInFilter.DONE) return; if (result==PlugInFilter.DOES_STACKS) { doStackOperation(img1, img2); stackOp = true; } else doOperation(img1, img2); } else doOperation(img1, img2); if (Recorder.record) { String params = operators[operator]; if (createWindow) params += " create"; if (floatResult) params += " 32-bit"; if (stackOp) params += " stack"; Recorder.record("imageCalculator", params, img1.getTitle(), img2.getTitle()); } } /** img1 = img2 op img2 (e.g. img1 = img2/img1) */ void doStackOperation(ImagePlus img1, ImagePlus img2) { int size1 = img1.getStackSize(); int size2 = img2.getStackSize(); if (size1>1 && size2>1 && size1!=size2) { IJ.error("Image Calculator", "'Image1' and 'image2' must be stacks with the same\nnumber of slices, or 'image2' must be a single image."); return; } if (createWindow) { img1 = duplicateStack(img1); if (img1==null) { IJ.error("Calculator", "Out of memory"); return; } img1.show(); } int mode = getBlitterMode(); ImageWindow win = img1.getWindow(); if (win!=null) WindowManager.setCurrentWindow(win); Undo.reset(); ImageStack stack1 = img1.getStack(); StackProcessor sp = new StackProcessor(stack1, img1.getProcessor()); Calibration cal2 = img2.getCalibration(); img2.getProcessor().setCalibrationTable(cal2.getCTable()); try { if (size2==1) sp.copyBits(img2.getProcessor(), 0, 0, mode); else sp.copyBits(img2.getStack(), 0, 0, mode); } catch (IllegalArgumentException e) { IJ.error("\""+img1.getTitle()+"\": "+e.getMessage()); return; } img1.setStack(null, stack1); if (img1.getType()!=ImagePlus.GRAY8) { img1.getProcessor().resetMinAndMax(); } img1.updateAndDraw(); } void doOperation(ImagePlus img1, ImagePlus img2) { int mode = getBlitterMode(); ImageProcessor ip1 = img1.getProcessor(); ImageProcessor ip2 = img2.getProcessor(); Calibration cal1 = img1.getCalibration(); Calibration cal2 = img2.getCalibration(); if (createWindow) ip1 = createNewImage(ip1, ip2, cal1); else { ImageWindow win = img1.getWindow(); if (win!=null) WindowManager.setCurrentWindow(win); ip1.snapshot(); Undo.setup(Undo.FILTER, img1); } if (floatResult) { ip2.setCalibrationTable(cal2.getCTable()); ip2 = ip2.convertToFloat(); } try { ip1.copyBits(ip2, 0, 0, mode); } catch (IllegalArgumentException e) { IJ.error("\""+img1.getTitle()+"\": "+e.getMessage()); return; } if (!(ip1 instanceof ByteProcessor)) ip1.resetMinAndMax(); if (createWindow) { ImagePlus img3 = new ImagePlus("Result of "+img1.getShortTitle(), ip1); img3.setCalibration(cal1); img3.show(); } else img1.updateAndDraw(); } ImageProcessor createNewImage(ImageProcessor ip1, ImageProcessor ip2, Calibration cal) { int width = Math.min(ip1.getWidth(), ip2.getWidth()); int height = Math.min(ip1.getHeight(), ip2.getHeight()); ImageProcessor ip3 = ip1.createProcessor(width, height); if (floatResult) { ip1.setCalibrationTable(cal.getCTable()); ip1 = ip1.convertToFloat(); ip3 = ip3.convertToFloat(); } ip3.insert(ip1, 0, 0); return ip3; } private int getBlitterMode() { int mode=0; switch (operator) { case 0: mode = Blitter.ADD; break; case 1: mode = Blitter.SUBTRACT; break; case 2: mode = Blitter.MULTIPLY; break; case 3: mode = Blitter.DIVIDE; break; case 4: mode = Blitter.AND; break; case 5: mode = Blitter.OR; break; case 6: mode = Blitter.XOR; break; case 7: mode = Blitter.MIN; break; case 8: mode = Blitter.MAX; break; case 9: mode = Blitter.AVERAGE; break; case 10: mode = Blitter.DIFFERENCE; break; case 11: mode = Blitter.COPY; break; } return mode; } ImagePlus duplicateStack(ImagePlus img1) { Calibration cal = img1.getCalibration(); ImageStack stack1 = img1.getStack(); int width = stack1.getWidth(); int height = stack1.getHeight(); int n = stack1.getSize(); ImageStack stack2 = img1.createEmptyStack(); try { for (int i=1; i<=n; i++) { ImageProcessor ip1 = stack1.getProcessor(i); ip1.resetRoi(); ImageProcessor ip2 = ip1.crop(); if (floatResult) { ip2.setCalibrationTable(cal.getCTable()); ip2 = ip2.convertToFloat(); } stack2.addSlice(stack1.getSliceLabel(i), ip2); } } catch(OutOfMemoryError e) { stack2.trim(); stack2 = null; return null; } ImagePlus img3 = new ImagePlus("Result of "+img1.getShortTitle(), stack2); img3.setCalibration(cal); if (img3.getStackSize()==n) { int[] dim = img1.getDimensions(); img3.setDimensions(dim[2], dim[3], dim[4]); } return img3; } }
|
ImageCalculator |
|