当前位置: 首页 > article >正文

详解BMP图片格式以及关于Verilog图像处理的仿真环境搭建

文章目录

  • 一、BMP位图简介
  • 二、BMP格式分析
    • 2.1 如何用十六进制打开BMP图片
    • 2.2 头文件格式
    • 2.3 信息头格式
    • 2.4 调色板格式
    • 2.5 位图数据格式
    • 2.6 位图对齐方式
  • 三、Verilog图像处理的仿真环境搭建
    • 3.1 Verilog文件操作指令
      • 3.1.1 条件编译 (`` `ifdef``、 `` `else``、`` `endif``)
      • 3.1.2 文件打开($fopen)
      • 3.1.3 文件关闭($fclose)
      • 3.1.4 文件写入($fwrite)和(fdisplay)
      • 3.1.5 文件读取
      • 3.1.6 文件定位
    • 3.2 读写BMP图片仿真环境搭建
      • 3.2.1 宏定义标识符以及条件编译例化
      • 3.2.2 常量和变量的声明
      • 3.2.3 寄存器和wire声明
      • 3.2.4 初始化R、G、B、以及BMP头文件寄存器的值
      • 3.2.5 从RGB寄存器中读出RGB像素值,再生成对应时序
      • 3.2.5 整体仿真流程控制
      • 3.2.6 写新的BMP图像
  • 四、仿真结果观察


一、BMP位图简介

  扩展名为 .BMP(Bitmap Image File)格式是一种位图图像文件格式,用于存储图像数据。它由微软在1986年推出,广泛用于Windows操作系统中。位图按照是否与设备相关分类可以分为:设备相关位图DDB(device-dependent bitmap)、设备无关位图DIB(device-independent bitmap)。BMP格式的特点包括:

  • 无压缩:BMP文件通常以未压缩的形式存储图像数据,这意味着图像质量较高,但文件大小也相对较大。

  • 简单的结构:BMP文件的结构相对简单,包含文件头、信息头、调色板(可选)和像素数据等部分。

  • 支持多种颜色深度:BMP格式支持多种颜色深度,从1位(黑白)到32位(包含透明度),这使得它可以存储不同类型的图像。

  • 兼容性:由于其简单性和历史悠久,BMP格式在许多图像处理软件和操作系统中具有良好的兼容性。

  • 缺乏压缩:虽然这使得图像质量保持较高,但也导致了文件体积较大,不适合网络传输。

  位深度又叫色彩位数,即位图中要用多少个二进制位来表示每个点的颜色,是分辨率的一个重要指标。常用有1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色),24位(真彩色)和32位(增强型真彩色)等。

在这里插入图片描述
  例如我电脑上这张BMP图片,分辨率是1920*1280,位深度是24位。

二、BMP格式分析

  BMP结构相对简单,主要由以下几个部分组成:文件头、信息头、调色板(可选)、位图数据四部分组成 。

2.1 如何用十六进制打开BMP图片

  我们随便双击打开一张BMP图片显示如下:

在这里插入图片描述
  这是一张1920*1280,24位深的BMP图片,接下来我们想要用文本编辑器查看这图片的存储数据:

  1. 我电脑上装的是notepad++,打开notepad++点击右上角的插件管理:

在这里插入图片描述

  1. 搜索Hex-Editor,然后点击安装

在这里插入图片描述

  1. 安装后notepad++会重启,此时我们点击BMP图片,打开方式选择notepad++

在这里插入图片描述

  1. 此时我们看现在还是显示乱码,我们点击右上角的插件 -> Hex-Editor - > View in HEX

在这里插入图片描述

  此时我们的BMP图片就以16进制的格式打开了,接下来我们分析BMP文件格式。

2.2 头文件格式

  文件头包含了关于文件的基本信息,包括文件类型、文件大小、保留字段和偏移量等。文件头的前两个字节通常是字符“BM”,表示这是一个BMP文件;一共占用14个字节,文件头的结构体定义如下所示:

typedef struct tagBITMAPFILEHEADER{
   
	WORD bftype; 		// 位图文件的类型,必须设置为BM,占用2字节
	DWORD bfSize; 		// 位图文件的大小,以字节为单位,占用4字节
	WORD bfReserved1; 	// 位图文件保留字,必须设置为0,占用2字节
	WORD bfReserved2; 	// 位图文件保留字,必须设置为0,占用2字节
	DWORD bfoffBits; 	// 位图数据相对于位图文件头的偏移量表示,占用4字节
} BITMAPFILEHEADER;

  头文件结构体中不同变量说明如下:

变量名称 地址偏移(十六进制) 大小(byte) 说明
bftype 16'h0000 2 用于文件的类型,为十六进制的 0x42,0x4D,与 ASCII 中的 B,M 相同,表示文件格式为BMP;它可能有以下值:
BM - Windows 3.1x、95、NT、…等
BA - OS/2 结构位图数组
CI - OS/2 结构颜色图标
CP – OS/2 常量颜色指针
IC – OS/2 结构图标
PT – OS/2 指针
bfSize 16'h0002 4 BMP 文件的大小
bfReserved1 16'h0006 2 保留
bfReserved2 16'h0008 2 保留
bfoffBits 16'h000A 4 位图数据的起始地址,即:可以找到位图图像数据(像素)的字节的偏移量

  我们用十六进制打开上面的BMP图片分析头文件:

在这里插入图片描述
  整个红色框中就是14个字节的头文件信息,其中

  • 绿色框中的两个字节为0X42,0X4d表示文件类型,分别对应了ASCII表中的’ B ‘,’ M ’

在这里插入图片描述

  • 蓝色框中的四个字节表示文件的大小(低位在前),这里是0x708036;对应的十进制数就是7372854,说明此图片的大小为7372854字节,我们打开图片属性查看,图像大小就是7372854字节:

在这里插入图片描述

  • 两个粉色框中的四个字节表示为保留选项,默认为0

  • 黑色框中的四个字节表示位图像素的起始地址,这里为0x36 换算成十进制就是54,说明实际像素位置是从54字节开始(头文件14字节+ 信息头40字节 ),有的BMP文件还有调色板,因此像素的起始地址还要在54字节再加上包含调色板信息的字节数。

  调色板的主要作用是将像素值映射到实际的颜色。对于低位深度的图像(如1位、4位和8位),每个像素值并不直接表示颜色,而是通过调色板中的索引来找到对应的颜色。BMP格式中包含调色板的情况主要与图像的颜色深度有关:

  • 1位色深:每个像素用1位表示,只有两种颜色(黑和白)。此时,调色板会包含2种颜色的定义
  • 4位色深:每个像素用4位表示,可以支持16种颜色。调色板将包含这16种颜色的定义
  • 8位色深:每个像素用8位表示,可以支持256种颜色。调色板定义了这256种颜色的具体值

  在24位和32位色深的情况下,图像的每个像素直接使用RGB值表示颜色,因此不需要调色板。总之,BMP文件会在1位、4位和8位颜色深度的情况下包含调色板,而在24位和32位颜色深度时则不需要调色板。调色板的存在使得低位深度图像能够以较小的文件大小存储多种颜色的信息

2.3 信息头格式

  BMP信息头,包含了图像尺寸、像素数据大小、压缩类型、分辨率等信息一共占用40个字节,信息头的结构体定义如下所示:

typedef struct WINBMPINFOHEADER  
{
   
   unsigned long  biSize;			// 信息头结构所需要的字数,占用4字节
   unsigned long  biWidth;			// 图像宽度,单位为像素,占用4字节
   unsigned long  biHeight;			// 图像高度,单位为像素,负数,则说明图像是正向的,占用4字节
   unsigned short biPlanes;			// 为目标设备说明位面数,其值将总是被设为1,占用2字节
   unsigned short biBitCount;		// 一个像素占用的bit位,值位1、4、8、16、24、32,占用2字节
   unsigned long  biCompression;	// 压缩类型 占用4字节
   unsigned long  biSizeImage;		// 位图数据的大小,以字节为单位,占用4字节
   unsigned long  biXPelsPerMeter;	// 水平分辨率,单位 像素/米 占用4字节
   unsigned long  biYPelsPerMeter;	// 垂直分辨率,单位 像素/米 占用4字节
   unsigned long  biClrUsed;		// 位图实际使用的颜色表中的颜色变址数 占用4字节
   unsigned long  biClrImportant;	// 位图显示过程中被认为重要颜色的变址数 占用4字节
} WINBMPINFOHEADER;

  信息头结构体中不同变量说明如下:

变量名称 地址偏移(十六进制) 大小(byte) 说明
biSize 16'h000E 4 BMP 信息头总体占用的字节数
biWidth 16'h0012 4 图像宽度,像素为单位
biHeight 16'h0016 4 图像高度,像素为单位;为正数说明像素是倒序存放,为负数说明像素是正序存放,大多数都是倒叙存放,因此次数大多数是正数
biPlanes 16'h001A 2 色彩平面数,其值始终为1
biBitCount 16'h001C 2 一个像素所占的bit数
biCompression 16'h001E 4 说明图像的压缩的类型,取值范围:
0:BI_RGB(表示无压缩)
1:BI_RLE8(8位RLE压缩)
2:BI_RLE4(4位RLE压缩)
3:BI_BITFIELDS(位字段压缩)
4:BI_JPEG(位图按照JPEG压缩)
5:BI_PNG(位图按照PNG压缩)
biSizeImage 16'h0022 4 图像像素数据的总大小(以字节为单位)。如果使用BI_RGB压缩,则该值可以为零
biXPelsPerMeter 16'h0026 4 水平分辨率,像素/米
biYPelsPerMeter 16'h002A 4 垂直分辨率,像素/米
biClrUsed 16'h002E 4 调色板颜色索引数,0表示使用所有可能的颜色。
biClrImportant 16'h0032 4 重要影响的颜色索引数目,0表示所有颜色都重要

  我们继续用十六进制打开上面的BMP图片分析信息头:

在这里插入图片描述

  1. 红色框中就是4个字节表示整个信息头所占用的大小,这里是0x28,换算成十进制就是40,说明整个信息头占用40个字节。
  2. 橙色框中4个字节表示图片宽度(单位像素),这里是0x0780,换算成十进制就是1920:

在这里插入图片描述
3. 黄色框中4个字节表示图片高度(单位像素),这里是0x0500,换算成十进制就是1280:

在这里插入图片描述

  1. 绿色框中2个字节表示色彩平面数,其值始终为1
  2. 浅蓝色框中2个字节表示一个像素所占的bit数,这里是0x0018,换算成十进制就是24:

在这里插入图片描述
6. 深蓝色框中4个字节表示图像压缩类型,此处为0表示不压缩
7. 紫色框中4个字节表示像素数据的总大小,这里是0x708000,转换成十进制是7372800字节,和头文件中的BMP大小7372854字节,相差54个字节(14个字节的头文件+40个字节的信息头)
8. 粉色框中4个字节表水平分辨率,这里是0x0ec4,转换成十进制是3780像素/米
9. 浅黄色框中4个字节表垂直分辨率,这里是0x0ec4,转换成十进制是3780像素/米
10. 第十个框和第十一个框是调色板相关的参数,我们是24位位图,不包含调色板信息,因此这里都是0:表示使用所有可能的颜色。

2.4 调色板格式

  BMP 调色板用于指定显示设备中每个像素颜色的 RGB 值。当调色板存在时(如1位、4位或8位深度的BMP图像),位图数据中的每个像素存储一个用作调色板索引的值,必须通过在调色板中查表才能得到各个像素的颜色数值。调色板通常在图像数据之前存储,调色板的结构体定义如下所示:

typedef tagRGBQUAD{
   
	BYTE rgbBlue;  	 	// 蓝色分量
	BYTE rgbGreen;  	// 绿色分量
	BYTE rgbRed;    	// 红色分量
	BYTE rgbReserved;	//透明度,一般保留
} RGBQUAD;

  调色板存放的是一副图像能使用的所有颜色组合,每种颜色占有四个字节B、G、R、A(透明度),例如红色就是:0X0000FF00。调色板的大小与位图色深N有关:
调色板大小 = 2 N 调色板大小=2^N 调色板大小=2N</


http://www.kler.cn/a/298434.html

相关文章:

  • HTTP 三、http在springboot中得应用
  • 华为 HCIP-Datacom H12-821 题库 (12)
  • Retrieval-based-Voice-Conversion-WebUI模型构建指南
  • 【Hadoop|HDFS篇】HDFS的读写流程
  • AI对未来教育领域的改变!如何使用ChatGPT,一个高效提问的指令构建模型,通过ChatGPT有效提高学习效率
  • 启明云端WT0132C5-S6模组乐鑫ESP32-C5芯片应用,设备联网开发新选择
  • 负载均衡调度器--LVS
  • ElasticSearch精要
  • 有效寻找潜在客户的五个方法
  • 完整的数仓能力,ByConity 1.0 版本发布!
  • 如何实现过滤器、拦截器和全局异常捕获?
  • 低代码平台中的统一认证与单点登录(SSO):实现简化与安全的用户管理
  • 第一个搭建SpringBoot项目(连接mysql)
  • Jedis,SpringDataRedis
  • log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈
  • LeetCode 69.x的平方根
  • 2024数学建模国赛A题详细思路:基于空间几何运动学和优化模型matlab求解
  • ollama 本地部署
  • Linux下载压缩包:tar.gz、zip、tar.bz2格式全攻略
  • 从学习到的因果网络中估计因果效应