【问题标题】:Bluring a Java buffered image模糊 Java 缓冲图像
【发布时间】:2013-10-03 12:09:55
【问题描述】:

我想在 Java 中模糊缓冲图像,而不需要特殊的“模糊 api”。 现在我找到了这个page 并写了这段代码:

 public int[][] filter(int[][] matrix)
{
   float[] blurmatrix = {
    0.111f, 0.111f, 0.111f, 
    0.111f, 0.111f, 0.111f, 
    0.111f, 0.111f, 0.111f, 
};

   int[][] returnMatrix = new int[matrix.length][matrix[0].length];

   for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[0].length; j++) {
            returnMatrix[i][j]=matrix[i][j];
           for(int k=0;k<blurmatrix.length;k++)
           {
               float blurPixel= blurmatrix[k];
               int newPixel= (int) (returnMatrix[i][j]*blurPixel);
               returnMatrix[i][j]= newPixel;
           }
        }
    }
    return returnMatrix;

}

int 矩阵来自这个方法:

 public int[][] getMatrixOfImage(BufferedImage bufferedImage) {
    int width = bufferedImage.getWidth(null);
    int height = bufferedImage.getHeight(null);
    int[][] retrunMatrix = new int[width][height];
    for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
            retrunMatrix[i][j] = bufferedImage.getRGB(i, j);
        }
    }

    return retrunMatrix;
}

但它想要工作,怎么了?

谢谢!

更新

问题是,结果不是应该的。 当我有这个模糊矩阵时:

float[] blurmatrix = {
    10.111f, 0.111f, 0.111f, 
    0.111f, 50.111f, 0.111f, 
    0.111f, 0.111f, 10.111f, 
};

我得到这个结果:http://img854.imageshack.us/img854/541/2qw7.png 当我有这个模糊矩阵时:

float[] blurmatrix = {
    0.111f, 0.111f, 0.111f, 
    0.111f, 0.111f, 0.111f, 
    0.111f, 0.111f, 0.111f, 
};

图片被删除。

【问题讨论】:

  • 什么是“行不通”?例外?出乎意料的结果?结果与您的预期相比如何? ...
  • 对不起,我已经更新了问题

标签: java filtering bufferedimage


【解决方案1】:

您的矩阵似乎错误。通常,这些矩阵中所有数字的总和为 1。您的矩阵可能会使所有内容变为白色。

编辑:我看到你更正了矩阵。

Edit2:你的代码有很多错误。

您的方法 getMatrixOfImage 返回一个由 32 位 RGB 或 RGBA 值组成的数组。 您将这些值与过滤器值相乘。这是不正确的。这种乘法会使一种颜色的值溢出到其他颜色中。您需要分别将 R、G 和 B 值相乘。

您的最内层循环(具有 k 索引的循环)完全错误。你拿一个像素乘以 0.111 九次。您需要做的是在每个像素周围取 3x3 像素正方形,将每个像素乘以该像素的过滤器值,将它们相加,然后将它们保存为该像素。

另一个错误是您将源图像中的像素一个接一个地填充到目标图像中,这是行不通的,因为您需要尚未填充的相邻像素。

您的函数需要创建一个与源图像大小相同的新图像数组。 然后它需要遍历目标图像并获取每个像素,例如:

在源图像中的位置[x-1][y-1][x][y-1][x+1][y-1][x-1][y][x][y][x+1][y][x-1][y+1][x][y+1][x+1][y+1] 处获取像素并与它们相乘值(在您的情况下,每个值为 0.111),将它们相加并将像素保存到新图像中。

请注意,您需要对每种颜色分别执行此操作(使用二进制 AND 运算和位移来获取每种颜色值)。您还需要考虑边缘,其中[x-1][y-1] 像素可能不存在。您可以将值替换为 0 或使用 [x][y] 代替。

【讨论】:

    【解决方案2】:

    您没有正确执行convolution。您需要将(i,j) 处的像素设置为所有周围像素的平均值。这就是1/9 = 0.111f 的用途。卷积运算会将一个像素的所有相邻像素平均为一个值,并将该值设置为中心像素:

    for (int i = 0; i < matrix.length; i++) {
        for (int j = 0; j < matrix[i].length; j++) {
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i-1, j-1)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i-1, j)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i-1, j+1)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i  , j-1)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i  , j)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i  , j+1)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i+1, j-1)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i+1, j)));
             returnMatrix[i][j] += (int)( 0.111f * get(returnMatrix, i+1, j+1)));
        }
    }
    
    int get(int[][]m, int i, int j) {
       if(i >= 0 && i < m.length && j >= 0 && j <= m[i].length) {
           return m[i][j];
       }
       return 0;
    }
    

    【讨论】:

    • @UMad 好吧,这需要按 R、G 和 B 完成。由 OP 为不同的通道编写额外的循环。这就是您对矩阵进行卷积的方式,需要卷积多少矩阵(不同颜色分量)取决于用户。
    【解决方案3】:

    该算法使用内核对bufferedImage的图像矩阵进行了卷积,不同的内核可以用于不同的目的。

    希望对你有帮助

    import java.awt.Color;
    import javax.imageio.ImageIO;
    import java.io.*;
    import java.awt.image.BufferedImage;
    
    
    class psp {
    
        public static void main(String[] args) {
    try
    {
    
    
    File input=new File("abc.jpg");
    File output=new File("output1.jpg");
            BufferedImage picture1 = ImageIO.read(input);   // original
    BufferedImage picture2= new BufferedImage(picture1.getWidth(), picture1.getHeight(),BufferedImage.TYPE_INT_RGB);      
            int width  = picture1.getWidth();
            int height = picture1.getHeight();
    
    //int kernel[][]={{-1,-1,-1},{-1,8,-1},{-1,-1,-1}};//for edge detection
    float kernel[][]={{0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f}};//for blur
    //float kernel[][]={{0.111f,0.111f,0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f,0.111f,0.111f},{0.111f,0.111f,0.111f,0.111f,0.111f}};
    //int kernel[][]={{0,-1,0},{-1,5,-1},{0,-1,0}};//for sharpen
    
    for (int y = 0; y < height ; y++) {//loops for images
    for (int x = 0; x < width ; x++) {
    
    int r=0,g=0,b=0;//for kernel
    for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
    try
    {
    Color c=new Color(picture1.getRGB(x+i-1,y+j-1));//x+i-1,y+j-1 will do exact what we want
     r+=c.getRed()*kernel[i][j];
     b+=c.getBlue()*kernel[i][j];
     g+=c.getGreen()*kernel[i][j];
    }catch(Exception e){}
    
    }
    }
     r = Math.min(255, Math.max(0, r));
    g = Math.min(255, Math.max(0, g));
    b = Math.min(255, Math.max(0, b));
    Color color = new Color(r, g, b);
    picture2.setRGB(x, y, color.getRGB());
    
    }
    }
    
    
    
    
    ImageIO.write(picture2,"jpg",output);       
    }catch(Exception e){
    System.out.println(e);
    }}}
    

    【讨论】:

      猜你喜欢
      • 2013-04-14
      • 1970-01-01
      • 2013-02-27
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      相关资源
      最近更新 更多