public static BufferedImage sobel(BufferedImage input) {
        int Gx[][] = new int[][]{
                {-1, 0, 1},
                {-2, 0, 2},
                {-1, 0, 1}
        };

        int Gy[][] = new int[][]{
                {-1, -2, -1},
                {0, 0, 0},
                {1, 2, 1}
        };

        BufferedImage result = new BufferedImage(input.getWidth(), input.getHeight(), input.getType());


        for (int i = 0; i < result.getWidth(); i++)
            for (int j = 0; j < result.getHeight(); j++) {

                double redX = 0;
                double greenX = 0;
                double blueX = 0;
                double redY = 0;
                double greenY = 0;
                double blueY = 0;


                for (int s = -1; s < 2; s++) {
                    for (int k = -1; k < 2; k++) {
                        Color c = new Color(input.getRGB(Math.abs(i + s) % result.getWidth(),
                                Math.abs(j + k) % result.getHeight()));
                        redX += Gx[s + 1][k + 1] * c.getRed();
                        greenX += Gx[s + 1][k + 1] * c.getGreen();
                        blueX += Gx[s + 1][k + 1] * c.getBlue();

                        redY += Gy[s + 1][k + 1] * c.getRed();
                        greenY += Gy[s + 1][k + 1] * c.getGreen();
                        blueY += Gy[s + 1][k + 1] * c.getBlue();
                    }
                }
                Color diff12 = normColor(redX, greenX, blueX);
                Color diff34 = normColor(redY, greenY, blueY);


                int r = (int) Math.sqrt(diff12.getRed() * diff12.getRed() + diff34.getRed() * diff34.getRed());
                int g = (int) Math.sqrt(diff12.getGreen() * diff12.getGreen() + diff34.getGreen() * diff34.getGreen());
                int b = (int) Math.sqrt(diff12.getBlue() * diff12.getBlue() + diff34.getBlue() * diff34.getBlue());

                result.setRGB(i, j, normColor(r, g, b).getRGB());
            }

        return result;
    }