STM32F4_照相机

目录

前言

1. BMP编码

2. JPEG编码


前言

        我们所要实现的照相机,支持BMP图片格式的照片和JPEG图片格式的照片。

1. BMP编码

BMP文件是由文件头、位图信息头、颜色信息和图形数据四部分构成。

1. BMP文件头(14个字节):BMP文件头数据结构含有BMP文件类型、文件大小和位图起始位置等信息。

//BMP文件头

typedef__packed struct
{
    u16 bfType;  //文件标志,只对‘BM’,用来识别BMP位图类型
    u32 bfSize;  //文件大小,占四个字节
    u16 bfReserved1;  //保留
    u16 bfReserved2;  //保留
    u32 bfOffBits;    //从文件开始到位图数据(Bitmap data)开始之间的偏移量
}BITMAPFILEHEADER;

2. 位图信息头(40个字节):BMP位图信息头数据用于说明位图的尺寸等信息

typedef __packed struct 
{ 
 u32 biSize ; //说明 BITMAPINFOHEADER 结构所需要的字数。 
 long biWidth ; //说明图象的宽度,以象素为单位 
 long biHeight ; //说明图象的高度,以象素为单位 
 u16 biPlanes ;  //为目标设备说明位面数,其值将总是被设为 1 
 u16 biBitCount ; //说明比特数/象素,其值为 1、4、8、16、24、或 32 
 u32 biCompression ; //说明图象数据压缩的类型。其值可以是下述值之一: 
 //BI_RGB:没有压缩; 
 //BI_RLE8:每个象素 8 比特的 RLE 压缩编码,压缩格式由 2 字节组成 
 //BI_RLE4:每个象素 4 比特的 RLE 压缩编码,压缩格式由 2 字节组成 
 //BI_BITFIELDS:每个象素的比特由指定的掩码决定。 
 u32 biSizeImage ; //说明图象的大小,以字节为单位。当用 BI_RGB 格式时,可设置为 0 
 long biXPelsPerMeter ;//说明水平分辨率,用象素/米表示 
 long biYPelsPerMeter ;//说明垂直分辨率,用象素/米表示 
 u32 biClrUsed ; //说明位图实际使用的彩色表中的颜色索引数 
 u32 biClrImportant ; //说明对图象显示有重要影响的颜色索引的数目, 
//如果是 0,表示都重要。 
}BITMAPINFOHEADER ; 

3. 颜色表:颜色表用于说明位图中的颜色,它有若干个表项,每一个表项是一个RGBQUAD类型的结构,定义一种颜色。

typedef__packed struct
{
    u8 rgbBlue;   //指定蓝色强度
    u8 rgbGreen;  //指定绿色强度
    u8 rgbRed;    //指定红色强度
    u8 rgbReserved; //保留,设置为0
}RGBQUAD;

4. 位图数据:位图数据记录了位图的每一个像素值,记录顺序是扫描行内从左到右,扫描行之间从下到上。位图的一个像素值所占的字节数:

当 biBitCount=1 时,8 个像素占 1 个字节; 

当 biBitCount=4 时,2 个像素占 1 个字节; 

当 biBitCount=8 时,1 个像素占 1 个字节; 

当 biBitCount=16 时,1 个像素占 2 个字节; 

当 biBitCount=24 时,1 个像素占 3 个字节; 

当 biBitCount=32 时,1 个像素占 4 个字节; 

biBitCount=1 表示位图最多有两种颜色,绝大多数情况下是黑色和白色,也可以自己定义。

图像信息头装调色板中将有两个调色板项,称为索引0和索引1。图像数据阵列中每一位表示一个像素。如果一个位是0,显示时就使用索引0的RGB值,如果位是1,则使用索引1的RGB值。

保存为BMP格式的图片文件的步骤:

1. 创建BMP位图信息,并且初始化各个相关信息

我们要设置 BMP 图片的分辨率为 LCD 分辨率、BMP 图片的大小(整个 BMP 文件 大小)、BMP 的像素位数(16 位)和掩码等信息。

2. 创建新BMP文件,写入BMP位图信息

我们要保存 BMP,当然要存放在某个地方(文件),所以需要先创建文件,同时先保存 BMP 位图信息,之后才开始 BMP 数据的写入。

3. 保存位图数据

从LCD的GRAM里面读取各点的颜色值,依次写入第二步创建的BMP文件即可。注意:保存顺序(也就是读取GRAM顺序)是从左到右,从下到上。

4. 关闭文件

使用FATFS,在文件创建之后,必须调用 f_close,文件才会真正的体现在文件系统里面,否则是不会写入的!注意:写完之后,一定要调用 f_close。

2. JPEG编码

        JPEG(Joint Photographic Experts Group)是一个由ISO和IEC两个组织机构联合组成的专家组,负责制定静态的数字图像数据压缩标准,这个专家组开发的算法称为JPEG算法,并且成为国际上通用的标准,又称为JPEG标准

        JPEG专家组开发了两种基本的压缩算法,一种是采用以离散余弦变换为基础的有损压缩算法,另一种是采用以预测技术为基础的无损压缩算法

        JPEG压缩是有损压缩,他利用了人的视角系统的特性,使用量化和无损压缩编码相结合来去掉视角的冗余信息和数据本身的冗余信息

        JPEG压缩编码分为三个步骤:

        1. 使用正向离散余弦变换把空间域表示的图变成频率域表示的图

        2. 使用加权函数对DCT系数进行量化,这个加权函数对于人的视觉系统是最佳的

        3. 使用霍夫曼可变字长编码器对量化系数进行编码

STM32F4_照相机_第1张图片

        DMA接收来自OV2640的JPEG数据流,首先使用M0AR(内存1)来存储,当M0AR满了以后,自动切换到M1AR(内存2),同时程序读取M0AR(内存 1)的数据到外部 SRAM; 当 M1AR 满了以后,又切回 M0AR,同时程序读取 M1AR(内存 2)的数据到外部 SRAM;依 次循环(此时的数据处理,是通过 DMA 传输完成中断实现的,在中断里面处理),直到帧中断, 结束一帧数据的采集,读取剩余数据到外部 SRAM,完成一次 JPEG 数据的采集。

        M0AR,M1AR所指向的内存,必须是内部内存,不过由于采用了双缓冲机制,我们不必定义一个很大的数组,一次性接收所以的JPEG数据了,而是可以分批次接收,数组可以定义的比较小。

你可能感兴趣的:(STM32,stm32,单片机,嵌入式硬件)