/**
   * Computes the geodesic distance function for each pixel in mask, using the given mask. Mask and
   * marker should be ImageProcessor the same size and containing float values. The function returns
   * a new Float processor the same size as the input, with values greater or equal to zero.
   */
  @Override
  public FloatProcessor geodesicDistanceMap(ImageProcessor marker, ImageProcessor mask) {
    // size of image
    width = mask.getWidth();
    height = mask.getHeight();

    // update mask
    this.maskProc = mask;

    // create new empty image, and fill it with black
    FloatProcessor result = new FloatProcessor(width, height);
    result.setValue(0);
    result.fill();

    // initialize empty image with either 0 (foreground) or Inf (background)
    array = result.getFloatArray();
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        int val = marker.get(i, j) & 0x00ff;
        array[i][j] = val == 0 ? backgroundValue : 0;
      }
    }

    int iter = 0;
    do {
      modif = false;

      // forward iteration
      IJ.showStatus("Forward iteration " + iter);
      forwardIteration();

      // backward iteration
      IJ.showStatus("Backward iteration " + iter);
      backwardIteration();

      // Iterate while pixels have been modified
      iter++;
    } while (modif);

    // Normalize values by the first weight
    if (this.normalizeMap) {
      for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
          array[i][j] /= this.weights[0];
        }
      }
    }

    // Compute max value within the mask
    float maxVal = 0;
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        if (maskProc.getPixel(i, j) != 0) maxVal = Math.max(maxVal, array[i][j]);
      }
    }

    // update and return resulting Image processor
    result.setFloatArray(array);
    result.setMinAndMax(0, maxVal);
    // Forces the display to non-inverted LUT
    if (result.isInvertedLut()) result.invertLut();
    return result;
  }
Esempio n. 2
0
  /** Segment image based on the current foreground and background ROIs */
  private synchronized void segment() {
    if (controlPanel.bgJRadioButton.isSelected()) backgroundRoi = imp.getRoi();
    else foregroundRoi = imp.getRoi();

    if (foregroundRoi == null) {
      IJ.error("Siox Segmentation", "ERROR: no foreground selected!");
      return;
    }

    // Create confidence matrix and initialize to unknown region of confidence
    confMatrix = new FloatProcessor(imp.getWidth(), imp.getHeight());
    final float[] imgData = (float[]) confMatrix.getPixels();
    confMatrix.add(SioxSegmentator.UNKNOWN_REGION_CONFIDENCE);

    // Set foreground ROI
    if (foregroundRoi != null) {
      confMatrix.setValue(SioxSegmentator.CERTAIN_FOREGROUND_CONFIDENCE);
      confMatrix.fill(foregroundRoi);
    }

    // Set background ROI
    if (backgroundRoi != null) {
      confMatrix.setValue(SioxSegmentator.CERTAIN_BACKGROUND_CONFIDENCE);
      confMatrix.fill(backgroundRoi);
    } else {
      // Workaround: select border pixels which are not foreground as background if no background
      // was specified.
      int w = imp.getWidth(), h = imp.getHeight();
      for (int i = 0; i < w; i++) {
        if (imgData[i] < 0.8f) imgData[i] = 0;
        if (imgData[i + w * (h - 1)] < 0.8f) imgData[i + w * (h - 1)] = 0;
      }
      for (int i = 0; i < h; i++) {
        if (imgData[w * i] < 0.8f) imgData[w * i] = 0;
        if (imgData[w - 1 + w * i] < 0.8f) imgData[w - 1 + w * i] = 0;
      }
    }

    // Call SIOX segmentation method
    int[] pixels = (int[]) ip.getPixels();

    final int smoothes = controlPanel.smoothness.getValue();

    siox = new SioxSegmentator(imp.getWidth(), imp.getHeight(), null);
    boolean success =
        siox.segmentate(pixels, imgData, smoothes, controlPanel.multipart.isSelected() ? 4 : 0);

    if (!success) IJ.error("Siox Segmentation", "The segmentation failed!");

    updateResult();

    // Set status flag to segmented
    controlPanel.status = ControlJPanel.SEGMENTATED_STATUS;
    controlPanel.updateComponentEnabling();

    roiOverlay.setComposite(transparency100);

    // Set up next panel components
    controlPanel.subJRadioButton.setSelected(true);
    controlPanel.addJRadioButton.setSelected(false);
    lastButton = controlPanel.subJRadioButton;
  }