[计算机视觉]灰度图像处理

计算机视觉专栏: https://blog.csdn.net/qq_41806966/category_9940691.html

彩色图像

在一个图像中,每一个像素有三个值 R(红色) G(绿色) B(蓝色)

要将一张图片变为只有黑白图很简单,就是将 R = G = B(值高偏白,值低偏黑)

我们也可以让这张图片只保留红色部分 G = B = 0,R不变

同理,也可以只保留绿色,蓝色,也可以去除一种颜色,保留其余两种

通常我们处理灰度图有几种方式

  • 分量法:从 R,G,B 中随便取一个值,另外两个分量直接等于这个值
  • 最值法:取最大或最小
    • 取R,G,B中数值最大的一个,例如R最大,那么G=B=R
    • 取R,G,G中数值最小的一个
  • 均值法:将三个分量取平均值来进行灰度处理
  • 加权法(这个效果可以):人眼颜色敏感度不同,按一定权值对三个分量进行加权平均能得到较合理的灰度图像
    • 一般情况都是 color = 0.35R + 0.59G + 0.11B

测试(这里我用的 Java)

RGB十进制与十六进制转换请参考: https://blog.csdn.net/qq_41806966/article/details/105816250

将转换的代码 类定义好

/**
 * 灰度图像
 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
 * @version 1.0
 */
public class GrayLevelImage {
	static int r,g,b;//对应像素点的r,g,b
	
	/**
	 * 将获取的 RGB 十六进制转成 rgb
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param color
	 */
	static void colorToRGB(int color) {
		r = (color >> 16) & 0xFF;
		g = (color >> 8) & 0xFF;
		b = color & 0xFF;
	}
	
	/**
	 * 将RGB转为十六进制的十进制形式
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 红色值
	 * @param g 绿色值
	 * @param b 蓝色值
	 * @return 十进制
	 */
	static int rgbToColor(int r,int g,int b) {
		//完全不透明
		int color = 255 << 24; 
		//rgb添加上 255 一位
		color += r << 16;
		color += g << 8;
		color += b;
		return color;
	}
	
	public static void main(String[] args) throws FileNotFoundException, IOException {
		//获取到图片
		BufferedImage image = ImageIO.read(new FileInputStream("F:/Test/ali_test.png"));
		int width = image.getWidth();
		int height = image.getHeight();
		//对每个像素点进行操作
		for (int y = 0;y < height;y++) {
			for (int x = 0;x < width;x++) {
				int color = image.getRGB(x, y);
				//获取rgb
				colorToRGB(color);
				//处理颜色
				
				//设置颜色
				image.setRGB(x,y,color);
			}
		}
		//处理后的图片进行输出
		ImageIO.write(image, "png", new FileOutputStream("F:/Test/test.png"));
	}
}

分量法处理的图像(这里取R)

 添加如下方法

   /**
	 * 分量处理图像
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int flcl(int r,int g,int b) {
		g = r;
		b = r;
		return rgbToColor(r, g, b);
	}

在main中添加

测试结果

 

  最值法(我这里取最大值) 同样要在main里调用

/**
	 * 取最大值处理图像
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int getMax(int r,int g,int b) {
		int temp = r > g ? (r > b ? r : b) : (g > b ? g : b);
		return rgbToColor(temp,temp,temp);
	}

测试结果

 均值法

/**
	 * 均值法
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int averageRGB(int r,int g,int b) {
		int temp = (r*g*b) / 3;
		return rgbToColor(temp,temp,temp);
	}

运行结果 

加权法(用这个比较科学,也可以自己看哪种效果好自己调节...)

/**
	 * 加权法
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int weightRGB(int r,int g,int b) {
		int temp = (int) (0.3 * r + 0.59 * g + 0.11 * b);
		return rgbToColor(temp,temp,temp);
	}

测试结果

这个结果与平均法感觉一模一样?换一张图片试试

放大就可以看清差别了

加权法

平均法

全部的代码(关注获取更多精彩)

/**
 * 灰度图像
 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
 * @version 1.0
 */
public class GrayLevelImage {
	
	static int r,g,b;//对应像素点的r,g,b
	
	/**
	 * 将获取的 RGB 十六进制转成 rgb
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param color
	 */
	static void colorToRGB(int color) {
		r = (color >> 16) & 0xFF;
		g = (color >> 8) & 0xFF;
		b = color & 0xFF;
	}
	
	/**
	 * 将RGB转为十六进制的十进制形式
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 红色值
	 * @param g 绿色值
	 * @param b 蓝色值
	 * @return 十进制
	 */
	static int rgbToColor(int r,int g,int b) {
		//完全不透明
		int color = 255 << 24; 
		//rgb添加上 255 一位
		color += r << 16;
		color += g << 8;
		color += b;
		return color;
	}
	
	public static void main(String[] args) throws FileNotFoundException, IOException {
		//获取到图片
		BufferedImage image = ImageIO.read(new FileInputStream("F:/Test/ali_test.png"));
		int width = image.getWidth();
		int height = image.getHeight();
		//对每个像素点进行操作
		for (int y = 0;y < height;y++) {
			for (int x = 0;x < width;x++) {
				int color = image.getRGB(x, y);
				//获取rgb
				colorToRGB(color);
				//处理颜色
				//分量处理
//				color = flcl(r,g,b);
//				//最大值处理
//				color = getMax(r,g,b);
//				//平均法
//				color = averageRGB(r,g,b);
				//加权法
				color = weightRGB(r,g,b);
				//设置颜色
				image.setRGB(x,y,color);
			}
		}
		//处理后的图片进行输出
		ImageIO.write(image, "png", new FileOutputStream("F:/Test/test.png"));
	}
	
	/**
	 * 分量处理图像
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int flcl(int r,int g,int b) {
		g = r;
		b = r;
		return rgbToColor(r, g, b);
	}
	
	/**
	 * 取最大值处理图像
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int getMax(int r,int g,int b) {
		int temp = r > g ? (r > b ? r : b) : (g > b ? g : b);
		return rgbToColor(temp,temp,temp);
	}
	
	/**
	 * 均值法
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int averageRGB(int r,int g,int b) {
		int temp = (r+g+b) / 3;
		return rgbToColor(temp,temp,temp);
	}
	
	/**
	 * 加权法
	 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>
	 * @param r 要处理的像素点的R值
	 * @param g 要处理的像素点的G值
	 * @param b 要处理的像素点的B值
	 * @return 处理后的颜色
	 */
	static int weightRGB(int r,int g,int b) {
		int temp = (int) (0.3 * r + 0.59 * g + 0.11 * b);
		return rgbToColor(temp,temp,temp);
	}
	
}
原创文章 55 获赞 64 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41806966/article/details/105819858