opencv Mat 理解(1)

对Mat和.bmp文件在内存中的存在状态弄不清楚。

Mat A = imread("a.bmp");
Mat B = A;
以上代码执行的结构是不是这样的:?

opencv Mat 理解(1)_第1张图片


图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/

下面两张图是该博客中的内容:

opencv Mat 理解(1)_第2张图片

图3 二维Mat

图4 三维Mat

现在的问题是,a.bmp被入读到Mat A 中以后是要按照Mat的格式重新分配空间了吗?如何分配?带着矩阵头一起吗?


你可能感兴趣的:(opencv,mat,bmp)