Example #1
0
  /**
   * Creates the Euclidian Distance Map of a (binary) byte image.
   *
   * @param ip The input image, not modified; must be a ByteProcessor.
   * @param backgroundValue Pixels in the input with this value are interpreted as background. Note:
   *     for pixel value 255, write either -1 or (byte)255.
   * @param edgesAreBackground Whether out-of-image pixels are considered background
   * @return The EDM, containing the distances to the nearest background pixel. Returns null if the
   *     thread is interrupted.
   */
  public FloatProcessor makeFloatEDM(
      ImageProcessor ip, int backgroundValue, boolean edgesAreBackground) {
    int width = ip.getWidth();
    int height = ip.getHeight();
    FloatProcessor fp = new FloatProcessor(width, height);
    byte[] bPixels = (byte[]) ip.getPixels();
    float[] fPixels = (float[]) fp.getPixels();
    final int progressInterval = 100;
    int nProgressUpdates =
        height
            / progressInterval; // how often the progress bar is updated when passing once through y
    // range
    double progressAddendum = (nProgressUpdates > 0) ? 0.5 / nProgressUpdates : 0;

    for (int i = 0; i < width * height; i++)
      if (bPixels[i] != backgroundValue) fPixels[i] = Float.MAX_VALUE;

    int[][] pointBufs =
        new int[2][width]; // two buffers for two passes; low short contains x, high short y
    int yDist = Integer.MAX_VALUE; // this value is used only if edges are not background
    // pass 1 & 2: increasing y
    for (int x = 0; x < width; x++) {
      pointBufs[0][x] = NO_POINT;
      pointBufs[1][x] = NO_POINT;
    }
    for (int y = 0; y < height; y++) {
      if (edgesAreBackground) yDist = y + 1; // distance to nearest background point (along y)
      edmLine(bPixels, fPixels, pointBufs, width, y * width, y, backgroundValue, yDist);
      if (y % progressInterval == 0) {
        if (Thread.currentThread().isInterrupted()) return null;
        addProgress(progressAddendum);
      }
    }
    // pass 3 & 4: decreasing y
    for (int x = 0; x < width; x++) {
      pointBufs[0][x] = NO_POINT;
      pointBufs[1][x] = NO_POINT;
    }
    for (int y = height - 1; y >= 0; y--) {
      if (edgesAreBackground) yDist = height - y;
      edmLine(bPixels, fPixels, pointBufs, width, y * width, y, backgroundValue, yDist);
      if (y % progressInterval == 0) {
        if (Thread.currentThread().isInterrupted()) return null;
        addProgress(progressAddendum);
      }
    }

    fp.sqrt();
    return fp;
  } // public FloatProcessor makeFloatEDM