Is there a function to sum the rasters of two buffered images?
-
12-12-2019 - |
Question
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);
}
Solution
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);
}
}
OTHER TIPS
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.