public static BufferedImage median(BufferedImage input, int size) {

        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++) {

                List<Integer> reds = new ArrayList<Integer>();
                List<Integer> greens = new ArrayList<Integer>();
                List<Integer> blues = new ArrayList<Integer>();

                for (int dx = -size / 2; dx < size / 2; dx++) {
                    for (int dy = -size / 2; dy < size / 2; dy++) {
                        Color c = new Color(input.getRGB(Math.abs(i + dx) % result.getWidth(),
                                Math.abs(j + dy) % result.getHeight()));
                        reds.add(c.getRed());
                        greens.add(c.getGreen());
                        blues.add(c.getBlue());
                    }
                }

                Collections.sort(reds);
                Collections.sort(greens);
                Collections.sort(blues);

                result.setRGB(i, j, new Color(
                        reds.get(reds.size() / 2),
                        greens.get(greens.size() / 2),
                        blues.get(blues.size() / 2)).getRGB());
            }

        return result;
    }