图像模型
ESP-VISION 中的每一个视觉操作都在读写一个 image.Image:一个由像素 组成的矩形网格,外加描述其宽、高与像素格式的小头部。理解像素的排布方式、算法使用 的色彩空间,以及底层内存的管理方式,是写出高效且正确脚本的关键。
像素格式
像素格式决定每个像素占用多少字节,以及其数值如何被解释。
格式 |
字节/像素 |
说明 |
|---|---|---|
|
1 bit |
黑/白。用于掩膜以及 |
|
1 |
8 位灰度(0-255)。多数滤波与检测算法优先使用的格式。 |
|
2 |
16 位彩色:红 5 位、绿 6 位、蓝 5 位。 |
|
1 |
来自传感器的原始单通道马赛克,按需去马赛克。 |
|
2 |
亮度/色度打包,常见于摄像头与编解码流水线。 |
|
不定 |
由 |
RGB565 把一个颜色打包进 16 位,以色彩精度换取相较 RGB888 一半的内存。绿色多分到 一位,因为人眼对绿色最敏感。image.Image.get_pixel() 既可返回打包值,也可 返回展开为每通道 8 位的 (r, g, b) 元组。
色彩空间
尽管像素以灰度或 RGB565 存储,颜色阈值化却在 LAB 色彩空间中进行。LAB 把亮度 (L)与两条颜色对立轴(A:绿-红,B:蓝-黄)分开,因此用 LAB 表示的阈值对亮度变化 远比 RGB 鲁棒。这也是为什么颜色阈值是六元组 (l_min, l_max, a_min, a_max, b_min, b_max),而灰度阈值只是 (min, max)。
模块级转换辅助函数(image.rgb_to_lab()、image.lab_to_rgb()、 image.rgb_to_grayscale() 以及其余 *_to_* 系列)对单个像素暴露这些 转换,便于离线计算阈值。
帧缓冲与 fb_alloc
嵌入式内存十分有限,因此 ESP-VISION 避免逐帧在堆上分配。sensor.snapshot() 返回的图像由一块可复用的 帧缓冲 支撑:下一次 snapshot() 会覆盖它。如果需要 保留某一帧(例如在 image.Image.difference() 中与后续帧比较),请显式调用 img.copy()。
许多算法需要只在调用期间存在的临时内存。它们使用一个栈式分配器 fb_alloc,从 帧缓冲区域中划出临时缓冲,并在操作返回时一次性释放。这就是重负载方法不会造成堆碎片 的原因,也是在热循环中应优先复用同一图像而非反复分配的原因。
感兴趣区域(ROI)
多数分析与转换方法接受 roi=(x, y, w, h) 关键字,把操作限制在图像的某个子矩形内。 在 ROI 上工作既更快(像素更少)又更有针对性(忽略无关区域)。ROI 始终以源图像的 像素坐标表示。