一、标准转换公式:
gray = r * 0.299 + g * 0.587 + b * 0.114
采用RGB三个通道值分别乘以一个系数(权重),之后再求和,三个系数之和为1,也就是加权平均。
代码:
public BufferedImage transferGrayImage(BufferedImage image) {
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int gray = (r * 299 + g * 587 + b * 114 + 500) / 1000;
rgb = (255 & 0xff) << 24 | (gray & 0xff) << 16 | (gray & 0xff) << 8 | gray & 0xff;
grayImage.setRGB(i, j, rgb);
}
}
return grayImage;
}
二、Photoshop转灰度图公式:
Gray = (0.2973*R^2.2 + 0.6274 * G^2.2 + 0.0753 * B^2.2 )^(1/2.2)
Photoshop的转换方式为,RGB通道分别进行指数为2.2的幂运算,再进行加权平均,之后再开2.2次方。由于计算过程包含幂运算和乘运算,处理过程计算量比较大,可以通过查找表来优化。
代码:
public BufferedImage transferGrayImageByAdobe(BufferedImage image) {
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
double r = (rgb >> 16) & 0xff;
double g = (rgb >> 8) & 0xff;
double b = rgb & 0xff;
double gray = Math.pow(
0.2973 * Math.pow(r, 2.2) + 0.6274 * Math.pow(g, 2.2) + 0.0753 * Math.pow(b, 2.2), 1.0 / 2.2);
rgb = (255 & 0xff) << 24 | ((int) gray & 0xff) << 16 | ((int) gray & 0xff) << 8 | (int) gray & 0xff;
grayImage.setRGB(i, j, rgb);
}
}
return grayImage;
}
三、RGB均值转灰度
求取RGB三个通道均值作为该像素灰度值。
代码:
public BufferedImage transferGrayImageByAverage(BufferedImage image) {
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int gray = (r + g + b) / 3;
rgb = (255 & 0xff) << 24 | (gray & 0xff) << 16 | (gray & 0xff) << 8 | gray & 0xff;
grayImage.setRGB(i, j, rgb);
}
}
return grayImage;
}
四、RGB最低通道转灰度
取RGB三个通道中最小值最为灰度值。
public BufferedImage transferGrayImageByLowest(BufferedImage image) {
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int[] arr = new int[] { r, g, b };
Arrays.sort(arr);
int gray = arr[0];
rgb = (255 & 0xff) << 24 | (gray & 0xff) << 16 | (gray & 0xff) << 8 | gray & 0xff;
grayImage.setRGB(i, j, rgb);
}
}
return grayImage;
}
五、RGB最高通道转灰度
public BufferedImage transferGrayImageByHighest(BufferedImage image) {
BufferedImage grayImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
int[] arr = new int[] { r, g, b };
Arrays.sort(arr);
int gray = arr[2];
rgb = (255 & 0xff) << 24 | (gray & 0xff) << 16 | (gray & 0xff) << 8 | gray & 0xff;
grayImage.setRGB(i, j, rgb);
}
}
return grayImage;
}