1

I'm doing 2D filteing and want to do element by element addition on grayscale BufferedImages. Is there an existing function that will complete this for me or do i need to make one from scrach?

Is there some sort of matrix class that converts a raster to a matrix to simplyfy this problem?

Edit: here is the general gist of it

    BufferedImageOp opX = new ConvolveOp(new Kernel(3,3, kernelX));
    BufferedImageOp opY = new ConvolveOp(new Kernel(3,3, kernelY));
    BufferedImage filtImageX = opX.filter(sourceImage, null);
    BufferedImage filtImageY = opY.filter(sourceImage, null);
    BufferedImage outputImage = addBufferedImages(filtImageX, filtImageY);

Grayscale Conversion:

public void toGrayscale() { 
     BufferedImageOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); 
     sourceImage = op.filter(sourceImage, null); 
}
Adam
  • 593
  • 7
  • 13

2 Answers2

1

I am not familiar with any java libs that do that for you.

You can get pixel at [i,j] with: image.getRGB(i, j);

BufferedImage image = ...;
BufferedImage resultImage = ...

int rgb= image.getRGB(i, j);
resultImage.setRGB(i, j, rgb);

You can also convert a buffered image to a byte array [ https://stackoverflow.com/a/7388025/1007845 ].
See this thread: how to convert image to byte array in java? to get a WritableRaster

EDIT:

It seems that WritableRaster might be useful in this case: http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/WritableRaster.html

WritableRaster raster = image.getRaster();

for(int h=0;h<height;h++) {
    for(int w=0;w<width;w++) {
        int colour = 127;
      raster.setSample(w,h,0,colour); 
   }
}
Community
  • 1
  • 1
Adrian
  • 5,603
  • 8
  • 53
  • 85
  • it says an interger is returned. How can you grab the apropriate pixel from that? (I know that an int is 4bytes each one represents a different channel) Remember i've converted the colorspace to grayscale...so how do i interpret the information then. – Adam Mar 12 '12 at 16:51
  • @Adam for greyscale you calculate luminescence sth like: L = .30*R + .59*G + .11*B. Point I'm trying to make is that you still have integers. Could you post your code, it would help :) – Adrian Mar 12 '12 at 17:30
  • @Adam don't you still have R,G,B values after your convolution? where is the code where you can't get colour of the pixel as int? – Adrian Mar 12 '12 at 18:56
  • @Adam I edited the post to include WritableRaster. Try it out! – Adrian Mar 13 '12 at 14:54
1

I don't know of a direct way to do this.

But i can suggest a slightly underhanded approach. First, take your two images, and combine them into a single image with two bands. I'm hazy on the details of how to do this. I suspect you will want to create a Raster with a BandedSampleModel, and then blit the contents of the other two images into its DataBuffer. Although it looks like you should be able to create a two-bank DataBuffer which uses the arrays of the source images' (one-banked) DataBuffers as banks, which would avoid copying.

Once you have a two-band image, simply apply a BandCombineOp which sums the bands. You will need to express the summation as a matrix, but that shouldn't be hard. I think it would be [1.0, 1.0],or [0.5, 0.5] if you want to rescale the result.

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133