南通大学计算机科学与技术学院《数字图像处理》课程实验报告书实验名BMP文件的读写(8位和24位)班级计121姓名张进学号12130220162014年6月16日一、实验内容1、了解BMP文件的结构2、8位位图和24位位图的读取二、BMP图形文件简介BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运行的所有图象处理软件都支持BMP图象文件格式。Windows系统内部各图像绘制操作都是以BMP为基础的。Windows3.0以前的BMP图文件格式与显示设备有关,因此把这种BMP图象文件格式称为设备相关位图DDB(device-dependentbitmap)文件格式。Windows3.0以后的BMP图象文件与显示设备无关,因此把这种BMP图象文件格式称为设备无关位图DIB(device-independentbitmap)格式(注:Windows3.0以后,在系统中仍然存在DDB位图,象BitBlt()这种函数就是基于DDB位图的,只不过如果你想将图像以BMP格式保存到磁盘文件中时,微软极力推荐你以DIB格式保存),目的是为了让Windows能够在任何类型的显示设备上显示所存储的图象。BMP位图文件默认的文件扩展名是BMP或者bmp(有时它也会以.DIB或.RLE作扩展名)。位图文件可看成由4个部分组成:位图文件头(bitmap-fileheader)、位图信息头(bitmap-informationheader)、彩色表(colortable)和定义位图的字节阵列,它具有如下所示的形式。位图文件的组成结构名称符号位图文件头(bitmap-fileheader)BITMAPFILEHEADERbmfh位图信息头(bitmap-informationheader)BITMAPINFOHEADERbmih彩色表(colortable)RGBQUADaColors[]图象数据阵列字节BYTEaBitmapBits[]位图文件结构内容摘要偏移量域的名称大小内容图象文件头0000h文件标识2bytes两字节的内容用来识别位图的类型:‘BM’:Windows3.1x,95,NT,…‘BA’:OS/2BitmapArray‘CI’:OS/2ColorIcon‘CP’:OS/2ColorPointer‘IC’:OS/2Icon‘PT’:OS/2Pointer注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识“BM”就行。0002hFileSize1dword用字节表示的整个文件的大小0006hReserved1dword保留,必须设置为0000AhBitmapDataOffset1dword从文件开始到位图数据开始之间的数据(bitmapdata)之间的偏移量000EhBitmapHeaderSize1dword位图信息头(BitmapInfoHeader)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示:28h-Windows3.1x,95,NT,…0Ch-OS/21.xF0h-OS/22.x注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。0012hWidth1dword位图的宽度,以象素为单位0016hHeight1dword位图的高度,以象素为单位001AhPlanes1word位图的位面数(注:该值将总是1)图象信息头001ChBitsPerPixel1word每个象素的位数1-单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)4-16色位图8-256色位图16-16bit高彩色位图24-24bit真彩色位图32-32bit增强型真彩色位图001EhCompression1dword压缩说明:0-不压缩(使用BI_RGB表示)1-RLE8-使用8位RLE压缩方式(用BI_RLE8表示)2-RLE4-使用4位RLE压缩方式(用BI_RLE4表示)3-Bitfields-位域存放方式(用BI_BITFIELDS表示)0022hBitmapDataSize1dword用字节数表示的位图数据的大小。该数必须是4的倍数0026hHResolution1dword用象素/米表示的水平分辨率002AhVResolution1dword用象素/米表示的垂直分辨率002EhColors1dword位图使用的颜色数。如8-比特/象素表示为100h或者256.0032hImportantColors1dword指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要调色板数据根据BMP版本的不同而不同PaletteN*4byte调色板规范。对于调色板中的每个表项,这4个字节用下述方法来描述RGB的值:1字节用于蓝色分量1字节用于绿色分量1字节用于红色分量1字节用于填充符(设置为0)图象数据根据BMP版本及调色板尺寸的不同而不同BitmapDataxxxbytes该域的大小取决于压缩方法及图像的尺寸和图像的位深度,它包含所有的位图数据字节,这些数据可能是彩色调色板的索引号,也可能是实际的RGB值,这将根据图像信息头中的位深度值来决定。三、读写涉及的原理1、图像的二值化的基本原理图像的二值化处理就是讲图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。2、图像的反色原理对于彩色图像的R、G、B各彩色分量取反的技术就是图像的反色处理,这在处理二值化图像的连通区域选取的时候非常重要。如物体连通域用黑色表示,而二值化后的物体连通域图像可那是白色的,而背景是黑色的,这时应手动选取图像的反色处理或有程序根据背景和物体连通域两种颜色的数量所占比例而自动选择是否选择选取图像的反色处理四、读写转换代码#includemath.h#includeiomanip.h#includestdlib.h#includewindows.h#includestdio.h#includestdlib.h#includeiostream.h#includefstream.h//---------------------------------------------------------------------------------------//以下该模块是完成BMP图像(彩色图像是24bitRGB各8bit)的像素获取,并存在文件名为xiang_su_zhi.txt中unsignedchar*pBmpBuf;//读入图像数据的指针intbmpWidth;//图像的宽intbmpHeight;//图像的高RGBQUAD*pColorTable;//颜色表指针intbiBitCount;//图像类型,每像素位数//-------------------------------------------------------------------------------------------//读图像的位图数据、宽、高、颜色表及每像素位数等数据进内存,存放在相应的全局变量中boolreadBmp(char*bmpName){FILE*fp=fopen(bmpName,rb);//二进制读方式打开指定的图像文件if(fp==0)return0;//跳过位图文件头结构BITMAPFILEHEADERfseek(fp,sizeof(BITMAPFILEHEADER),0);//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中BITMAPINFOHEADERhead;fread(&head,sizeof(BITMAPINFOHEADER),1,fp);//获取图像宽、高、每像素所占位数等信息bmpWidth=head.biWidth;bmpHeight=head.biHeight;biBitCount=head.biBitCount;//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)intlineByte=(bmpWidth*biBitCount/8+3)/4*4;//灰度图像有颜色表,且颜色表表项为256if(biBitCount==8){//申请颜色表所需要的空间,读颜色表进内存pColorTable=newRGBQUAD[256];fread(pColorTable,sizeof(RGBQUAD),256,fp);}//申请位图数据所需要的空间,读位图数据进内存pBmpBuf=newunsignedchar[lineByte*bmpHeight];fread(pBmpBuf,1,lineByte*bmpHeight,fp);fclose(fp);//关闭文件return1;//读取文件成功}//-----------------------------------------------------------------------------------------//给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,将其写到指定文件中boolsaveBmp(char*bmpName,unsignedchar*imgBuf,intwidth,intheight,intbiBitCount,RGBQUAD*pColorTable){//如果位图数据指针为0,则没有数据传入,函数返回if(!imgBuf)return0;//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0intcolorTablesize=0;if(biBitCount==8)colorTablesize=1024;//待存储图像数据每行字节数为4的倍数intlineByte=(width*biBitCount/8+3)/4*4;//以二进制写的方式打开文件FILE*fp=fopen(bmpName,wb);if(fp==0)return0;//申请位图文件头结构变量,填写文件头信息BITMAPFILEHEADERfileHead;fileHead.bfType=0x4D42;//bmp类型//bfSize是图像文件4个组成部分之和fileHead.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTablesize+lineByte*height;fileHead.bfReserved1=0;fileHead.bfReserved2=0;//bfOffBits是图像文件前3个部分所需空间之和fileHead.bfOffBits=54+colorTab