卷积实现不能按预期工作

时间:2014-03-21 18:43:08

标签: java image matrix convolution

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

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

我得到的例子:

enter image description here

以下是代码:

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);

    }

}

1 个答案:

答案 0 :(得分: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

相关的类