1. 图像处理基础:从像素到数字图像
说实话,每次带新人入门图像加速,我都要先问一个问题:你真的理解像素吗?很多人觉得这太基础了,不就是一个个小点嘛。但我在FPGA上做图像处理这些年,踩过的坑十有八九都是因为对像素的理解不够深。
好,咱们从头捋一遍。
1.1 像素是什么?
像素,英文叫pixel,是picture element的缩写。说白了,它就是数字图像里最小的、不可再分的单元。
你想想看,一张照片在电脑里放大再放大,最后会看到什么?对,一个个小方格。每个小方格就是一个像素。每个像素记录着这个位置的颜色信息。
核心概念:数字图像 = 像素的二维矩阵。每个像素有固定的位置坐标 (x, y) 和颜色值。
我在项目中遇到过一件事:有次做摄像头采集,图像边缘总有一条绿线。查了半天,发现是像素坐标计算时少减了1。你看,坐标问题就是这么要命。
1.2 RGB色彩空间
人眼能感知的颜色,其实可以用三种基色混合出来:红(Red)、绿(Green)、蓝(Blue)。这就是RGB色彩模型。
每个像素的颜色,由R、G、B三个分量共同决定。每个分量通常用8位表示,取值范围0~255。
| 颜色 | R | G | B |
|---|---|---|---|
| 纯红 | 255 | 0 | 0 |
| 纯绿 | 0 | 255 | 0 |
| 纯蓝 | 0 | 0 | 255 |
| 白色 | 255 | 255 | 255 |
| 黑色 | 0 | 0 | 0 |
| 灰色 | 128 | 128 | 128 |
嗯,这里要注意:RGB三个分量相等时,得到的就是灰度。128,128,128是中灰色。这个规律在做图像预处理时很有用。
1.3 灰度空间
为什么很多图像处理算法要先转灰度?我个人的经验是:灰度图只有亮度信息,没有颜色信息,数据量直接降到1/3。在FPGA上,这意味着一半以上的资源节省。
RGB转灰度的经典公式:
Gray = 0.299 × R + 0.587 × G + 0.114 × B
为什么权重不一样?因为人眼对绿色最敏感,对蓝色最不敏感。这个公式是ITU-R BT.601标准里规定的。
实战技巧:在FPGA里做这个计算,别直接用浮点。我习惯把系数放大256倍,变成整数运算:
Gray = (77 × R + 150 × G + 29 × B) >> 8
这样只用乘法和移位,资源省很多。
1.4 图像在计算机中的存储格式
图像在内存里怎么存的?这个问题我面试时必问。其实就两种主流方式:
1.4.1 位图格式(BMP)
最简单,不压缩。文件头 + 像素数据。每个像素按行存储,从下往上。嗯,你没看错,BMP是从左下角开始存的。
1.4.2 像素排列方式
- 交错模式(Interleaved): R,G,B,R,G,B,... 连续排列。适合逐像素处理。
- 平面模式(Planar): 所有R放一起,所有G放一起,所有B放一起。适合色彩空间转换。
我在做HDMI显示驱动时,就遇到过交错和平面搞混的问题。图像颜色全乱套了。后来我养成了一个习惯:先打印前几个像素的十六进制值,看一眼就知道是什么排列。
1.4.3 常见图像格式对比
| 格式 | 压缩 | 适用场景 | FPGA处理难度 |
|---|---|---|---|
| BMP | 无 | 调试、测试 | 低 |
| JPEG | 有损 | 照片存储 | 高(需解码) |
| PNG | 无损 | 网络传输 | 中 |
| RAW | 无 | 传感器原始数据 | 低 |
避坑指南:我曾经在项目中直接用JPEG做实时处理,结果发现解码延迟太大,帧率根本跑不上去。后来改成RAW格式输入,FPGA直接处理Bayer数据,延迟降到了1行以内。
所以,做图像加速时,尽量用无压缩或轻压缩格式。压缩格式的解码开销,往往比处理本身还大。
1.5 本章知识体系
下面这张图,是我自己总结的图像处理基础脉络。你看一遍,应该能对本章内容有个整体把握。
1.6 小结
这一章我们聊了三个核心概念:
- 像素是图像的最小单元,有坐标和颜色值
- RGB空间用三基色混合,灰度空间只保留亮度
- 存储格式决定了数据在内存里的排列方式,直接影响FPGA处理效率
我个人觉得,理解这些基础比背一堆算法公式更重要。因为你在FPGA上写代码时,面对的就是一个个像素、一个个字节。搞不清楚这些,后面做流水线、做DMA、做帧缓存,都会出问题。
好,基础打牢了,后面咱们就可以开始玩真的了。
可可精品资料库