1. 图像处理基础:数字图像表示、像素与分辨率、色彩空间(RGB/Gray)、图像文件格式
各位同学好,我是老张。今天咱们开始聊图像滤波与降噪的第一课。说实话,这部分内容看起来基础,但我在项目里见过太多人栽在基础概念上。你想想看,连图像怎么存的都不清楚,后面做滤波算法那不是瞎蒙吗?
1.1 数字图像的本质:就是一堆数字
数字图像是什么?说白了,就是一张由数字组成的网格。我习惯把它想象成一个Excel表格——每个格子存一个数值,所有格子拼在一起就成了一幅图。
这个网格里的每个小格子,就叫像素(Pixel)。像素是图像的最小单元,不能再分了。你手机屏幕上那些密密麻麻的小发光点,每一个就是一个像素。
核心概念:数字图像 = 二维矩阵(宽×高),每个元素 = 像素值
举个例子,一张640×480的图像,就是有640列、480行,总共307200个像素。每个像素里存的是啥?取决于色彩空间,后面会细说。
1.2 分辨率:不是越高越好
分辨率这个词,大家天天听。但我要说句实话:很多工程师对分辨率的理解是错的。
分辨率分两种:
- 图像分辨率:就是像素总数,比如1920×1080
- 空间分辨率:每英寸多少个像素(PPI),决定了清晰度
我在做嵌入式摄像头项目时踩过一个坑:选了200万像素的传感器,觉得肯定够清晰了。结果画面糊成一团。后来才发现,传感器靶面太小,单个像素感光面积不够,信噪比极差。嗯,这里要注意——像素多不等于画质好。
避坑指南:我曾经在STM32上处理1080P图像,结果帧率只有5fps。后来降到QVGA(320×240),帧率直接飙到30fps。嵌入式系统里,分辨率要跟算力匹配,别盲目追求高像素。
1.3 色彩空间:RGB与灰度
色彩空间,就是描述颜色的数学方法。嵌入式图像处理里,最常用的就两种:RGB和灰度(Gray)。
1.3.1 RGB色彩空间
RGB就是红绿蓝三原色。每个像素用3个通道表示:R(红)、G(绿)、B(蓝)。每个通道通常用8位表示,取值范围0~255。
所以一个RGB像素占3个字节。一张640×480的RGB图像,裸数据大小是:
640 × 480 × 3 = 921,600 字节 ≈ 0.88 MB
你想想看,如果每秒30帧,光图像数据就26MB/s。嵌入式系统的带宽和内存,扛得住吗?
我的习惯:在嵌入式项目里,只要不需要颜色信息,我第一时间转灰度图。数据量直接降到1/3,处理速度翻倍。
1.3.2 灰度图像
灰度图就简单了,每个像素只有一个值,表示亮度。0是纯黑,255是纯白,中间是深浅不同的灰色。
灰度转换公式(标准加权法):
Gray = 0.299 × R + 0.587 × G + 0.114 × B
为什么权重不一样?因为人眼对绿色最敏感,对蓝色最不敏感。这个公式是ITU-R BT.601标准里规定的,做图像处理的老前辈们早就研究透了。
我记得有一次做车牌识别,一开始用RGB直接处理,效果很差。后来转成灰度图,再用自适应阈值二值化,识别率从60%直接跳到95%。所以说,选对色彩空间比调算法参数重要得多。
1.4 图像文件格式:嵌入式里别用JPEG
图像文件格式,说白了就是怎么把像素数据存到文件里。常见的有:
| 格式 | 特点 | 嵌入式适用性 |
|---|---|---|
| BMP | 无压缩,数据直接存 | 适合,但文件大 |
| JPEG | 有损压缩,文件小 | 不适合,解码耗资源 |
| PNG | 无损压缩,支持透明 | 看情况,解码复杂 |
| RAW | 传感器原始数据 | 最适合,但需自己解析 |
我个人建议:嵌入式图像处理,尽量用RAW或BMP。JPEG虽然文件小,但解码需要大量计算和内存。我在一个Cortex-M4项目上试过JPEG解码,一张VGA图像解码要200ms,这还做什么实时处理?
重要结论:嵌入式图像处理,数据格式越简单越好。别在文件格式上浪费算力,把资源留给真正的算法。
1.5 像素在内存中的排列
这个知识点容易被忽略,但实际编码时特别重要。图像数据在内存里是怎么排的?
以RGB图像为例,常见排列方式有两种:
- 交错排列(Interleaved):R,G,B,R,G,B,... 一行接一行
- 平面排列(Planar):所有R通道在一起,所有G通道在一起,所有B通道在一起
我刚开始做图像处理时,没注意这个细节。用OpenCV读了一张图,以为是交错排列,结果用平面排列的方式去处理,画面全花了。查了半天才发现是数据排列方式搞错了。
在嵌入式里,摄像头传感器输出的通常是Bayer格式(一种特殊的RAW格式),每个像素只存一个颜色通道的值。需要做去马赛克(Demosaic)才能变成RGB。这部分内容,咱们后面讲滤波时会用到。
1.6 本章小结
好,咱们捋一下今天讲的核心:
- 数字图像就是二维矩阵,像素是最小单元
- 分辨率要跟嵌入式算力匹配,别贪多
- RGB占3字节/像素,灰度占1字节/像素——能转灰度就转
- 文件格式选RAW或BMP,别用JPEG给自己找麻烦
- 注意像素在内存里的排列方式,搞错了画面会花
下一章咱们开始讲滤波的基础——卷积操作。这部分是图像滤波的数学核心,我会用实际代码带着大家一步步实现。到时候你们会发现,卷积其实没那么神秘。
对了,课后作业:找一张彩色图片,手动计算前10个像素的灰度值,跟程序算出来的对比一下。这个练习能帮你彻底理解色彩空间转换。
小提示:做这个练习时,注意浮点数精度问题。嵌入式里我一般用整数运算代替浮点,比如把0.299放大1000倍变成299,最后再除回来。这样快很多。