RGB彩色图像分量提取(java实现)

引文

生活中最常见的RGB图像,比如手机照片,即为标准的三通道24位深RGB图像。 冈萨雷斯和伍兹所著的《数字图像处理》第二版中给出如下定义:一幅RGB图像,可以看作是一个MN3的彩色像素数组,其中每个彩色像素是一个三值组,这三个值分别对应特定空间位置处该RGB图像的红、绿、蓝分量。RGB也可以视为三幅灰度图像形成的“堆叠”,当它们送到彩色显示器时,会**按照一定规则进行组合,并在屏幕上生成一幅彩色图像。因此,按照此约定,我们把形成RGB彩色图像的三幅图像称为红色、绿色、蓝色分量图像。接下来要探讨的便是:如何通过这个规则进行逆变换,实现对RGB彩色图像的分量图像提取。

正文

一、RGB彩色图像简析

在引文部分中已经将RGB图像解释得特别清楚了,在此也可以将RGB图像理解为:
RGB图像是红、绿、蓝三波段图像,按一定规则的叠加得到的新的图像,即:通过对Red红,Green绿,Blue蓝三个通道进行量化,叠加得到一个像素的彩色。在此,核心问题是:这个“堆叠”规则是什么?

先来看一个如下的彩色空间坐标系,可将其初步解读为:在RGB彩色空间模型中,任意空间位置坐标(R,G,B)分量R、G、B按照规则搭配后组成一种颜色。
RGB彩色立方体
很显然,R、G、B对应的即是在引文中提到的红色、绿色、蓝色分量图像像素值。

二、彩色图像分量值

接下来,我们看一下已经提取出来的红色、绿色、蓝色波段分量图像和原RGB图像的区别。

以下为:正常图像分离出来的R(红色)、G(绿色)、B(蓝色)三波段的图像。
红色通道分量图像
绿色通道分量图像
绿色通道分量图像
以下为正常的RGB彩色图像:
在这里插入图片描述
至此,我们对RGB图像以及它的分量图像便有了直观的视觉感受,那么:分量图是如何“堆叠”成为RGB图呢?
(1)先要对一个彩色像素值对应的R、G、B分量在内存中分布进行初步认识。
RGB描述
如图:结合RGB图像是3字节,24位深的属性,我们将三个格子视为三个连续字节,即:24位长的存储空间,其中:R所占的位置(共8个字节)用来存放红色分量图的像素值;G所占的位置(共8个字节)用来存放绿色分量图的像素值;B所占的位置(共8个字节)用来存放蓝色分量图的像素值。
(2)那么,问题来了:我们常规思维理解的是只要将代表色彩分量的值(0-255px)直接放在对应位置就好了,但是计算机是一个将一切事物量化存储的系统,它并不认识按照人类思维存放进去的值到底是什么,因此,这里的R、G、B分量存放时,实际上存在一个位运算的过程,即:
R分量将通过左移(16位)运算放到高8位上,G分量通过左移(8位)运算放到中8位上,B分量直接放置到低8位上,由此:我们可以预知,平时我们看到的,或者是通过matlab直接读取出来的像素值,是将R、G、B分量值进行位运算后得到的结果。(当然:计算机里面存储的都是实际数值的补码,关于数值原码、反码、补码的知识,将不在此进行赘述)
由此,可以认识到:只要将对应的红、绿、蓝波段值赋予一张新的图像,并且存放在对应位置上,就可以实现RGB彩色图像的分量提取。
(3)关于RGB分量提取算法,实质上就是对原彩色像素值的位运算。
在java中,可以通过getRGB()方法获取一张图像的彩色像素值,在此假设用预定义的public,int型变量RGB_value来接收此彩色像素值,那么:

r_value=this.RGB_value>>16;
g_value=this.RGB_value>>8;
b_value=this.RGB_value;

对于R、G、B分量值的附加,即:进行相应像素值的相反位运算,将不再进行赘述。

三、java编程实现:RGB图像彩色分量提取

			//定义用来存放RGB图像分量图的image对象(下面用到的this.image是已经预读取来的RGB原图像)
			BufferedImage this.image_R=new BufferedImage(this.width,this.height,BufferedImage.TYPE_INT_RGB);
            BufferedImage this.image_G=new BufferedImage(this.width,this.height,BufferedImage.TYPE_INT_RGB);
            BufferedImage this.image_B=new BufferedImage(this.width,this.height,BufferedImage.TYPE_INT_RGB);
            //单色通道提取
            for (int height=0;height<this.height;height++)
            {
                for (int width=0;width<this.width;width++)
                {
                    this.RGB_value=this.image.getRGB(width,height);//获取方式
                   this.rgb_value[0]=(this.RGB_value&0xff0000)>>16;//红色波段
                   this.rgb_value[1]=(this.RGB_value&0xff00)>>8;//绿色波段
                   this.rgb_value[2]=(this.RGB_value&0xff);//蓝色波段
                    this.image_R.setRGB(width,height,this.rgb_value[0]<<16);
                    this.image_G.setRGB(width,height,this.rgb_value[1]<<8);
                    this.image_B.setRGB(width,height,this.rgb_value[2]);
                }
            }
            //图像输出
            ImageIO.write(this.image_R,"jpg", new File("C:\\Users\\13241\\Desktop\\WorkPlace\\image_R.jpg"));
            ImageIO.write(this.image_G,"jpg", new File("C:\\Users\\13241\\Desktop\\WorkPlace\\image_G.jpg"));
            ImageIO.write(this.image_B,"jpg", new File("C:\\Users\\13241\\Desktop\\WorkPlace\\image_B.jpg"));

结语

至此,关于通过java实现RGB彩色图像分量提取的内容就结束了。因为刚接触对彩色图像的处理,所以还有很多不足,请大家多多指正。谢谢!

  • 2
    点赞
  • 1
    评论
  • 16
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值