5.34. 小结

image 模块是摄像头所暴露的最大的 API,本章只是概述了它的轮廓:图像在内存中如何表示,摄像头如何读写单个像素,如何在捕获的帧上进行绘制,如何对它们进行算术和几何变换,如何对它们进行阈值分类和滤波,如何从中提取测量值和检测结果,如何从中解码印刷符号,如何将一幅图像与另一幅进行比较,以及如何在摄像头上获取结果并将其传出。

这套工具箱有意做得很广。在小型嵌入式摄像头上运行的经典计算机视觉流水线,会在任何数据到达机器学习模型(如果有的话)之前完成它的大部分工作——阈值处理清理输入,滤波器去噪,区域缩小搜索范围,色块和直线检测器定位候选目标,相似度评分判断候选目标是否有价值,而 I/O 层将结果交给运行下一阶段的任何环节。本章的每一页都涵盖了其中一种操作;任何给定应用的恰当流水线,都是按问题所要求的顺序将它们组合而成的一个序列。

5.34.1. 流水线模式

大多数非平凡的摄像头应用都遵循相同的轮廓。从传感器捕获一帧。对其进行预处理:转换格式、均衡直方图、模糊去噪。定位感兴趣的区域或特征:色块检测、直线检测、模板匹配、代码解码。分析所找到的内容:几何测量、相似度评分、统计。基于分析决定要做什么:触发 GPIO、上报载荷、捕获并记录、将帧交给 ML 模型。输出决策或捕获的产物:保存、编码、发送、绘制回帧中以供 IDE 预览。

没有哪一个单独的章节页面涵盖了每一个步骤;本章涵盖的是流水线所组合的构建模块。选择使用哪些模块以及以何种顺序使用,是应用脚本的工作。

5.34.2. 本章的去向

image 模块把图像当作图像来处理——像素、区域、绘制、检测。许多针对捕获数据的工作并不符合这一框架。对任意数值数组计算统计量,对原始传感器数据运行向量化算术,应用一个背后没有 image 模块方法的自定义矩阵变换,为需要特定张量布局的机器学习模型准备数据——所有这些都是数值数组库的工作,而非图像处理库的工作。

下一章正好涵盖这部分内容。摄像头上随 MicroPython 提供的 ulab.numpy 模块是 NumPy 的一个子集,有两座桥梁将它与 image 模块连接起来:to_ndarray() 将一帧的像素复制到一个 ndarray 中以进行数值计算,而 Image 构造函数接受一个 ndarray 以从结果构建一幅新图像,可直接用于显示、保存或反馈回图像库。这两个模块相互组合——各自做对方所不做的事,二者合在一起便涵盖了嵌入式视觉应用所需的数值和成像工作。