【问题标题】:Convolution implementation does not work as expected卷积实现没有按预期工作
【发布时间】:2014-03-21 18:43:07
【问题描述】:

我花了一整天的时间尝试在 Java 中实现“卷积算法”,但最后一个似乎不适用于所有内核,它适用于因子为 1/9 的模糊内核,但不适用于其他的。

例如,如果我使用应该将图像向上移动 1 个像素的 {{0.1.0},{0,0,0},{0,0,0}} 矩阵,令人惊讶的是,它会将图像一直向下拉伸。

我得到的示例:

这里是代码:

public class ConvolutionTest {

    static BufferedImage bfimg;
    static BufferedImage outputimg;
    static File output = new File("/home/bz/Pictures/Selection_003_mod");
    static File input = new File("/home/bz/Pictures/Selection_003.png");
    static WritableRaster wr;
    static int tempColor;
    static double [] newColor = {0,0,0};
    static double red=0, green=0, blue=0;
    static double sumR=0, sumG=0, sumB=0;

    public static void main(String[] args) throws IOException {

        int tempIcoor;
        int tempJcoor;
        double[][] matConv = {      
                                {0d, 1d, 0d},
                                {0d, 0d, 0d},
                                {0d, 0d, 0d}
                              };

         bfimg = ImageIO.read(input);
         outputimg = bfimg;
         wr = outputimg.getRaster();


         for (int i = 1; i < bfimg.getHeight()-1; i++) {
            for (int j = 1; j < bfimg.getWidth()-1; j++) {

                tempIcoor = i - 1;
                tempJcoor = j - 1;


                for (int tempI = 0; tempI < 3; tempI++) {
                    for (int tempJ = 0; tempJ < 3; tempJ++) {

                        tempColor = bfimg.getRGB(tempJcoor, tempIcoor);

                        red = tempColor >> 16 & 0xff;
                        red = red * matConv[tempI][tempJ];

                        green = tempColor >> 8  & 0xff;
                        green = green * matConv[tempI][tempJ];

                        blue = tempColor      & 0xff;
                        blue = blue * matConv[tempI][tempJ];;

                        sumR = red + sumR;

                        sumG = green + sumG;

                        sumB = blue + sumB;


                        tempJcoor++;

                    }


                    newColor[0] = sumR;
                    newColor[1] = sumG;
                    newColor[2] = sumB;

                    tempIcoor++;
                    tempJcoor=j-1;
                }

                wr.setPixel(j, i, newColor);    

                sumR=0;
                sumG=0;
                sumB=0;
            }
        }

        ImageIO.write(sortie, "png", output);

    }

}

【问题讨论】:

    标签: java image matrix convolution


    【解决方案1】:

    outputimg = bfimg;
    

    您将输出图像设置为与输入图像相同。当您执行第一行的卷积时,然后(如您所说)输入图像的第一行像素将被写入输出图像的第二行。但它们是相同的 - 所以最终输出图像的所有行都是输入图像第一行的副本。

    只需将此行替换为

    outputimg = new BufferedImage(
        bfimg.getWidth(), bfimg.getHeight(), 
        BufferedImage.TYPE_INT_ARGB); 
    

    创建要写入的新输出图像。

    顺便说一句:所有这些都已在标准 API 中可用。你可能想看看与http://docs.oracle.com/javase/7/docs/api/java/awt/image/ConvolveOp.html 相关的类

    【讨论】:

    • 这很好用!谢谢你的帮助马可,我真的很感激!我们的教授有一个实际的工作来实现卷积算法,所以这就是为什么我这样做并避免使用我从未听说过的 API ^^ 另外,你怎么能建议我截断像素值?非常感谢!
    • “截断”到底是什么意思?当您有 R、G、B 值并希望将它们“或”在一起(使用 (r&lt;&lt;16) | (g&lt;&lt;8) | b)时,您通常必须确保对于每个组件都有值 r&gt;=0r&lt;256,例如在 r=Math.max(0,Math.min(r,255));但我不确定这是否是你所要求的......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 1970-01-01
    • 2021-10-01
    • 2021-10-19
    • 2020-03-18
    • 2012-06-14
    • 2014-11-15
    相关资源
    最近更新 更多