Question

I spent the whole day trying to implement the "convolution algorithm" in Java, but this last does not seem to work properly with all kernels, it works great with the blur kernel with a factor of 1/9, but not with the other ones.

For example, if I use the {{0.1.0},{0,0,0},{0,0,0}} matrix which is supposed to shift the image up by 1 pixel, surprisingly, it stretches the image all the way down.

Example of what I get:

enter image description here

And here is the code:

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

    }

}
Was it helpful?

Solution

With

outputimg = bfimg;

you are setting the output image to be the same as the input image. When you perform the convolution of the first row, then (as you said) the first row of pixels from the input image will be written into the the second row of the output image. But they are identical - so you end up with all rows of the output image being copies of the first row of the input image.

Just replace this line with

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

to create a new output image to write to.

By the way: All this is already available in the standard API. You might want to have a look at the classes related to http://docs.oracle.com/javase/7/docs/api/java/awt/image/ConvolveOp.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top