如何在java中制作流畅的模糊效果?

时间:2017-05-02 17:35:42

标签: java image

我模糊了一个图像。但它并不顺利。

我听说如果我使用高斯模糊技术,那么我可以删除框效果。

但我不知道如何用我的代码实现它(我做了一些随机技术,但它与颜色混淆)。你能建议我如何使用我的代码进行高斯模糊吗?

public class BlurImageDemo {

Color c[];

BlurImageDemo() throws IOException, InterruptedException {
    File f = new File("D:\\x.jpg");
    BufferedImage im = ImageIO.read(f);

    BufferedImage bi = new BufferedImage(im.getWidth(), im.getHeight(), BufferedImage.TYPE_INT_RGB);
    int i = 0;
    int max = 400, radius = 10;
    int a1 = 0, r1 = 0, g1 = 0, b1 = 0;
    c = new Color[max];
    int x = 1, y = 1, x1, y1, ex = 5, d = 0;
    for (x = radius; x < im.getHeight() - radius; x++) {
        for (y = radius; y < im.getWidth() - radius; y++) {

            //20x20 matrix
            for (x1 = x - radius; x1 < x + radius; x1++) {
                for (y1 = y - radius; y1 < y + radius; y1++) {
                    c[i++] = new Color(im.getRGB(y1, x1));
                    //System.out.println(i);
                }
            }
            i = 0;

            for (d = 0; d < max; d++) {
                a1 = a1 + c[d].getAlpha();
            }
            a1 = a1 / (max);

            for (d = 0; d < max; d++) {
                r1 = r1 + c[d].getRed();
            }
            r1 = r1 / (max);

            for (d = 0; d < max; d++) {
                g1 = g1 + c[d].getGreen();
            }
            g1 = g1 / (max);

            for (d = 0; d < max; d++) {
                b1 = b1 + c[d].getBlue();
            }
            b1 = b1 / (max);
            int sum1 = (a1 << 24) + (r1 << 16) + (g1 << 8) + b1;
            bi.setRGB(y, x, (int) (sum1));

        }
    }
    ImageIO.write(bi, "jpg", new File("D:\\x1.jpg"));
}

public static void main(String[] args) throws IOException, InterruptedException {
    new BlurImageDemo();
}
}

this is the final image, which is not smooth

3 个答案:

答案 0 :(得分:1)

这是我找到的最好的文章:

Java Image Processing

答案 1 :(得分:0)

我得到了答案。在这里。

IDE

答案 2 :(得分:0)

高斯模糊的一个非常好的属性是它是可分离的,这意味着它可以表示为纯水平和纯垂直模糊的组合。这样做的好处是,每个像素,它们需要2N次乘法(N是内核的大小),而2D非分离版本需要N 2 乘法。对于N = 7(正如你所知),这已经是一个不错的差异。它也有一个小的缺点,中间结果是四舍五入(失去一些精度)或大(每个像素3个浮点数而不是1个int),通常一点点舍入不是问题。

另一方面,更多的实现细节是,内核总权重的除法可以放入内核本身,从而节省了大量(非常慢)的划分。

此外,你的内核实际上看起来不像高斯,它太“尖”了。这取决于你,但高斯内核是唯一的循环对称的,也是可分离的(如果你只看实值内核)并且通常具有很好的属性,所以如果有充分的理由我建议只偏离它为了它。

无论如何,我现在会编写一些示例代码,未经过测试:

BufferedImage transposedHBlur(BufferedImage im) {
    int height = im.getHeight();
    int width = im.getWidth();
    // result is transposed, so the width/height are swapped
    BufferedImage temp =  new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
    float[] k = new float[7] { 0.00598, 0.060626, 0.241843, 0.383103, 0.241843, 0.060626, 0.00598 };
    // horizontal blur, transpose result
    for (int y = 0; y < height; y++) {
        for (int x = 3; x < width - 3; x++) {
            float r = 0, g = 0, b = 0;
            for (int i = 0; i < 7; i++) {
                int pixel = im.getRGB(x + i - 3, y);
                b += (pixel & 0xFF) * k[i];
                g += ((pixel >> 8) & 0xFF) * k[i];
                r += ((pixel >> 16) & 0xFF) * k[i];
            }
            int p = (int)b + ((int)g << 8) + ((int)r << 16);
            // transpose result!
            temp.setRGB(y, x, p);
        }
    }
    return temp;
}

由于它也会转置,你可以简单地调用它两次,第二次实际上是一个垂直模糊,也可以恢复方向:

temp = transposedHBlur(input);
result = transposedHBlur(temp);