Beispiel #1
0
  public Channels() {
    super("Channels");
    if (instance != null) {
      instance.toFront();
      return;
    }
    WindowManager.addWindow(this);
    instance = this;
    GridBagLayout gridbag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();
    setLayout(gridbag);
    int y = 0;
    c.gridx = 0;
    c.gridy = y++;
    c.gridwidth = 1;
    c.fill = GridBagConstraints.BOTH;
    c.anchor = GridBagConstraints.CENTER;
    int margin = 32;
    if (IJ.isMacOSX()) margin = 20;
    c.insets = new Insets(10, margin, 10, margin);
    choice = new Choice();
    for (int i = 0; i < modes.length; i++) choice.addItem(modes[i]);
    choice.select(0);
    choice.addItemListener(this);
    add(choice, c);

    CompositeImage ci = getImage();
    int nCheckBoxes = ci != null ? ci.getNChannels() : 3;
    if (nCheckBoxes > CompositeImage.MAX_CHANNELS) nCheckBoxes = CompositeImage.MAX_CHANNELS;
    checkbox = new Checkbox[nCheckBoxes];
    for (int i = 0; i < nCheckBoxes; i++) {
      checkbox[i] = new Checkbox("Channel " + (i + 1), true);
      c.insets = new Insets(0, 25, i < nCheckBoxes - 1 ? 0 : 10, 5);
      c.gridy = y++;
      add(checkbox[i], c);
      checkbox[i].addItemListener(this);
    }

    c.insets = new Insets(0, 15, 10, 15);
    c.fill = GridBagConstraints.NONE;
    c.gridy = y++;
    moreButton = new Button(moreLabel);
    moreButton.addActionListener(this);
    add(moreButton, c);
    update();

    pm = new PopupMenu();
    for (int i = 0; i < menuItems.length; i++) addPopupItem(menuItems[i]);
    add(pm);

    addKeyListener(IJ.getInstance()); // ImageJ handles keyboard shortcuts
    setResizable(false);
    pack();
    if (location == null) {
      GUI.center(this);
      location = getLocation();
    } else setLocation(location);
    show();
  }
 public PlugInDialog(String title) {
   super(IJ.isMacOSX() ? IJ.getInstance() : IJ.isJava16() ? null : new Frame(), title);
   enableEvents(AWTEvent.WINDOW_EVENT_MASK);
   this.title = title;
   ImageJ ij = IJ.getInstance();
   if (IJ.isMacOSX() && ij != null) {
     ij.toFront(); // needed for keyboard shortcuts to work
     IJ.wait(250);
   }
   addWindowListener(this);
   addFocusListener(this);
   if (IJ.isLinux()) setBackground(ImageJ.backgroundColor);
   if (ij != null && !IJ.isMacOSX() && IJ.isJava16()) {
     Image img = ij.getIconImage();
     if (img != null)
       try {
         setIconImage(img);
       } catch (Exception e) {
       }
   }
 }
  public void run(String arg) {
    GenericDialog gd = new GenericDialog("Options");
    double sfreq = 20000.0;
    gd.addNumericField("Sampling Frequency?", sfreq, 1, 10, null);
    String[] psfchoice = {"3D Gaussian", "Gaus-Lorentz^2", "2D Gaussian"};
    gd.addChoice("PSF Type?", psfchoice, psfchoice[0]);
    String[] filetypechoice = {
      "Confocor 3 raw", "Short binary trajectory", "PlotWindow trajectory", "Ascii Text File"
    };
    gd.addChoice("File Type?", filetypechoice, filetypechoice[0]);
    boolean ch2green = true;
    gd.addCheckbox("Ch2 is green?", ch2green);
    gd.showDialog();
    if (gd.wasCanceled()) {
      return;
    }
    sfreq = gd.getNextNumber();
    int psfflag = gd.getNextChoiceIndex();
    int fileflag = gd.getNextChoiceIndex();
    ch2green = gd.getNextBoolean();
    int nfiles = 0;
    Object[] histograms = null;
    int xmax = 0;
    int ymax = 0;
    String[] names = null;
    if (fileflag < 2) {
      jdataio ioclass = new jdataio();
      File[] filearray = ioclass.openfiles(OpenDialog.getDefaultDirectory(), IJ.getInstance());
      if (filearray.length == 0) {
        return;
      }
      String dir = filearray[0].getAbsolutePath();
      int sepindex = dir.lastIndexOf(File.separator);
      String newdir = dir.substring(0, sepindex + 1);
      OpenDialog.setDefaultDirectory(newdir);
      nfiles = filearray.length / 2;
      if (nfiles > 25) {
        nfiles = 25;
      }
      histograms = new Object[nfiles];
      names = organize_c3_files(filearray);
      for (int i = 0; i < nfiles; i++) {
        try {
          int length1 = (int) (((double) filearray[2 * i].length() - 128.0) / 4.0);
          int length2 = (int) (((double) filearray[2 * i + 1].length() - 128.0) / 4.0);
          int length3 = (int) (((double) filearray[2 * i].length()) / 2.0);
          int length4 = (int) (((double) filearray[2 * i + 1].length()) / 2.0);
          InputStream instream = new BufferedInputStream(new FileInputStream(filearray[2 * i]));
          InputStream instream2 =
              new BufferedInputStream(new FileInputStream(filearray[2 * i + 1]));
          if (fileflag == 0) {
            int[] pmdata = new int[length1];
            int[] pmdata2 = new int[length2];
            if (!ioclass.skipstreambytes(instream, 128)) {
              showioerror();
              instream.close();
              return;
            }
            if (!ioclass.skipstreambytes(instream2, 128)) {
              showioerror();
              instream2.close();
              return;
            }
            if (!ioclass.readintelintfile(instream, length1, pmdata)) {
              showioerror();
              instream.close();
              return;
            }
            if (!ioclass.readintelintfile(instream2, length2, pmdata2)) {
              showioerror();
              instream2.close();
              return;
            }
            if (ch2green) {
              histograms[i] = (new pmodeconvert()).pm2pch(pmdata2, pmdata, sfreq, 20000000);
            } else {
              histograms[i] = (new pmodeconvert()).pm2pch(pmdata, pmdata2, sfreq, 20000000);
            }
          } else {
            float[] tmdata = new float[length3];
            float[] tmdata2 = new float[length4];
            if (!ioclass.readintelshortfile(instream, length3, tmdata)) {
              showioerror();
              instream.close();
              return;
            }
            if (!ioclass.readintelshortfile(instream2, length4, tmdata2)) {
              showioerror();
              instream2.close();
              return;
            }
            if (ch2green) {
              histograms[i] = (new pmodeconvert()).create_2Dhistogram(tmdata2, tmdata);
            } else {
              histograms[i] = (new pmodeconvert()).create_2Dhistogram(tmdata, tmdata2);
            }
          }
          if (((float[][]) histograms[i]).length > xmax) {
            xmax = ((float[][]) histograms[i]).length;
          }
          if (((float[][]) histograms[i])[0].length > ymax) {
            ymax = ((float[][]) histograms[i])[0].length;
          }
          instream.close();
          instream2.close();
        } catch (IOException e) {
          showioerror();
          return;
        }
      }
    } else {
      if (fileflag == 2) {
        ImageWindow iw = WindowManager.getCurrentWindow();
        float[][] trajectories = (float[][]) jutils.runPW4VoidMethod(iw, "getYValues");
        float[][] tempxvals = (float[][]) jutils.runPW4VoidMethod(iw, "getXValues");
        sfreq = 1.0 / ((double) tempxvals[0][1]);
        nfiles = trajectories.length / 2;
        if (nfiles > 25) {
          nfiles = 25;
        }
        names = new String[nfiles + 1];
        names[nfiles] = "avg";
        histograms = new Object[nfiles];
        for (int i = 0; i < nfiles; i++) {
          names[i] = "trajectory " + (i + 1);
          if (ch2green) {
            histograms[i] =
                (new pmodeconvert())
                    .create_2Dhistogram(trajectories[2 * i + 1], trajectories[2 * i]);
          } else {
            histograms[i] =
                (new pmodeconvert())
                    .create_2Dhistogram(trajectories[2 * i], trajectories[2 * i + 1]);
          }
          if (((float[][]) histograms[i]).length > xmax) {
            xmax = ((float[][]) histograms[i]).length;
          }
          if (((float[][]) histograms[i])[0].length > ymax) {
            ymax = ((float[][]) histograms[i])[0].length;
          }
        }
      } else {
        // here we read tab delimited lines from files
        jdataio ioclass = new jdataio();
        File[] filearray = ioclass.openfiles(OpenDialog.getDefaultDirectory(), IJ.getInstance());
        if (filearray.length == 0) {
          return;
        }
        String dir = filearray[0].getAbsolutePath();
        int sepindex = dir.lastIndexOf(File.separator);
        String newdir = dir.substring(0, sepindex + 1);
        OpenDialog.setDefaultDirectory(newdir);
        nfiles = filearray.length;
        if (nfiles > 25) {
          nfiles = 25;
        }
        histograms = new Object[nfiles];
        names = new String[nfiles + 1];
        names[nfiles] = "avg";
        for (int i = 0; i < nfiles; i++) {
          try {
            names[i] = filearray[i].getName();
            BufferedReader d = new BufferedReader(new FileReader(filearray[i]));
            String[] lines = new String[256];
            int counter = 0;
            do {
              lines[counter] = d.readLine();
              counter++;
            } while ((lines[counter - 1] != null && lines[counter - 1] != "") && counter < 256);
            int numcolumns = 0;
            for (int j = 0; j < counter - 1; j++) {
              int temp = getncolumns(lines[j]);
              if (temp > numcolumns) {
                numcolumns = temp;
              }
            }
            float[][] temphist2 = null;
            if (ch2green) {
              temphist2 = new float[numcolumns][counter - 1];
            } else {
              temphist2 = new float[counter - 1][numcolumns];
            }
            for (int k = 0; k < counter - 1; k++) {
              float[] temp = tab_delim2float(lines[k]);
              for (int j = 0; j < numcolumns; j++) {
                if (ch2green) {
                  temphist2[j][k] = temp[j];
                } else {
                  temphist2[k][j] = temp[j];
                }
              }
            }
            histograms[i] = temphist2;
            d.close();
          } catch (IOException e) {
            showioerror();
            return;
          }
        }
        for (int i = 0; i < nfiles; i++) {
          if (((float[][]) histograms[i]).length > xmax) {
            xmax = ((float[][]) histograms[i]).length;
          }
          if (((float[][]) histograms[i])[0].length > ymax) {
            ymax = ((float[][]) histograms[i])[0].length;
          }
        }
      }
    }
    // note that here x is green and y is red
    float[][][] pch = new float[nfiles][xmax][ymax];
    for (int i = 0; i < nfiles; i++) {
      for (int j = 0; j < ((float[][]) histograms[i]).length; j++) {
        for (int k = 0; k < ((float[][]) histograms[i])[j].length; k++) {
          pch[i][j][k] = ((float[][]) histograms[i])[j][k];
        }
      }
    }

    final PCH2DFitWindow cw = new PCH2DFitWindow();
    cw.init(names, pch, psfflag);

    final Frame f = new Frame("PCH 2D Analysis");
    f.setLocation(10, 10);
    f.addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            f.dispose();
          }
        });

    f.add(cw);
    f.pack();
    f.setResizable(false);
    Insets ins = f.getInsets();
    cw.totalSize.height = PCH2DFitWindow.H + ins.bottom + ins.top + 65;
    cw.totalSize.width = PCH2DFitWindow.WR + ins.left + ins.right;
    f.setSize(cw.totalSize);
    f.setVisible(true);
    cw.requestFocus();
  }
