3、图像数据格式基础:BMP、JPEG、RGB565、灰度图

做嵌入式图像调试,说白了就是跟各种图像格式打交道。我刚开始接触这行时,也踩过不少坑——比如明明采集到了数据,串口打印出来却是一团乱码。后来才明白,问题出在格式理解上。

今天咱们就聊聊四种最常见的图像格式:BMP、JPEG、RGB565 和灰度图。每种格式都有自己的脾气,选对了事半功倍,选错了……嗯,你懂的。

3.1 BMP:简单粗暴的“原始人”

BMP 格式,全称 Bitmap,是 Windows 时代的元老。它的特点就一个字:

说白了,BMP 就是把每个像素的颜色值直接存下来。比如一张 320×240 的 24 位真彩色图,文件大小就是 320×240×3 = 230,400 字节,再加上 54 字节的文件头,几乎不玩任何花样。

优点:

  • 结构简单,解析起来毫无压力
  • 无压缩,数据完整无损
  • 调试时可以直接用十六进制查看器比对

缺点:

  • 文件体积巨大,串口传输慢到怀疑人生
  • 不支持压缩,存储效率极低

我个人习惯在开发初期用 BMP 做验证。为什么?因为它的数据排列方式最直观——从左到右、从下到上,每个字节对应什么颜色一目了然。我曾经在调试一个摄像头驱动时,就是靠打印 BMP 原始数据,发现像素顺序反了,才找到硬件接线的问题。

适用场景:开发调试阶段、数据验证、教学演示。千万别用在产品上,除非你的串口带宽是光纤级别的。

3.2 JPEG:压缩高手,但别指望它实时

JPEG 是图像压缩界的扛把子。它能把一张几兆的照片压到几百 KB,而且肉眼几乎看不出区别。

但这里有个坑——JPEG 是有损压缩。它通过丢弃人眼不敏感的高频信息来减小体积。你想想看,如果一张图反复压缩再解压,画质会越来越差。

优点:

  • 压缩比极高,适合串口传输
  • 支持 24 位真彩色,色彩丰富
  • 通用性强,几乎所有设备都能解析

缺点:

  • 编码/解码需要大量计算,MCU 扛不住
  • 有损压缩,不适合做图像分析
  • 不支持透明通道

我记得有一次,客户要求在 STM32F4 上实时传输摄像头画面。我一开始想用 JPEG,结果发现编码一帧 640×480 的图像需要 200 多毫秒——这还传个啥?后来果断换成了 RGB565。

避坑指南:我曾经在低端 MCU 上尝试软解 JPEG,结果内存爆了。如果你非要用 JPEG,建议选带硬件 JPEG 编解码模块的芯片,比如 ESP32-S3 或某些 RTOS 平台。

适用场景:存储照片、网络传输、对画质要求不高的远程监控。实时嵌入式系统慎用。

3.3 RGB565:嵌入式调试的“万金油”

RGB565 是我个人最常用的格式。它用 16 位表示一个像素:红色 5 位、绿色 6 位、蓝色 5 位。为什么绿色多一位?因为人眼对绿色最敏感。

这种格式的好处是——大小适中,解析简单。一张 320×240 的 RGB565 图像,大小是 320×240×2 = 153,600 字节,比 BMP 小了三分之一,而且没有压缩,数据完全可控。

优点:

  • 体积比 BMP 小,传输效率更高
  • 无压缩,数据完整
  • 解析简单,MCU 轻松搞定
  • 与 LCD 显示屏直接兼容

缺点:

  • 只有 65536 种颜色,色彩过渡不够平滑
  • 不适合高精度图像处理

我建议你在调试摄像头或 LCD 驱动时,优先用 RGB565。为什么?因为你可以直接把数据扔到屏幕上显示,不需要任何转换。我曾经用串口打印 RGB565 的原始数据,然后用 Python 脚本解析成图片,几分钟就定位到了像素偏移的问题。

小技巧:RGB565 的数据排列是低字节在前(Little-Endian),如果你用 Python 解析,记得用 struct.unpack('<H', data) 来读取。

适用场景:嵌入式实时显示、摄像头调试、LCD 驱动开发、串口图像传输。

3.4 灰度图:简单到极致

灰度图,说白了就是只有亮度信息,没有颜色。每个像素用一个字节(0-255)表示,从黑到白。

你想想看,一张 320×240 的灰度图,大小只有 76,800 字节——比 RGB565 还小一半。而且处理起来极其简单,连颜色空间转换都省了。

优点:

  • 体积最小,传输最快
  • 处理简单,MCU 毫无压力
  • 适合做图像识别、边缘检测等算法

缺点:

  • 没有颜色信息,不适合彩色场景
  • 细节丢失较多

我记得在做二维码识别项目时,摄像头采集到的彩色图像先转成灰度图,再二值化处理。灰度图在这里就是最佳选择——既保留了亮度信息,又大幅减少了数据量。

注意:灰度图转彩色容易,但彩色转灰度会丢失信息。如果你不确定后续是否需要颜色,建议保留 RGB565 格式。

适用场景:条形码/二维码识别、人脸检测、运动检测、文字识别、串口传输带宽受限的场景。

3.5 四种格式对比一览

格式 每像素位数 320×240 大小 压缩 色彩 MCU 处理难度
BMP 24位 24 ~230 KB 16.7M 极低
JPEG 24(压缩后) ~10-50 KB 有损 16.7M
RGB565 16 ~150 KB 65K
灰度图 8 ~75 KB 256级 极低

看到这个表格,你应该能明白为什么我推荐 RGB565 和灰度图作为串口调试的首选了吧?

3.6 我的选择建议

说了这么多,到底该怎么选?我总结一下:

  • 调试阶段:先用 BMP 验证数据正确性,再切换到 RGB565 提高传输效率
  • 实时显示:RGB565 是王道,直接怼到 LCD 上
  • 图像识别:灰度图就够了,别浪费带宽传颜色
  • 存储/网络传输:JPEG 压缩后传,但记得在 PC 端或云端解压

嗯,格式这块就聊到这儿。下一章咱们会讲怎么用串口把这些格式的数据传出来,以及怎么在 PC 端还原成图片。到时候我会分享一个我常用的 Python 脚本,保证你看了就能用。