Package ij.plugin

Source Code of ij.plugin.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;
import ij.macro.Interpreter;

/** 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;
  }
 
}
TOP

Related Classes of ij.plugin.ImageCalculator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.