@Override
  public BufferedImage processImage(BufferedImage image) {

    originalImage = image;

    width = originalImage.getWidth();
    height = originalImage.getHeight();

    filteredImage = new BufferedImage(width, height, originalImage.getType());

    kernel = createKernel();

    int white = 255;
    int black = 0;

    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        int color = new Color(originalImage.getRGB(i, j)).getRed();
        if (color == black) {
          convolve(i, j);
        } else {
          int alpha = new Color(originalImage.getRGB(i, j)).getAlpha();
          int rgb = ImageUtilities.colorToRGB(alpha, white, white, white);
          filteredImage.setRGB(i, j, rgb);
        }
      }
    }
    return filteredImage;
  }
 private void convolve(int i, int j) {
   for (int x = i - 2; x <= i + 2; x++) {
     for (int y = j - 2; y <= j + 2; y++) {
       if (x >= 0 && y >= 0 && x < width && y < height) {
         int black = 0;
         int alpha = new Color(originalImage.getRGB(x, y)).getAlpha();
         int rgb = ImageUtilities.colorToRGB(alpha, black, black, black);
         filteredImage.setRGB(x, y, rgb);
       }
     }
   }
 }
  @Override
  public BufferedImage processImage(BufferedImage image) {

    originalImage = image;

    int width = originalImage.getWidth();
    int height = originalImage.getHeight();

    filteredImage = new BufferedImage(width, height, originalImage.getType());

    int alpha;
    double gray;

    double[][] G = new double[width][height]; // Integral sum G

    gray = new Color(originalImage.getRGB(0, 0)).getRed();
    G[0][0] = gray / 255;

    for (int i = 1; i < width; i++) {
      gray = new Color(originalImage.getRGB(i, 0)).getRed();
      G[i][0] = G[i - 1][0] + gray / 255;
    }
    for (int j = 1; j < height; j++) {
      gray = new Color(originalImage.getRGB(0, j)).getRed();
      G[0][j] = G[0][j - 1] + gray / 255;
    }
    for (int i = 1; i < width; i++) {
      for (int j = 1; j < height; j++) {
        gray = new Color(originalImage.getRGB(i, j)).getRed();
        G[i][j] = gray / 255 + G[i][j - 1] + G[i - 1][j] - G[i - 1][j - 1];
      }
    }

    int d = windowSize / 2;

    int A = 0;
    int B = 0;
    int C = 0;
    int D = 0;

    double s;
    double m;
    double delta;
    double treshold;

    int newColor;

    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {

        if (i + d - 1 >= width) {
          A = width - 1;
        } else {
          A = i + d - 1;
        }

        if (j + d - 1 >= height) {
          B = height - 1;
        } else {
          B = j + d - 1;
        }

        if (i - d < 0) {
          C = 0;
        } else {
          C = i - d;
        }

        if (j - d < 0) {
          D = 0;
        } else {
          D = j - d;
        }

        s = (G[A][B] + G[C][D]) - (G[C][B] + G[A][D]);
        m = s / (windowSize * windowSize);

        gray = new Color(originalImage.getRGB(i, j)).getRed();

        delta = gray / 255 - m;

        treshold = m * (1 + k * (delta / (1.0 - delta) - 1));

        if (gray / 255 > treshold) {
          newColor = 255;
        } else {
          newColor = 0;
        }

        alpha = new Color(originalImage.getRGB(i, j)).getAlpha();
        newColor = ImageUtilities.colorToRGB(alpha, newColor, newColor, newColor);

        filteredImage.setRGB(i, j, newColor);
      }
    }

    return filteredImage;
  }