【问题标题】:Code for image convolution not displaying an image properly?图像卷积代码无法正确显示图像?
【发布时间】:2012-03-14 20:46:43
【问题描述】:

所以这是交易:我尝试简化(对用户)如何执行卷积。我尝试使用它来运行 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;

}

代码已更新

如果我执行以下操作,我的 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 

如果我只是转换为灰度,我会得到正确的结果,如果我只是应用过滤器,我会得到正确的结果。如果我按原样完成此操作,我会弹出一个空白 GUI 屏幕。如果我交换它们的执行顺序(先过滤然后转换为灰度),我会得到结果。

我认为灰度转换过程搞砸了卷积

toGrayscale 应该将图像转换为灰度

convolutionFilter 应该采用 2D 图像过滤器,将其展开为 1D 数组,然后对处理后的图像进行卷积并返回结果。

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; 

    } 
 } 

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖 SSCCE。你有问题吗? (不,在标题中添加“?”不会成为问题。)
  • 尝试调试时发现了什么?
  • @Adam,更新后的代码运行良好。请参阅我的答案中的编辑。

标签: java swing image-processing signal-processing convolution


【解决方案1】:

不确定您的输入图像是什么,因此您为temp 图像构造函数指定的imageType (BufferedImage.TYPE_INT_ARGB) 参数可能存在差异。您不必在以下位置提供目标图片:

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 中得到修复。

另外,请注意,在 toGrayscale()convolutionFilter() 的实现中初始分配 tempImage 是多余的。

【讨论】:

  • 我尝试使用从维基百科页面获得的标准图像 Lenna.png:en.wikipedia.org/wiki/Lenna(这个)
  • @Adam,看看你上次编辑的代码会得到什么样的结果。
  • 它是 wiki 页面上的 Lenna 图像。 upload.wikimedia.org/wikipedia/en/thumb/2/24/Lenna.png/… 谢谢。
  • 仍然没有图像,也没有异常。另外:我正在使用 Java 6(我认为我们不会很快在这里升级)
  • @Adam,上述代码 (JOptionPane.showMessageDialog) 在 Win7 x64、JDK 1.6.0_29 上运行良好。你的平台是什么?
猜你喜欢
  • 1970-01-01
  • 2020-08-27
  • 2021-09-26
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多