代码改变世界

图像结构的认识

2011-09-25 09:53  ubunoon  阅读(498)  评论(0编辑  收藏  举报

一、图像分类

      目前图像主要分为两类,矢量图位图图像,矢量图的最大好处是图形不会随着图像尺寸的变化而变化,最近比较火的应用是svg(在浏览器中直接显示的矢量图),缺点是很难表示复杂图形,位图图像应用相对更加广泛,也更加直观,直接用RGB等数据来表示图形,缺点是图像占据空间很大,尺寸变化时图像数据丢失。对于图像的识别和处理,一般都是位图图像,而位图图像中最重要最直观的莫如BMP图像

 

二、位图图像结构

位图图像通常被已知格式存储为一个以.BMP为后缀的文件。位图图像结构分为四部分,第一部分是文件格式(严格来说不属于图像),第二部分是图像格式,第三部分为调色板,第四部分是图像数据

 

典型的BMP结构如下:

 

结构

对应字节

BITMAPFILEHEADER

0X00-0X0D,(0-13)

BITMAPINFOHEADER

0x0E-0x31,(14-49)

RGBQUAD

0x32-0x75,(50-117)

颜色素引阵列

0x76-(118-结束)

 

1、位图文件头

 

位图文件头,主要是用来读对位图进行文件读写(保存)时使用,一般情况下,在内存进行图像处理时,都是从位图信息头开始。

 

在MSDN上 BITMAPFILEHEADER上的定义如下:

typedef struct tagBITMAPFILEHEADER { // bmfh 
    WORD    bfType; 
    DWORD   bfSize; 
    WORD    bfReserved1; 
    WORD    bfReserved2; 
    DWORD   bfOffBits; 
} BITMAPFILEHEADER; 
 

其中各个字段含义如下:

 

字 段 名

大小(单位:字节)

描 述

bfType

2

位图类别,根据不同的操作系统而不同,在Windows

中,此字段的值总为‘BM’,十六进制值为:0x4D42,注意第一个字节为0x42,第二个字节为0x4D

bfSize

4

BMP图像文件的大小

bfReserved1

2

总为0

bfReserved2

2

总为0

bfOffBits

4

BMP图像数据的地址

 

bfSize = bfOffBits + BITMAPINFOHEADER.biSizeImage;

bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof(BITMAPINFOHEADER) + 调色板长度;

 

2、位图信息头

位图信息头包含了位图信息头的大小,图像的宽和高,图像的色深,压缩说明等,注意,此处才是实际使用的图像格式。

MSDN上定义如下:

typedef struct tagBITMAPINFOHEADER{ // bmih 
    DWORD  biSize; 
    LONG   biWidth; 
    LONG   biHeight; 
    WORD   biPlanes; 
    WORD   biBitCount 
    DWORD  biCompression; 
    DWORD  biSizeImage; 
    LONG   biXPelsPerMeter; 
    LONG   biYPelsPerMeter; 
    DWORD  biClrUsed; 
    DWORD  biClrImportant; 
} BITMAPINFOHEADER; 

 

其中各个字段含义如下:

字 段 名

大小(单位:字节)

描 述

biSize 

4

本结构的大小,根据不同的操作系统而不同,在Windows中,此字段的值总为0x28字节=40字节,一般用 sizeof(BITMAPINFOHEADER)来表示。

biWidth

4

BMP图像文件的宽度,单位像素

biHeight 

4

BMP图像文件的高度,单位像素

biPlanes 

2

总为0

biBitCount 

2

BMP图像的色深,即一个像素用多少位表示,常见有148162432,分别对应单色、16色、256色、16为高彩色、24位真彩色和32为增强型真彩色

biCompression 

4

压缩方式,0表示不压缩(BI_RGB)1表示RLE8压缩(BI_RLE8),2表示RLE4BI_RLE4)压缩,3表示每个像素值由指定的掩码决定

biSizeImage 

4

BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足,因为4的倍数关系,会导致biWidth不是实际像素的宽度

biXPelsPerMeter 

4 

水平分辨率,单位像素/m ,一般为072

biYPelsPerMeter 

4

垂直分辨率,单位像素/m 

biClrUsed 

4

BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为0x100=256 

biClrImportant 

4

重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色 

 

3、调色板

调色板一般是单色、16色、256色、16为高彩色等图像文件所特有的,相对应的调色板大小是2、16、256、16,调色板以4个字节为单位,每4个字节存放一定的数据值,对于非真彩色的图像来说,图像数据是指向调色板的索引。调色板在程序编写中,可以将其作为数组来表示,每个数组元素大小为4个字节。

 

在早期的计算机中,显卡比较落后,不一定能够显示所有颜色,因此在调色板中的颜色数据应尽可能将图像中主要的颜色按顺序排列在前面,位图信息头的biClrImportant字段指明有多少中颜色是重要的。因此在目前的计算机体系中,biClrImportant值大部分设置为0.

 

在MSDN上RGBQUAD的定义如下:

typedef struct tagRGBQUAD { // rgbq 
    BYTE    rgbBlue; 
    BYTE    rgbGreen; 
    BYTE    rgbRed; 
    BYTE    rgbReserved; 
} RGBQUAD; 
 
其中各个字段含义如下:

字 段 名

大小(单位:字节)

描 述

rgbBlue 

1

蓝色值

rgbGreen 

1

绿色值

rgbRed 

1

红色值

rgbReserved 

1

保留,一般为0,在RGBA颜色体系中(即32位真彩色)该值表示透明色,用Alpha来表示,因此也可以认为0是不透明,而255是完全透明

 

从上面也可以看到,每一种颜色需要4个字节来表示,使用调色板的好处是,位图数据用指向调色板的索引来表示具体的数据,这样就可以用1个字节甚至更少的位来表示一种颜色(单色图用位来表示),从而极大的减少了BMP图像的尺寸,在DOS时代,这个硬盘都是寸字节寸金的情况,这个措施非常必要,并且从程序处理角度上看,这样的处理也十分方便。

 

4、位图数据

如果位图是单色、16色和256色,则紧跟着调色板的是位图数据,位图数据时指向调色板的索引号。

如果位图是16位、24位和32位彩色图,则图像中不保留调色板,即不存在调色板,图像的颜色数据直接在位图数据中给出。

 

上面的区分对于程序编写而言,是一个很大的挑战,对于不同的格式,需要动态去判断调色板的大小。

 

位图数据的颜色数目通过位图信息头中的biBitCount 来表明

对于灰度和黑白图像:

单色:biBitCount =1 ,使用一位来表示一个颜色,颜色通过调色板来对应。调色板数据,用0表示白色,1表示黑色,

16位灰度图:biBitCount = 4,使用4位来表色一个颜色值

256灰度图:biBitCount=256,用1个字节来表示一个颜色值

 

对于彩色图像

16位图像使用2字节保存颜色值,常见有两种格式:5位红 5位绿 5位蓝和5位红 6位绿 5位蓝,即555格式和565格式,555格式值使用了15位,最后一位保留,设置为0.

24位位图使用3字节保存颜色值,每一个字节代表一种颜色,按红、绿、蓝排列

32位图像使用4字节来保存颜色值,每一个字节代表一种颜色,即红、绿、蓝和Alpha通道(透明色)

 

一般目前将JPEG、PNG等主流格式解压缩后,主要为单色、256灰度图,24位真彩色和32位真彩色,对于图像数据识别中,最重要的就是单色、256灰度图和24为真彩色,因此接下来的处理主要是这三种颜色的图像处理。