Reputation: 603
So heres the deal: I tried simplifiying (to the user) how to execute convolution. I tried using this to run a Sobel filter and when i try to display the image (via jfram and image icon) the image icon doesnt pop up, it just a big gray square.
The jframe/imageicon worked flawlessly until i tried to get it to display the output of the result of this filter.
float[][] sobel = { { -1, 0, 1},
{ -2, 0, 2},
{-1, 0, 1} };
someObject test = new someObject(filepath);
test.convolutionFilter(sobel);
public BufferedImage convolutionFilter(float[][] filter) {
int columns = filter.length;
int rows= filter[0].length;
float numTemp;
float[] filter1D = new float[columns*rows];
for (int j = 0; j<rows; j++) {
for (int i= 0; i< columns; i++ ) {
numTemp = filter[j][i];
System.out.print(numTemp + " ");
filter1D[j*columns + i] = numTemp;
}
}
Kernel kern = new Kernel(rows, columns, filter1D);
ConvolveOp op = new ConvolveOp(kern);
BufferedImage temp = new BufferedImage(processedImage.getWidth(), processedImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
op.filter(processedImage, temp);
processedImage = temp;
return processedImage;
}
CODE HAS BEEN UPDATED
If i do the following my gui will display a plane gray frame with no image. If I do one command and not the other, the image will display perfectly. BufferedImage testImage = ImageIO.read(filepath);
float[][] sobelFilter = { { -1, 0, 1},
{ -2, 0, 2},
{ -1, 0, 1} };
testImage = SimpleImage.toGrayscale(testImage);
testImage = SimpleImage.convolutionFilter(testImage, sobelFilter);
//use some swing functions to display image
if I JUST convert to grayscale I will get correct results, if i just apply JUST the filter I will get correct results. If I Complete this AS IS I get a Blank GUI screen that popsup. If I swap the order that they are executed (filter first then convert to grayscale) I will get results.
I think something with the grayscale conversion process is screwing up the convolution
toGrayscale should convert the image to grayscale
convolutionFilter should take a 2D image filter, unroll it into 1D array and then convolve the processedImage and return the result.
public class SimpleImage {
public static BufferedImage toGrayscale(BufferedImage processedImage) {
BufferedImage tempImage = new BufferedImage(processedImage.getWidth(), processedImage.getHeight(), processedImage.getType());
BufferedImageOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
tempImage = op.filter(processedImage, null);
return tempImage;
}
public static BufferedImage convolutionFilter(BufferedImage processedImage, float[][] filter2D) {
BufferedImage tempImage = new BufferedImage(processedImage.getWidth(), processedImage.getHeight(), processedImage.getType());
int columns = filter2D.length;
int rows= filter2D[0].length;
//Unrolls a 2D filter into a 1D filter
float[] filter1D = new float[columns*rows];
for (int j = 0; j<rows; j++) {
for (int i= 0; i< columns; i++ ) {
filter1D[j*columns + i] = filter2D[j][i];
}
}
//creates Kernal and convolution operator
Kernel kern = new Kernel(rows, columns, filter1D);
ConvolveOp op = new ConvolveOp(kern);
//apply filtering
tempImage = op.filter(processedImage, null);
return tempImage;
}
}
Upvotes: 1
Views: 2060
Reputation: 21223
Not sure what is your input image, so may be there is a discrepancy in the imageType
(BufferedImage.TYPE_INT_ARGB
) argument that you specify for you temp
image constructor. You don't have to provide a destination image in:
op.filter(processedImage, temp);
You can use the image returned by ConvolveOp.filter(), try the following:
public BufferedImage convolutionFilter(float[][] filter, BufferedImage processedImage) {
...
Kernel kern = new Kernel(rows, columns, filter1D);
ConvolveOp op = new ConvolveOp(kern);
BufferedImage temp = op.filter( processedImage, null );
return temp;
}
Then the resulting image will created with the source ColorModel
.
EDIT after toGrayscale() introduction
I could not reproduce the problem you're having with toGrayScale/convolutionFilter combination. I am getting correct results using both of your updated methods. Any chance you can share the image you're using?
EDIT :
This code works for the mentioned image:
public static void main(String args[]) {
try {
BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
image = SimpleImage.toGrayscale(image);
image = SimpleImage.convolutionFilter(image, sobel);
JOptionPane.showMessageDialog(null, "", "", JOptionPane.INFORMATION_MESSAGE, new ImageIcon( image ));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
Also, note that the type of mentioned image is TYPE_3BYTE_BGR
. This can interfere with proper operation of ConvolveOp
. Here is a bug. Looks like it was fixed only in Java 7.
Also, note that initial allocation of tempImage
in your implementation of toGrayscale()
and convolutionFilter()
is redundant.
Upvotes: 3