public void mergeTwoImages(BufferedImage firstImage) {
    int width = originalImage.getWidth();
    int height = originalImage.getHeight();

    int black = 0;
    int white = 255;

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

        int oldColor = new Color(originalImage.getRGB(i, j)).getRed();
        if (oldColor == white) {
          int alpha = new Color(firstImage.getRGB(i, j)).getAlpha();
          rgb = PreprocessingHelper.colorToRGB(alpha, black, black, black);
        } else {
          rgb = new Color(firstImage.getRGB(i, j)).getRGB();
        }
        filteredImage.setRGB(i, j, rgb);
      }
    }
  }
  @Override
  public BufferedImage processImage(BufferedImage image) {

    originalImage = image;
    wSize = 31;
    k = 0.02;

    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 = wSize / 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 / (wSize * wSize);

        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 = PreprocessingHelper.colorToRGB(alpha, newColor, newColor, newColor);

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

    return filteredImage;
  }