【问题标题】:convert a RGB image to grayscale Image reducing the memory in java将RGB图像转换为灰度图像减少java中的内存
【发布时间】:2012-02-26 05:59:26
【问题描述】:

我有一个 RGB bufferedImage bImg。
我想将 bImg 转换为灰度图像。

BufferedImage grayIm=new BufferedImage(bImg.getWidth(null), bImg.getHeight(null), BufferedImage.TYPE_BYTE_GRAY); 

我已经尝试过这个 grayIm,但我无法设置这个 grayIm 的灰度值。

【问题讨论】:

标签: java image-processing


【解决方案1】:

一种方法可能是转换色彩空间(性能不佳):

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);  
ColorConvertOp op = new ColorConvertOp(cs, null);  
BufferedImage image = op.filter(bufferedImage, null);

另一种方法是使用 BufferedImage,就像你一样(更好的性能):

BufferedImage image = new BufferedImage(width, height,  
    BufferedImage.TYPE_BYTE_GRAY);  
Graphics g = image.getGraphics();  
g.drawImage(colorImage, 0, 0, null);  
g.dispose();  

最后但同样重要的是,最好的性能是使用 GrayFilter:

ImageFilter filter = new GrayFilter(true, 50);  
ImageProducer producer = new FilteredImageSource(colorImage.getSource(), filter);  
Image mage = Toolkit.getDefaultToolkit().createImage(producer);  

来源:http://www.codebeach.com/2008/03/convert-color-image-to-gray-scale-image.html

编辑:根据马克的评论。

【讨论】:

  • 第三种方法中,createImage没有定义。 this 应该是 Toolkit.getDefaultToolkit()
  • 第三种实现的性能是否比下面的解决方案好很多?
【解决方案2】:

注意:这不是 OP 所要求的(因为它确实减少内存使用量),但我将把它留在这里,因为人们喜欢每个像素的手册方法。相反,我将展示如何准确计算灰度颜色。


这很简单。这个想法是迭代图像的每个像素,并将其更改为等效的灰度。

public static void makeGray(BufferedImage img)
{
    for (int x = 0; x < img.getWidth(); ++x)
    for (int y = 0; y < img.getHeight(); ++y)
    {
        int rgb = img.getRGB(x, y);
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = (rgb & 0xFF);

        // Normalize and gamma correct:
        float rr = Math.pow(r / 255.0, 2.2);
        float gg = Math.pow(g / 255.0, 2.2);
        float bb = Math.pow(b / 255.0, 2.2);

        // Calculate luminance:
        float lum = 0.2126 * rr + 0.7152 * gg + 0.0722 * bb;

        // Gamma compand and rescale to byte range:
        int grayLevel = (int) (255.0 * Math.pow(lum, 1.0 / 2.2));
        int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel; 
        img.setRGB(x, y, gray);
    }
}

但是,这不会减少内存。要有效减少内存使用,请执行相同的过程,但使用灰度 BufferedImage 作为输出。

【讨论】:

  • 但这会减少内存@Martijn Courteaux
  • 实际上,灰度转换并不是 R、G 和 B 通道的简单平均,因为蓝色对我们的亮度感知贡献最小,而绿色贡献最大。为了准确表示灰度图像中的光强度,需要加权平均。使用 0.2126R + 0.7152G + 0.0722B
  • @Mr.WorshipMe:太好了!我知道这种现象。关于你的体重的任何资源?
  • @MartijnCourteaux 这是 OpenCV 在 cvtColor 中使用的,它也出现在 wikipedia 的灰度文章中。
  • @MartijnCourteaux。如何仅从一个通道(如 R)创建灰度图像。新图片仅采用红色的 rgb 值是否足够?
【解决方案3】:

我也遇到了同样的问题。您选择的解决方案不仅取决于性能水平。也有必要了解您所追求的图像质量。请看这些例子。他们都维护源代码。 http://codehustler.org/blog/java-to-create-grayscale-images-icons/

【讨论】:

    猜你喜欢
    • 2014-02-26
    • 2014-12-22
    • 2019-11-14
    • 1970-01-01
    • 2016-11-05
    • 2013-10-25
    • 1970-01-01
    • 2018-08-15
    相关资源
    最近更新 更多