对Mat和.bmp文件在内存中的存在状态弄不清楚。
Mat A = imread("a.bmp"); Mat B = A;以上代码执行的结构是不是这样的:?
图1
先看 BMP图像文件。
BMP位图文件格式是Windows系统交换图像数据的一种标准图像文件存储格式。BMP位图文件由4个部分组成:位图头文件(Bitmap-file Header)、位图信息头(Bitmap-information Header)、调色板(Palette)和像素数据(Image Data),如图2所示。
图2
用a.bmp测试一下。
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #pragma pack(2) /*定义WORD为两个字节的类型*/ typedef unsigned short WORD; /*定义DWORD为e四个字节的类型*/ typedef unsigned long DWORD; /*位图文件头*/ typedef struct BMP_FILE_HEADER { WORD bType; /* 文件的类型 */ DWORD bSize; /* 文件的大小,以字节为单位 */ WORD bReserved1; /* 保留值,设置为0 */ WORD bReserved2; /* 保留值,设置为0 */ DWORD bOffset; /* 文件头的begin到实际图像数据位开始的偏移量 */ } BMPFILEHEADER; /* 固定大小14个字节 */ /*位图信息头*/ typedef struct BMP_INFO { DWORD bInfoSize; /* 信息头的大小 */ DWORD bWidth; /* 图像的宽度(以像素为单位)*/ DWORD bHeight; /* 图像的高度(以像素为单位)*/ WORD bPlanes; /* 目标设备位平面数 */ WORD bBitCount; /* 每个像素的位数 */ DWORD bCompression; /* 压缩类型 */ DWORD bmpImageSize; /* 压缩图像的大小,以字节为单位,非压缩图像为0 */ DWORD bXPelsPerMeter; /* 水平分辨率 */ DWORD bYPelsPerMeter; /* 垂直分辨率 */ DWORD bClrUsed; /* 使用的色彩数 */ DWORD bClrImportant; /* 重要的颜色数,0表示都重要 */ } BMPINF; /* a.bmp:这部分有40个字节 */ /*彩色表*/ typedef struct RGB_QUAD { WORD rgbBlue; /* 蓝色强度 */ WORD rgbGreen; /* 绿色强度 */ WORD rgbRed; /* 红色强度 */ WORD rgbReversed; /* 保留值 */ } RGBQUAD; /* bmp图没有这部分 */ int main() { FILE *fp; BMPFILEHEADER fileHeader; BMPINF infoHeader; long offset, bmpImageSize, width, height, bytesPerPixel, size, bitCount; WORD c; if((fp = fopen("a.bmp", "rb")) == NULL) { printf("Cann't open the file!\n"); exit(0); } fseek(fp, 0, 0); fread(&fileHeader, sizeof(fileHeader), 1, fp); fread(&infoHeader, sizeof(infoHeader), 1, fp); //printf("%d %d %d %d %d %d %d\n", size, offset, bmpImageSize, width, height, bitCount, bytesPerPixel); printf("%d\n", fileHeader.bSize); printf("%d\n", fileHeader.bOffset); printf("%d\n", infoHeader.bInfoSize); printf("%d\n", infoHeader.bCompression); printf("%d\n", infoHeader.bWidth); printf("%d\n", infoHeader.bHeight); printf("%d\n", infoHeader.bBitCount); }a.bmp是一个真彩色图,输出信息:
fileHeader.bSize = 3932214
fileHeader.bOffset = 54
infoHeader.bInfoSize = 40
infoHeader.bCompression = 0
infoHeader.bWidth = 1280
infoHeader.bHeight = 1024
infoHeader.bBitCount = 24
这些数据的关系是:3932214 = 1280*1024*3+54;
文件头的大小是固定的:14个字节;a.bmp的信息头大小是40个字节,加起来正好是54,即文件头到实际数据的偏移量;实际像素数据的大小是1280*1024*3(rows*cols*channel)。a.bmp是真彩色图,所以没有调色板。
再看Mat。
基本上讲Mat 是一个类,由两部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指针,指向存储所有像素值的矩阵。(这里有困惑,指向BMP文件头还是指向实际像素数据部分第一个数据的地址?C语言基础不好啊)。
关于Mat属性,我参考了这篇博客,非常好的图。点击打开链接 http://ggicci.blog.163.com/blog/static/210364096201261052543349/
下面两张图是该博客中的内容:
图3 二维Mat
图4 三维Mat
现在的问题是,a.bmp被入读到Mat A 中以后是要按照Mat的格式重新分配空间了吗?如何分配?带着矩阵头一起吗?