图像模型

[English]

ESP-VISION 中的每一个视觉操作都在读写一个 image.Image:一个由像素 组成的矩形网格,外加描述其宽、高与像素格式的小头部。理解像素的排布方式、算法使用 的色彩空间,以及底层内存的管理方式,是写出高效且正确脚本的关键。

像素格式

像素格式决定每个像素占用多少字节,以及其数值如何被解释。

格式

字节/像素

说明

BINARY

1 bit

黑/白。用于掩膜以及 image.Image.binary() 的输出。

GRAYSCALE

1

8 位灰度(0-255)。多数滤波与检测算法优先使用的格式。

RGB565

2

16 位彩色:红 5 位、绿 6 位、蓝 5 位。

BAYER

1

来自传感器的原始单通道马赛克,按需去马赛克。

YUV422

2

亮度/色度打包,常见于摄像头与编解码流水线。

JPEG / PNG

不定

image.Image.to_jpeg() / to_png 生成的压缩字节流。

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 始终以源图像的 像素坐标表示。