图像处理中的彩色图像处理
在计算机图形学与图像处理中,数字图像的灰度是进行图像识别与处理的基础。我们往往需要先读取数字图像的灰度,然后对其进行分析与处理,如生成灰度直方图、灰度修正、提取图像特征、图像锐化等。本文介绍在Visual J++ 6.0中读取数字图像灰度的方法,以及在此基础上,对图像进行比例变换、灰度取反、生成灰度直方图及对直方图进行均衡化修正等操作。
数字图像在计算机上以位图(bitmap)的形式存在,位图是一个矩形点阵,其中每一点称为像素(pixel),像素是数字图像中的基本单位。一幅m×n大小的图像,是由m×n个明暗度不等的像素组成的。数字图像中各个像素所具有的明暗程度由灰度值(gray level)所标识。一般将白色的灰度值定义为255,黑色灰度值定义为0,而由黑到白之间的明暗度均匀地划分为256个等级。对于黑白图像,每个像素用一个字节数据来表示,而在彩色图像中,每个像素需用三个字节数据来表述。彩色图像可以分解成红(R)、绿(G)、蓝(B)三个单色图像,任何一种颜色都可以由这三种颜色混合构成。在图像处理中,彩色图像的处理通常是通过对其三个单色图像分别处理而得到的。
?
彩色图像亮度值的读取
?
彩色图像的亮度值由红、绿、蓝三个分量共同决定,因此,读取彩色图像的亮度实际上是读取其中每个像素的R、G、B值。Visual J++ 6.0的java.awt.image包中定义了一个重要的类ColorModel,它是用来描述数字图像中像素点的。其中getRed( int pixel )、 getGreen(int pixel)、 getBlue(int pixel)函数分别读取像素的R、G、B值(整型)。
我们不妨设ImageWidth 、ImageHeight分别为图像的宽度与高度值,令PixelsSource=ImageWidth×ImageHeigh,即图像的像素个数,则读取彩色图像RGB值的函数代码如下:
public void GetImageRGB(int[] ImageSource,int[] ImageDestination)
{
//得到默认的颜色模型
ColorModel colorModel=ColorModel.getRGBdefault();
int i ,j,k,r,g,b;
for(i = 0; i < ImageHeight;i++)
{
for(j = 0;j < ImageWidth;j++)
{
//定位像素点
k = i * ImageHeight+j;
r = colorModel.getRed(ImageSource[k]);
g = colorModel.getGreen(ImageSource[k]);
b = colorModel.getBlue(ImageSource[k]);
ΔΔΔ//此处可添加对R、G、B值进行调整的代码
//将R、G值左移,并保存RGB值
ImageDestination[k] =0xFF000000 | (( r
<< 16 ) | ( g << 8 ) | b );
}
}
}
如果要将彩色图像转换为灰度图像,则先使用如下灰度变换公式:
int gray=r*0.3+g*0.59+b*0.11;
然后,令r=g=b=gray即可。
?
读取黑白图像灰度值
?
黑白图像灰度值的读取比较简单,只需读取R分量的值:
int gray=getRed( int pixel );
?
图像处理
?
1.比例变换
比例变换就是将图像的亮度或灰度乘以某一系数,以达到增强或减弱图像亮度或灰度的目的。在计算过程中要注意灰度值的变化范围(0~255)。
可在上述代码ΔΔΔ处加入以下语句:
//变换比例
float Scale=1.2f;
r=(int)(r*Scale);
g=(int)(g*Scale);
b=(int)(b*Scale);
r=(r<0)?0:((r>255)?255:r);
g=(g<0)?0:((g>255)?255:g);
b=(b<0)?0:((b>255)?255:b);
2.灰度取反
灰度取反运算很简单,只需用255减去原灰度值即可:
r=255-r;
g=255-g;
b=255-b;
3.灰度直方图处理
直方图表示的是图像中每一灰度级与其出现频数之间的统计关系,用横坐标表示灰度级,纵坐标表示频数。直方图能反映出图像的灰度范围、每个灰度级的频数、灰度分布情况、整幅图像的亮度等,它是对图像进行处理的重要依据。如对直方图进行均衡化修正,可使图像的灰度间距增大或灰度均匀分布、增大反差,使图像的细节变得清晰。均衡化修正的基本思想是将出现频数较少的灰度级并入邻近的灰度级中,从而减少图像的灰度等级,增加其对比度。
public void EquilibrateGray(int[] ImageSource,int[] ImageDestination)
{
ColorModel colorModel=ColorModel.getRGBdefault();
int i ,j,r,g,b,gray;
int PixelsGray[]=new int[PixelsSource];
int FrequenceGray[]=new int[PixelsSource];
int SumGray[]=new int[256];
for(i = 0; i <PixelsSource ;i++)
{
r = colorModel.getRed(ImageSource[i]);
g = colorModel.getGreen(ImageSource[i]);
b = colorModel.getBlue(ImageSource[i]);
gray=r*0.3+g*0.59+b*0.11;
PixelsGray[i]=gray;
FrequenceGray[gray]++;
}
//灰度均衡化
SumGray[0]=FrequenceGray[0];
For(i=1;i<256;i++)
//灰度级频度数累加
SumGray[i]=SumGray[i-1]+FrequenceGray[i];
For(i=0;i<256;i++)
//计算调整灰度值
SumGray[i]=(int)(SumGray[i]*255/PixelsSource);
//灰度值变换
for(i=0;i<ImageHeight;i++)
{
for(j=0;j<ImageWidth;j++)
{
k=i*IamgeHeight+j;
r=g=b=SumGray[pixelsGray[k]];
ImageDestination[k]=0xFF000000 | (( r <<
16 ) | ( g << 8 ) | b );
}
}
}