所以这是交易:我尝试简化(对用户)如何执行卷积。我尝试使用它来运行Sobel滤镜,当我尝试显示图像时(通过jfram和图像图标),图像图标不会弹出,它只是一个大的灰色方块。
jframe / imageicon完美运行,直到我试图让它显示此过滤器结果的输出。
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已更新
如果我执行以下操作,我的gui将显示一个没有图像的平面灰色框。如果我执行一个命令而不执行另一个命令,则图像将完美显示。 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
如果我只能转换为灰度,我会得到正确的结果,如果我只是应用JUST过滤器我会得到正确的结果。如果我按原样完成,我会弹出一个空白GUI屏幕。如果我交换它们执行的顺序(先过滤然后转换为灰度),我会得到结果。
我认为灰度转换过程中的一些事情搞砸了卷积
toGrayscale应该将图像转换为灰度
convolutionFilter应该采用2D图像过滤器,将其展开为1D数组,然后对processedImage进行卷积并返回结果。
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;
}
}
答案 0 :(得分:3)
不确定您的输入图片是什么,因此您为imageType
图片构造函数指定的BufferedImage.TYPE_INT_ARGB
(temp
)参数可能存在差异。您不必在:
op.filter(processedImage, temp);
您可以使用ConvolveOp.filter()返回的图片,尝试以下操作:
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;
}
然后将使用源ColorModel
创建生成的图像。
在toGrayscale()简介后编辑
我无法使用toGrayScale / convolutionFilter组合重现您遇到的问题。我使用您的两种更新方法获得了正确的结果。您有机会分享您正在使用的图像吗?
编辑:
此代码适用于上述图片:
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();
}
}
另请注意,所提及图像的类型为TYPE_3BYTE_BGR
。这可能会干扰ConvolveOp
的正常操作。这是一个bug。看起来它只在Java 7中修复。
另请注意,在tempImage
和toGrayscale()
的实施中初始分配convolutionFilter()
是多余的。