对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
#include
#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的格式重新分配空间了吗?如何分配?带着矩阵头一起吗?