本帖最后由 jinyi7016 于 2016-3-27 21:02 编辑
一个bmp图片最多由4大部分组成: BITMAPFILEHEADER结构体 BITMAPINFOHEADER结构体 RGBQUAD结构体(这个结构体可以有,也可以没有) DIB数据区。其中DIB意思就是Device-Independent Bitmap(设备无关位图)
第一个像素点在左下,从左到右,从下到上,扫描。 通过画图查看图片第一像素点:
与在WinHex中看到的第一像素的值是一样的。
由上可以看出,BMP图片的数据区,真实的色彩顺序并不是RGB而是BGR,所以定义每个像素点的结构体为:
- typedef struct
- {
- unsigned char Blue; // 蓝色分量
- unsigned char Green; // 绿色分量
- unsigned char Red; // 红色分量
- } tagRGB24;
复制代码
根据bmp文件的结构,定义bmp文件的结构体为:
- typedef struct
- {
- BITMAPFILEHEADER file; // 文件信息区
- BITMAPINFOHEADER info; // 图象信息区
- RGBQUAD *pColorTable; // 调色板
- unsigned char *imgBuf; // 位图数据
- }bmp;
复制代码
结构体中的其他结构体也与对应的bmp的文件格式相对应。
文件信息结构体
- typedef struct tagBITMAPFILEHEADER
- {
- unsigned short int bfType; // 位图文件的类型,必须为 BM
- unsigned int bfSize; // 文件大小,以字节为单位
- unsigned short int bfReserverd1; // 位图文件保留字,必须为0
- unsigned short int bfReserverd2; // 位图文件保留字,必须为0
- unsigned int bfbfOffBits; // 位图文件头到数据的偏移量,以字节为单位
- }BITMAPFILEHEADER;
复制代码
图象信息
- typedef struct tagBITMAPINFOHEADER
- {
- int biSize; // 该结构大小,字节为单位
- int biWidth; // 图形宽度以象素为单位
- int biHeight; // 图形高度以象素为单位
- short int biPlanes; // 目标设备的级别,必须为1
- short int biBitcount; // 颜色深度,每个象素所需要的位数
- int biCompression; // 位图的压缩类型
- int biSizeImage; // 位图的大小,以字节为单位
- int biXPelsPermeter; // 位图水平分辨率,每米像素数
- int biYPelsPermeter; // 位图垂直分辨率,每米像素数
- int biClrUsed; // 位图实际使用的颜色表中的颜色数
- int biClrImportant; // 位图显示过程中重要的颜色数
- }BITMAPINFOHEADER;
复制代码
调色板
- typedef struct tagRGBQUAD
- {
- unsigned char rgbBlue;
- unsigned char rgbGreen;
- unsigned char rgbRed;
- unsigned char rgbReserved;
- }RGBQUAD;
复制代码
由于手头没有监控摄像头,算法调试部分就暂以PC上的图片为例。使用stdio.h中的文件操作函数。 通过fopen函数读取的图片信息:
从以上信息可以看出,这个车牌的监控图是24位真彩图片,图片尺寸是600*480的,图片的大小是0xc5c46字节,即791K,等等信息。 数据区从imgBuf的内存地址(即0x8090ff44)开始每三个字节为一个像素点的数据。 以下是数据区的开头部分数据:
例如: BB C6 CE 就是第一个像素点的颜色,顺序是BGR。以此类推。
而存储时,也是按照bmp图片的文件格式,一个结构体一个结构体的将数据写入一个bmp的文件。
因源码与out文件在另一台电脑上,周一统一上传。
|