package yi.iu.processor.morph;

import java.awt.Dimension;
import yi.iu.processor.filter.GaussianSmooth;

/**
 * GaussianDilation is to dilate a binary region using Gussian smoothing.
 */
public class GaussianDilation {

  /**
   * Default value for Gaussian theta
   */
  public final static double DEFAULT_THETHA = 0.01;

  /**
   * Default value for filtering threshold
   */
  public final static double DEFAULT_FILTER_THRESHOLD = 0.2;

  /**
   * Dilate binary image.  the significant pixels (value = 1 in binary image)
   * are first smoothed by Gaussian and then pixels with their values passed the
   * threshold will be considered as significant pixels too.  More pixels are
   * gotten together, more surrounding pixels will be selected.  (for example,
   * 10 pixels together generate more energy around them than 1 pixel alone).
   * @param binary binary image. [0,1]
   * @param width image width
   * @param height image height
   * @param gaussian_theta theta used in Gaussian smooth step.  It is not a
   *        absolute value.
   *        the used theta = gaussian_theta * Math.sqrt(width*height).
   *        Eg. width = 600, height = 400, theta = around 5 if
   *        gaussian_theta = 0.01
   * @param filter_threshold threshold used in the filter step.  0.2 is a good
   *        choice, see detail comparison in cv010
   * @return dilated binary image [0,1]
   */
  public static int[] dilation(int[] binary, int width, int height, double gaussian_theta, double filter_threshold) {

    // convert the binary int array to [0,255] since GaussianSmooth only use
    // integer and if the data are only within [0,1], the result will be all 0
    for (int i=0;i<binary.length;i++) if (binary[i]!=0) binary[i]=255;

    // new Gaussian smooth processor
    GaussianSmooth gau = new GaussianSmooth(gaussian_theta * Math.sqrt(width*height));
    binary = gau.getProcessed(binary, new Dimension(width,height));

    int binary_threshold = (int)(255 * filter_threshold);
    int[] dilated = new int[binary.length];
    for (int i=0;i<binary.length;i++) {
      dilated[i] = (binary[i]>binary_threshold)?1:0;
    }

    return dilated;
  }

  public static int[] dilation(int[] binary, int width, int height) {
    return dilation(binary, width, height, DEFAULT_THETHA, DEFAULT_FILTER_THRESHOLD);
  }
}