论文部分内容阅读
[摘要]介绍了使用QT对BMP图像进行灰度化处理的相关概念和方法。根据BMP格式图像的格式类型和存储原理,介绍对BMP格式图像进行读取和写入方法,并在此基础上介绍了对BMP图片进行灰度化的方法。
[关键词]数字图像;灰度化处理;QT;C++;位图
大家生活中很多情况下需要将一张彩色的图片转变成黑白的图片,也就是灰度图,但是大部分人都是直接使用PS或美图秀秀这些图片处理的软件进行,而对图片灰度化的过程不是十分了解甚至一无所知。很多时候我们需要把彩色图像转换为黑白图像然后进行相关的计算等。而QT的界面设计使得开发带界面的软件更为方便,且可用C++语言编写,运行效率高,执行速度快,适合图像处理。因此用QT开发一款图像灰度化的处理程序十分方便也能帮助我们理解灰度化的原理和过程。
1、灰度化原理
生活中,我们见到的大部分物品都是彩色的,我们生活在一个五颜六色的世界中,我们通常用来描述一个物体的颜色的诸如赤、橙、黄、绿、青、蓝、紫这些颜色名词有很多,但是即使是这样,仍然不能涵盖自然界的所有颜色或者说即使用这些词来描述一个物体的颜色仍旧不能描述得很准确。其实每一种复杂的颜色都是可以用红绿蓝这三种颜色按照不同的比例调配出来的,所以不同的颜色种类根据三种颜色所占比例的不同是不同的,数量是非常大的。
同样,不同的色光还有不同的亮度,同样是红色,有的比较亮,有的比较暗。由此可见,颜色是无穷无尽的,那黑白图像又是怎么一回事呢?图像的灰度化的原理又是什么呢。
其实图像灰度化就是根据公示计算出每个像素点的亮度,从而直接用亮度来表示图片,而不是用以前的R(红)、G(绿)、B(蓝)值。计算公示如下:
这是一个矩阵计算公示,公式中的Y就是亮度值,实际上就是通过原像素点的红绿蓝的值计算出亮度值。通常灰度图的数据用8位进行存储,这样的图片灰度有256级,也就是说这种灰度化的图片中包含256中不同亮度的像素点,255是白色,0是黑色,中间是不同程度的灰色。
而对于不同位数的BMP图像的灰度化过程也是不同的。
对于24位的BMP图像只需要通过公式 Y=0.299R+0.587G+0.144B计算出各像素点的亮度值,然后将亮度值附给该点的RGB值即R=B=G=Y就行了。
而对于其他位数的灰度化也有两种方法。如对于8位的BMP图像
Ⅰ.获取第一个颜色表项中的RGB值,然后利用公式Y=0.299R+0.587G+0.144B计算出该颜色的亮度值Y,并令该颜色表项的RGB值都等于此亮度值Y。同理,再完成对剩余所有颜色表项的处理,便可实现灰度化。
Ⅱ.在8位BMP文件的位图数据中,首先获取任意第i行,第j列像素点的颜色表索引值index,根据该索引值找到与其对应的颜色表项color[index],并获取该颜色表项的RGB值,然后利用公式Y=0.299R+0.587G+0.144B计算出该颜色的亮度值Y,再令index=Y;在完成上述處理之后,再对颜色表项按顺序灰度化,即color[index]的R=G=B=index。至此,8位BMP文件的位图数据就表示每个像素真实的亮度值。这里介绍的示例程序采用上述方法ii实现灰度化。
2、程序设计步骤
程序是基于QT设计的,使用C++编程语言,所以设计过程包括界面设计和程序设计思路。
2.1程序界面设计
程序需要用户输入数据,故设计用户数据接口即可。
2.2程序流程设计
程序设计的实现过程为:
(1)读取BMP文件的文件头、信息头、颜色表、像素点数据等位图数据。
其中QT中封装的获得文件名代码如下:
namebmp=QFileDialog::getOpenFileName(this,"打开bmp文件","/","files(*.bmp)");//获得bmp文件名
(2)根据灰度化原理进行处理,
对8比特的BMP图片进行灰度化的代码如下:
for(inti=0;i {
for(intj=0;j {
index=data[i][j];
////////24bit
if(Bitmapinfoheader.biBitCount==24)
{
doubley3=0.299*data[i][j*3]+0.587*data[i][3*j+1]+0.114*data[i][3*j+2];
inty4=(int)((y3+0.5)*10/10.0);
if(ui->checkBox->isChecked())
y4=255;
data[i][j*3]=y4;
data[i][j*3+1]=y4;
data[i][j*3+2]=y4;
}
////////8bit
if(Bitmapinfoheader.biBitCount==8)
y0=0.299*Rgbquad[index].rgbRed+0.587*Rgbquad[index].rgbGreen+0.114*Rgbquad[index].rgbBlue;
(3)将新图片数据写到新文件中。
///////写新文件
FILE*fp1;
fp1=fopen((dir1+"/"+name1).toStdString().c_str(),"wb");
fwrite(&Bitmapfileheader,14,1,fp1);
fwrite(&Bitmapinfoheader,40,1,fp1);
///////8bit
if(Bitmapinfoheader.biBitCount==8)
{
fwrite(Rgbquad,4*colornum,1,fp1);
for(intn=0;n fwrite(data[n],w1,1,fp1);
}
3、程序测试实验
本实验用的是500乘500的8位BMP格式的彩色图像。
灰度化结果如图2所示
4、其他
这里只介绍了8比特彩色图像的灰度化,在进行4比特图像的灰度化的过程中时要注意数据部分中,每个字节中包含两个像素的索引值,每次读出一个字节后需要进行处理。
[关键词]数字图像;灰度化处理;QT;C++;位图
大家生活中很多情况下需要将一张彩色的图片转变成黑白的图片,也就是灰度图,但是大部分人都是直接使用PS或美图秀秀这些图片处理的软件进行,而对图片灰度化的过程不是十分了解甚至一无所知。很多时候我们需要把彩色图像转换为黑白图像然后进行相关的计算等。而QT的界面设计使得开发带界面的软件更为方便,且可用C++语言编写,运行效率高,执行速度快,适合图像处理。因此用QT开发一款图像灰度化的处理程序十分方便也能帮助我们理解灰度化的原理和过程。
1、灰度化原理
生活中,我们见到的大部分物品都是彩色的,我们生活在一个五颜六色的世界中,我们通常用来描述一个物体的颜色的诸如赤、橙、黄、绿、青、蓝、紫这些颜色名词有很多,但是即使是这样,仍然不能涵盖自然界的所有颜色或者说即使用这些词来描述一个物体的颜色仍旧不能描述得很准确。其实每一种复杂的颜色都是可以用红绿蓝这三种颜色按照不同的比例调配出来的,所以不同的颜色种类根据三种颜色所占比例的不同是不同的,数量是非常大的。
同样,不同的色光还有不同的亮度,同样是红色,有的比较亮,有的比较暗。由此可见,颜色是无穷无尽的,那黑白图像又是怎么一回事呢?图像的灰度化的原理又是什么呢。
其实图像灰度化就是根据公示计算出每个像素点的亮度,从而直接用亮度来表示图片,而不是用以前的R(红)、G(绿)、B(蓝)值。计算公示如下:
这是一个矩阵计算公示,公式中的Y就是亮度值,实际上就是通过原像素点的红绿蓝的值计算出亮度值。通常灰度图的数据用8位进行存储,这样的图片灰度有256级,也就是说这种灰度化的图片中包含256中不同亮度的像素点,255是白色,0是黑色,中间是不同程度的灰色。
而对于不同位数的BMP图像的灰度化过程也是不同的。
对于24位的BMP图像只需要通过公式 Y=0.299R+0.587G+0.144B计算出各像素点的亮度值,然后将亮度值附给该点的RGB值即R=B=G=Y就行了。
而对于其他位数的灰度化也有两种方法。如对于8位的BMP图像
Ⅰ.获取第一个颜色表项中的RGB值,然后利用公式Y=0.299R+0.587G+0.144B计算出该颜色的亮度值Y,并令该颜色表项的RGB值都等于此亮度值Y。同理,再完成对剩余所有颜色表项的处理,便可实现灰度化。
Ⅱ.在8位BMP文件的位图数据中,首先获取任意第i行,第j列像素点的颜色表索引值index,根据该索引值找到与其对应的颜色表项color[index],并获取该颜色表项的RGB值,然后利用公式Y=0.299R+0.587G+0.144B计算出该颜色的亮度值Y,再令index=Y;在完成上述處理之后,再对颜色表项按顺序灰度化,即color[index]的R=G=B=index。至此,8位BMP文件的位图数据就表示每个像素真实的亮度值。这里介绍的示例程序采用上述方法ii实现灰度化。
2、程序设计步骤
程序是基于QT设计的,使用C++编程语言,所以设计过程包括界面设计和程序设计思路。
2.1程序界面设计
程序需要用户输入数据,故设计用户数据接口即可。
2.2程序流程设计
程序设计的实现过程为:
(1)读取BMP文件的文件头、信息头、颜色表、像素点数据等位图数据。
其中QT中封装的获得文件名代码如下:
namebmp=QFileDialog::getOpenFileName(this,"打开bmp文件","/","files(*.bmp)");//获得bmp文件名
(2)根据灰度化原理进行处理,
对8比特的BMP图片进行灰度化的代码如下:
for(inti=0;i
for(intj=0;j
index=data[i][j];
////////24bit
if(Bitmapinfoheader.biBitCount==24)
{
doubley3=0.299*data[i][j*3]+0.587*data[i][3*j+1]+0.114*data[i][3*j+2];
inty4=(int)((y3+0.5)*10/10.0);
if(ui->checkBox->isChecked())
y4=255;
data[i][j*3]=y4;
data[i][j*3+1]=y4;
data[i][j*3+2]=y4;
}
////////8bit
if(Bitmapinfoheader.biBitCount==8)
y0=0.299*Rgbquad[index].rgbRed+0.587*Rgbquad[index].rgbGreen+0.114*Rgbquad[index].rgbBlue;
(3)将新图片数据写到新文件中。
///////写新文件
FILE*fp1;
fp1=fopen((dir1+"/"+name1).toStdString().c_str(),"wb");
fwrite(&Bitmapfileheader,14,1,fp1);
fwrite(&Bitmapinfoheader,40,1,fp1);
///////8bit
if(Bitmapinfoheader.biBitCount==8)
{
fwrite(Rgbquad,4*colornum,1,fp1);
for(intn=0;n
}
3、程序测试实验
本实验用的是500乘500的8位BMP格式的彩色图像。
灰度化结果如图2所示
4、其他
这里只介绍了8比特彩色图像的灰度化,在进行4比特图像的灰度化的过程中时要注意数据部分中,每个字节中包含两个像素的索引值,每次读出一个字节后需要进行处理。