Beispiel #4
0
 public static void main(String args[]) {
   if (System.getProperty("java.version").substring(0, 3).compareTo("1.5") < 0) {
     javax.swing.JOptionPane.showMessageDialog(
         null, "ImageJ " + VERSION + " requires Java 1.5 or later.");
     System.exit(0);
   }
   boolean noGUI = false;
   int mode = STANDALONE;
   arguments = args;
   // System.setProperty("file.encoding", "UTF-8");
   int nArgs = args != null ? args.length : 0;
   boolean commandLine = false;
   for (int i = 0; i < nArgs; i++) {
     String arg = args[i];
     if (arg == null) continue;
     if (args[i].startsWith("-")) {
       if (args[i].startsWith("-batch")) noGUI = true;
       else if (args[i].startsWith("-debug")) IJ.setDebugMode(true);
       else if (args[i].startsWith("-ijpath") && i + 1 < nArgs) {
         if (IJ.debugMode) IJ.log("-ijpath: " + args[i + 1]);
         Prefs.setHomeDir(args[i + 1]);
         commandLine = true;
         args[i + 1] = null;
       } else if (args[i].startsWith("-port")) {
         int delta = (int) Tools.parseDouble(args[i].substring(5, args[i].length()), 0.0);
         commandLine = true;
         if (delta == 0) mode = EMBEDDED;
         else if (delta > 0 && DEFAULT_PORT + delta < 65536) port = DEFAULT_PORT + delta;
       }
     }
   }
   // If existing ImageJ instance, pass arguments to it and quit.
   boolean passArgs = mode == STANDALONE && !noGUI;
   if (IJ.isMacOSX() && !commandLine) passArgs = false;
   if (passArgs && isRunning(args)) return;
   ImageJ ij = IJ.getInstance();
   if (!noGUI && (ij == null || (ij != null && !ij.isShowing()))) {
     ij = new ImageJ(null, mode);
     ij.exitWhenQuitting = true;
   }
   int macros = 0;
   for (int i = 0; i < nArgs; i++) {
     String arg = args[i];
     if (arg == null) continue;
     if (arg.startsWith("-")) {
       if ((arg.startsWith("-macro") || arg.startsWith("-batch")) && i + 1 < nArgs) {
         String arg2 = i + 2 < nArgs ? args[i + 2] : null;
         Prefs.commandLineMacro = true;
         if (noGUI && args[i + 1].endsWith(".js")) Interpreter.batchMode = true;
         IJ.runMacroFile(args[i + 1], arg2);
         break;
       } else if (arg.startsWith("-eval") && i + 1 < nArgs) {
         String rtn = IJ.runMacro(args[i + 1]);
         if (rtn != null) System.out.print(rtn);
         args[i + 1] = null;
       } else if (arg.startsWith("-run") && i + 1 < nArgs) {
         IJ.run(args[i + 1]);
         args[i + 1] = null;
       }
     } else if (macros == 0 && (arg.endsWith(".ijm") || arg.endsWith(".txt"))) {
       IJ.runMacroFile(arg);
       macros++;
     } else if (arg.length() > 0 && arg.indexOf("ij.ImageJ") == -1) {
       File file = new File(arg);
       IJ.open(file.getAbsolutePath());
     }
   }
   if (IJ.debugMode && IJ.getInstance() == null) new JavaProperties().run("");
   if (noGUI) System.exit(0);
 }
 public void windowActivated(WindowEvent e) {
   ImageJ ij = IJ.getInstance();
   if (IJ.isMacOSX() && ij != null && !ij.isActive() && !(this instanceof ThresholdAdjuster))
     ij.toFront();
   WindowManager.setWindow(this);
 }
  /** 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
    }
  }
    public BandAdjuster() {

      super("Threshold Colour");
      if (instance != null) {
        instance.toFront();
        return;
      }
      imp = WindowManager.getCurrentImage();
      if (imp == null) {
        IJ.beep();
        IJ.showStatus("No image");
        return;
      }
      IJ.run("Select None");
      thread = new Thread(this, "BandAdjuster");
      WindowManager.addWindow(this);
      instance = this;
      IJ.register(PasteController.class);

      ij = IJ.getInstance();
      Font font = new Font("SansSerif", Font.PLAIN, 10);
      GridBagLayout gridbag = new GridBagLayout();
      GridBagConstraints c = new GridBagConstraints();
      setLayout(gridbag);

      int y = 0;
      c.gridx = 0;
      c.gridy = y;
      c.gridwidth = 1;
      c.weightx = 0;
      c.insets = new Insets(5, 0, 0, 0);
      labelh = new Label("Hue", Label.CENTER);
      add(labelh, c);

      c.gridx = 1;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = 0;
      c.insets = new Insets(7, 0, 0, 0);
      labelf = new Label("Filter type", Label.RIGHT);
      add(labelf, c);

      // plot
      c.gridx = 0;
      c.gridy = y;
      c.gridwidth = 1;
      c.fill = c.BOTH;
      c.anchor = c.CENTER;
      c.insets = new Insets(0, 5, 0, 0);
      add(plot, c);

      // checkboxes
      panelh = new Panel();
      filterTypeH = new CheckboxGroup();
      bandPassH = new Checkbox("Pass");
      bandPassH.setCheckboxGroup(filterTypeH);
      bandPassH.addItemListener(this);
      panelh.add(bandPassH);
      bandStopH = new Checkbox("Stop");
      bandStopH.setCheckboxGroup(filterTypeH);
      bandStopH.addItemListener(this);
      panelh.add(bandStopH);
      bandPassH.setState(true);
      c.gridx = 1;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(5, 0, 0, 0);
      add(panelh, c);

      // minHue slider
      minSlider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 90 : 100;
      c.fill = c.HORIZONTAL;
      c.insets = new Insets(5, 5, 0, 0);

      add(minSlider, c);
      minSlider.addAdjustmentListener(this);
      minSlider.setUnitIncrement(1);

      // minHue slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 10 : 0;
      c.insets = new Insets(5, 0, 0, 0);
      label1 = new Label("       ", Label.LEFT);
      label1.setFont(font);
      add(label1, c);

      // maxHue sliderHue
      maxSlider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y;
      c.gridwidth = 1;
      c.weightx = 100;
      c.insets = new Insets(5, 5, 0, 0);
      add(maxSlider, c);
      maxSlider.addAdjustmentListener(this);
      maxSlider.setUnitIncrement(1);

      // maxHue slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.gridy = y++;
      c.weightx = 0;
      c.insets = new Insets(5, 0, 0, 0);
      label2 = new Label("       ", Label.LEFT);
      label2.setFont(font);
      add(label2, c);

      // =====
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = 0;
      c.insets = new Insets(10, 0, 0, 0);
      labels = new Label("Saturation", Label.CENTER);
      add(labels, c);

      // plot
      c.gridx = 0;
      c.gridy = y;
      c.gridwidth = 1;
      c.fill = c.BOTH;
      c.anchor = c.CENTER;
      c.insets = new Insets(0, 5, 0, 0);
      add(splot, c);

      // checkboxes
      panels = new Panel();
      filterTypeS = new CheckboxGroup();
      bandPassS = new Checkbox("Pass");
      bandPassS.setCheckboxGroup(filterTypeS);
      bandPassS.addItemListener(this);
      panels.add(bandPassS);
      bandStopS = new Checkbox("Stop");
      bandStopS.setCheckboxGroup(filterTypeS);
      bandStopS.addItemListener(this);
      panels.add(bandStopS);
      bandPassS.setState(true);
      c.gridx = 1;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(5, 0, 0, 0);
      add(panels, c);

      // minSat slider
      minSlider2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 90 : 100;
      c.fill = c.HORIZONTAL;
      c.insets = new Insets(5, 5, 0, 0);
      add(minSlider2, c);
      minSlider2.addAdjustmentListener(this);
      minSlider2.setUnitIncrement(1);

      // minSat slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 10 : 0;
      c.insets = new Insets(5, 0, 0, 0);
      label3 = new Label("       ", Label.LEFT);
      label3.setFont(font);
      add(label3, c);

      // maxSat slider
      maxSlider2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = 100;
      c.insets = new Insets(5, 5, 0, 0);
      add(maxSlider2, c);
      maxSlider2.addAdjustmentListener(this);
      maxSlider2.setUnitIncrement(1);

      // maxSat slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.weightx = 0;
      c.insets = new Insets(5, 0, 0, 0);
      label4 = new Label("       ", Label.LEFT);
      label4.setFont(font);
      add(label4, c);

      // =====
      c.gridx = 0;
      c.gridwidth = 1;
      c.gridy = y++;
      c.weightx = 0;
      c.insets = new Insets(10, 0, 0, 0);
      labelb = new Label("Brightness", Label.CENTER);
      add(labelb, c);

      c.gridx = 0;
      c.gridwidth = 1;
      c.gridy = y;
      c.fill = c.BOTH;
      c.anchor = c.CENTER;
      c.insets = new Insets(0, 5, 0, 0);
      add(bplot, c);

      // checkboxes
      panelb = new Panel();
      filterTypeB = new CheckboxGroup();
      bandPassB = new Checkbox("Pass");
      bandPassB.setCheckboxGroup(filterTypeB);
      bandPassB.addItemListener(this);
      panelb.add(bandPassB);
      bandStopB = new Checkbox("Stop");
      bandStopB.setCheckboxGroup(filterTypeB);
      bandStopB.addItemListener(this);
      panelb.add(bandStopB);
      bandPassB.setState(true);
      c.gridx = 1;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(5, 0, 0, 0);
      add(panelb, c);

      // minBri slider
      minSlider3 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 90 : 100;
      c.fill = c.HORIZONTAL;
      c.insets = new Insets(5, 5, 0, 0);
      add(minSlider3, c);
      minSlider3.addAdjustmentListener(this);
      minSlider3.setUnitIncrement(1);

      // minBri slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.weightx = IJ.isMacintosh() ? 10 : 0;
      c.insets = new Insets(5, 0, 0, 0);
      label5 = new Label("       ", Label.LEFT);
      label5.setFont(font);
      add(label5, c);

      // maxBri slider
      maxSlider3 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 1;
      c.weightx = 100;
      c.insets = new Insets(5, 5, 0, 0);
      add(maxSlider3, c);
      maxSlider3.addAdjustmentListener(this);
      maxSlider3.setUnitIncrement(1);

      // maxBri slider label
      c.gridx = 1;
      c.gridwidth = 1;
      c.weightx = 0;
      c.insets = new Insets(5, 0, 0, 0);
      label6 = new Label("       ", Label.LEFT);
      label6.setFont(font);
      add(label6, c);

      // =====
      panelt = new Panel();
      threshold = new Checkbox("Threshold");
      threshold.addItemListener(this);
      panelt.add(threshold);

      invert = new Checkbox("Invert");
      invert.addItemListener(this);
      panelt.add(invert);

      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(0, 0, 0, 0);
      add(panelt, c);

      // buttons
      panel = new Panel();
      // panel.setLayout(new GridLayout(2, 2, 0, 0));
      originalB = new Button("Original");
      originalB.setEnabled(false);
      originalB.addActionListener(this);
      originalB.addKeyListener(ij);
      panel.add(originalB);

      filteredB = new Button("Filtered");
      filteredB.setEnabled(false);
      filteredB.addActionListener(this);
      filteredB.addKeyListener(ij);
      panel.add(filteredB);

      stackB = new Button("Stack");
      stackB.addActionListener(this);
      stackB.addKeyListener(ij);
      panel.add(stackB);

      helpB = new Button("Help");
      helpB.addActionListener(this);
      helpB.addKeyListener(ij);
      panel.add(helpB);

      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(0, 0, 0, 0);
      add(panel, c);

      panelMode = new Panel();

      sampleB = new Button("Sample");
      sampleB.addActionListener(this);
      sampleB.addKeyListener(ij);
      panelMode.add(sampleB);

      colourMode = new CheckboxGroup();
      hsb = new Checkbox("HSB");
      hsb.setCheckboxGroup(colourMode);
      hsb.addItemListener(this);
      panelMode.add(hsb);
      hsb.setState(true);
      rgb = new Checkbox("RGB");
      rgb.setCheckboxGroup(colourMode);
      rgb.addItemListener(this);
      panelMode.add(rgb);

      c.gridx = 0;
      c.gridy = y++;
      c.gridwidth = 2;
      c.insets = new Insets(0, 0, 0, 0);
      add(panelMode, c);

      addKeyListener(ij); // ImageJ handles keyboard shortcuts
      pack();
      GUI.center(this);
      setVisible(true);

      ip = setup(imp);
      if (ip == null) {
        imp.unlock();
        IJ.beep();
        IJ.showStatus("RGB image cannot be thresholded");
        return;
      }
      thread.start();
    }