圖片灰度化原理與實現(java)

24位彩色圖與8位灰度圖

    首先要先介紹一下24位彩色圖像,在一個24位彩色圖像中,每一個像素由三個字節表示,一般表示爲RGB。一般,許多24位彩色圖像存儲爲32位圖像,每一個像素多餘的字節存儲爲一個alpha值,表現有特殊影響的信息[1]。

    在RGB模型中,若是R=G=B時,則彩色表示一種灰度顏色,其中R=G=B的值叫灰度值,所以,灰度圖像每一個像素只需一個字節存放灰度值(又稱強度值、亮度值),灰度範圍爲0-255[2]。這樣就獲得一幅圖片的灰度圖。

幾種灰度化的方法

    份量法:使用RGB三個份量中的一個做爲灰度圖的灰度值。
    最值法:使用RGB三個份量中最大值或最小值做爲灰度圖的灰度值。
    均值法:使用RGB三個份量的平均值做爲灰度圖的灰度值。
    加權法:因爲人眼顏色敏感度不一樣,按下必定的權值對RGB三份量進行加權平均能獲得較合理的灰度圖像。通常狀況按照:Y = 0.30R + 0.59G + 0.11B。
    [注]加權法其實是取一幅圖片的亮度值(人眼對綠色的敏感最高,對藍色敏感最低 )做爲灰度值來計算,用到了YUV模型。在[3]中會發現做者使用了Y = 0.21 * r + 0.71 * g + 0.07 * b(百度百科:Y = 0.30 * r + 0.59 * g + 0.11 * b)來計算灰度值。實際上,這種差異應該與是否使用伽馬校訂有關[1]。

強制設置灰度化的方法(效果相對就差)

/**
 * 圖片灰化(效果不行,不建議。聽說:搜索「Java實現灰度化」,十有八九都是一種方法)
 * 
 * @param bufferedImage 待處理圖片
 * @return
 * @throws Exception
 */
public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {

    int width = bufferedImage.getWidth();  
    int height = bufferedImage.getHeight();  

    BufferedImage grayBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); 
    for (int x = 0; x < width; x++) {  
        for(int y = 0 ; y < height; y++) {  
        	grayBufferedImage.setRGB(x, y, bufferedImage.getRGB(x, j));  
        }  
    }  
}

加權法灰度化(效果較好)

/**
 * 圖片灰化(參考:http://www.codeceo.com/article/java-image-gray.html)
 * 
 * @param bufferedImage 待處理圖片
 * @return
 * @throws Exception
 */
public static BufferedImage grayImage(BufferedImage bufferedImage) throws Exception {
	
	int width = bufferedImage.getWidth();
	int height = bufferedImage.getHeight();

	BufferedImage grayBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			// 計算灰度值
			final int color = bufferedImage.getRGB(x, y);
			final int r = (color >> 16) & 0xff;
			final int g = (color >> 8) & 0xff;
			final int b = color & 0xff;
			int gray = (int) (0.3 * r + 0.59 * g + 0.11 * b);
			int newPixel = colorToRGB(255, gray, gray, gray);
			grayBufferedImage.setRGB(x, y, newPixel);
		}
	}
	
	return grayBufferedImage;
	
}

/**
 * 顏色份量轉換爲RGB值
 * 
 * @param alpha
 * @param red
 * @param green
 * @param blue
 * @return
 */
private static int colorToRGB(int alpha, int red, int green, int blue) {
	
	int newPixel = 0;
	newPixel += alpha;
	newPixel = newPixel << 8;
	newPixel += red;
	newPixel = newPixel << 8;
	newPixel += green;
	newPixel = newPixel << 8;
	newPixel += blue;

	return newPixel;
	
}

參考

[1] 《多媒體技術教程》Ze-Nian Li,Mark S.Drew著,機械工業出版社。
[2] 百度百科:灰度值
[3] Java color image to grayscale conversion algorithm(s) html

相關文章
相關標籤/搜索