跳到主要内容

image — 机器视觉

image 是 OpenMV 机器视觉的核心模块。它提供 Image 图像对象,用来保存内存中的像素,并进行绘制、滤波、变换和特征提取;还提供检测结果对象,以及阈值、直方图、统计量等辅助对象。

摄像头的设置与采集由 csi 负责,采集得到的图像交给 image 处理。例如,img = csi0.snapshot() 得到一帧图像后,可以调用 img.find_blobs(...) 查找色块,再利用返回的结果进行判断或绘图。

本页以 H7 Plus / OV5640、固件 5.0.1(OPENMV4P) 为范围。模块名 image 小写,类名 Image 大写;image.Image、image.ImageIO、image.Blob 等名称保持官方拼写,关键点匹配类 kptmatch 按官方保留小写。

获取图像​

可以通过以下四种方式在 RAM 中获得 Image 对象:

  1. 从摄像头实时采集。 调用 csi.CSI.snapshot(),把下一帧捕获到帧缓冲区;返回的 Image 引用这块缓冲区。
  2. 从文件加载。 把文件路径传给 Image 构造函数,例如 image.Image("/sdcard/photo.jpg")。支持 BMP、PPM/PGM、JPEG、PNG,以及 OpenMV 的 ImageIO 录制格式。
  3. 从 ndarray 加载。 把形状为 (h, w) 或 (h, w, 3) 的 float32 数组传给 Image 构造函数。数组中 0.0–255.0 范围的像素值分别转换为 GRAYSCALE 或 RGB565 图像。这可以把 ml 的张量输出或 ulab 的处理结果转回可绘制的图像。
  4. 新建空图像缓冲区。 指定尺寸与像素格式,例如 image.Image(320, 240, image.RGB565)。可以从空图像开始绘制,也可以把它用作图像运算的临时缓冲区。

文件路径、数组和宽高参数代表不同的构造方式;使用时选择其中一种。完整构造签名和图像操作方法见下方的 Image 类参考。

像素格式​

像素格式决定内存占用、处理开销和可用算法。构造图像或设置摄像头格式时,使用 BINARY、GRAYSCALE、RGB565、BAYER、YUV422、JPEG 或 PNG 常量。

格式存储方式使用与限制
BINARY1 bit/像素占用最小,常用于阈值与形态学处理,通常不直接由传感器采集。
GRAYSCALE8 bit/像素,即 1 字节对应 YUV422 的 Y 通道;对 AprilTag、边缘检测、光流等多数视觉算法处理较快。
RGB56516 bit/像素,即 2 字节红色 5 位、绿色 6 位、蓝色 5 位,是默认彩色格式。
BAYER8 bit/像素传感器原始 Bayer 排列数据,适合自行去马赛克,或先用较少内存保存更多像素、需要时再转换。多数图像处理方法不能直接使用。
YUV42216 bit/像素,即 2 字节4:2:2 色度抽样,每对像素按 Y1, U, Y2, V 打包;适合直接处理色度信息,但只有部分方法支持。
JPEG / PNG压缩缓冲区,大小随内容变化适合存储与传输。进行逐像素操作前,先调用 Image.to_grayscale() 或 Image.to_rgb565() 转换。

例如,320 × 240 图像有 76800 个像素。仅计算像素数据,GRAYSCALE 需要约 75 KiB,RGB565 需要约 150 KiB;这里没有计入对象和其他缓冲区的开销。

处理结果​

检测与特征提取方法会返回结果对象。例如,Image.find_blobs() 返回 Blob 列表,Image.find_apriltags() 返回 AprilTag 列表。可以逐项读取检测结果的中心、包围框、面积、编码值等信息,再用于控制逻辑,或交给 Image.draw_rectangle()、Image.draw_string() 等方法绘制。

图像对象和检测结果对象用途不同:img 保存像素,检测结果描述这次处理发现了什么。某种结果有哪些属性、哪些操作返回列表,应以对应类的参考为准,不能把旧版结果方法写法与新版属性写法混用。

色彩空间辅助函数​

image 提供二值、灰度、RGB、LAB、YUV 之间的单个像素值转换函数。它们适合在 Python 中换算阈值或调色板条目,例如把一个 RGB 颜色转换为 LAB 值。

这些函数只转换一个值,不会修改整张图像。整图转换应使用 Image 的 to_* 方法,避免在 Python 循环中逐像素调用辅助函数。

类​

以下保留官方的 18 个类索引,链接进入官方 5.0.1 独立类参考。Image 的 find_blobs() 等属于类方法,不是下方的 30 个模块级函数。独立类页可能涵盖其他板卡特性,使用时仍须遵守 OPENMV4P 的功能限制。

类主要用途与参考
Image图像对象,保存像素并执行图像处理
ImageIO图像序列的读写与录制
HaarCascadeHaar 级联特征描述符
Similarity图像相似度结果
Histogram直方图
Percentile百分位结果
Threshold阈值结果
Statistics图像统计结果
Blob色块检测结果
Line直线结果
Circle圆形结果
Rect矩形结果
QRCode二维码检测结果
AprilTagAprilTag 检测结果
DataMatrixData Matrix 检测结果
BarCode条形码检测结果
Displacement位移估计结果
kptmatch关键点匹配结果

色彩空间转换函数​

下面的 X_to_Y 函数接收一个源色彩空间中的值,返回目标色彩空间中的值。调用时加上模块名,例如 image.rgb_to_lab((255, 0, 0))。

色彩空间参数或返回值的形式与范围
二值int,0–1
灰度int,0–255
RGB(r, g, b) 元组,每个分量为 0–255 的整数
LAB(l, a, b) 元组,L 为 0–100,A、B 为 −128–127
YUV(y, u, v) 元组,Y 为 0–255,U、V 为 −128–127

注意,辅助函数接收的 RGB 是三个 8 位分量的元组,不是打包后的 RGB565 整数。签名中的 Tuple[int, int, int] 表示三个整数构成的元组,-> 后是返回类型。

binary_to_grayscale()​

image.binary_to_grayscale(value: int) -> int

将 value 中的二值整数转换为灰度整数并返回。输入与输出的形式、范围见上表。

binary_to_rgb()​

image.binary_to_rgb(value: int) -> Tuple[int, int, int]

将 value 中的二值整数转换为 RGB 元组并返回。输入与输出的形式、范围见上表。

binary_to_lab()​

image.binary_to_lab(value: int) -> Tuple[int, int, int]

将 value 中的二值整数转换为 LAB 元组并返回。输入与输出的形式、范围见上表。

binary_to_yuv()​

image.binary_to_yuv(value: int) -> Tuple[int, int, int]

将 value 中的二值整数转换为 YUV 元组并返回。输入与输出的形式、范围见上表。

grayscale_to_binary()​

image.grayscale_to_binary(value: int) -> int

将 value 中的灰度整数转换为二值整数并返回。输入与输出的形式、范围见上表。

grayscale_to_rgb()​

image.grayscale_to_rgb(value: int) -> Tuple[int, int, int]

将 value 中的灰度整数转换为 RGB 元组并返回。输入与输出的形式、范围见上表。

grayscale_to_lab()​

image.grayscale_to_lab(value: int) -> Tuple[int, int, int]

将 value 中的灰度整数转换为 LAB 元组并返回。输入与输出的形式、范围见上表。

grayscale_to_yuv()​

image.grayscale_to_yuv(value: int) -> Tuple[int, int, int]

将 value 中的灰度整数转换为 YUV 元组并返回。输入与输出的形式、范围见上表。

rgb_to_binary()​

image.rgb_to_binary(value: Tuple[int, int, int]) -> int

将 value 中的 RGB 元组转换为二值整数并返回。输入与输出的形式、范围见上表。

rgb_to_grayscale()​

image.rgb_to_grayscale(value: Tuple[int, int, int]) -> int

将 value 中的 RGB 元组转换为灰度整数并返回。输入与输出的形式、范围见上表。

rgb_to_lab()​

image.rgb_to_lab(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 RGB 元组转换为 LAB 元组并返回。输入与输出的形式、范围见上表。

rgb_to_yuv()​

image.rgb_to_yuv(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 RGB 元组转换为 YUV 元组并返回。输入与输出的形式、范围见上表。

lab_to_binary()​

image.lab_to_binary(value: Tuple[int, int, int]) -> int

将 value 中的 LAB 元组转换为二值整数并返回。输入与输出的形式、范围见上表。

lab_to_grayscale()​

image.lab_to_grayscale(value: Tuple[int, int, int]) -> int

将 value 中的 LAB 元组转换为灰度整数并返回。输入与输出的形式、范围见上表。

lab_to_rgb()​

image.lab_to_rgb(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 LAB 元组转换为 RGB 元组并返回。输入与输出的形式、范围见上表。

lab_to_yuv()​

image.lab_to_yuv(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 LAB 元组转换为 YUV 元组并返回。输入与输出的形式、范围见上表。

yuv_to_binary()​

image.yuv_to_binary(value: Tuple[int, int, int]) -> int

将 value 中的 YUV 元组转换为二值整数并返回。输入与输出的形式、范围见上表。

yuv_to_grayscale()​

image.yuv_to_grayscale(value: Tuple[int, int, int]) -> int

将 value 中的 YUV 元组转换为灰度整数并返回。输入与输出的形式、范围见上表。

yuv_to_rgb()​

image.yuv_to_rgb(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 YUV 元组转换为 RGB 元组并返回。输入与输出的形式、范围见上表。

yuv_to_lab()​

image.yuv_to_lab(value: Tuple[int, int, int]) -> Tuple[int, int, int]

将 value 中的 YUV 元组转换为 LAB 元组并返回。输入与输出的形式、范围见上表。

特征描述子函数​

HaarCascade()​

image.HaarCascade(path: str, stages: int = -1) -> Cascade

加载 Haar 级联,返回供 Image.find_features() 使用的 Cascade 句柄。

参数说明
path字符串 "frontalface" 或 "eye" 加载固件 ROM 内置的人脸或眼睛级联;也可以填写自定义 .cascade 二进制文件的路径,该文件由 OpenMV 级联转换工具生成。
stages检测时计算的级联层数,默认 -1 使用文件中的全部层。减少层数可以加快检测,但会增加误检。

image.HaarCascade("frontalface") 是加载检测器,并不会执行人脸检测;实际检测由图像的 find_features() 方法完成。

load_descriptor()​

image.load_descriptor(path: str) -> kp_desc | lbp_desc

从 path 指向的文件加载描述子并返回。文件内部的类型标记决定恢复哪类对象:

  • ORB 关键点描述子(kp_desc):先通过 Image.find_keypoints() 提取,再由 image.save_descriptor() 保存。
  • LBP 描述子(lbp_desc):先通过 Image.find_lbp() 提取,再由 image.save_descriptor() 保存。

path 应指向已经保存的 OpenMV 描述子文件,不能用普通照片路径代替。

save_descriptor()​

image.save_descriptor(descriptor: kp_desc | lbp_desc, path: str) -> None

将 descriptor(ORB 关键点或 LBP 描述子)序列化到 path 指定的文件,使用 OpenMV 描述子文件格式;返回 None。

之后可以用 image.load_descriptor(path) 重新加载同一文件。保存的是特征描述子,不是原始图像。

match_descriptor()​

image.match_descriptor(descriptor0, descriptor1, threshold: int = 85, filter_outliers: bool = False) -> int | kptmatch

匹配两个同类型的描述子,不能把 ORB 与 LBP 混合传入。

参数说明
descriptor0、descriptor1两个待比较的描述子;均为 LBP,或均为 ORB 关键点描述子。
thresholdORB 匹配阈值,范围 0–100,默认 85。原文规定:数值越小越严格,会拒绝较弱的最近邻匹配。
filter_outliers是否对匹配关键点启用类似 RANSAC 的离群点剔除,默认 False。两幅图之间预期只有一个刚性变换时可启用;关键点来自多个物体时应关闭。

返回值随描述子类型变化:

  • 两个 LBP 描述子:返回整数汉明距离,越小越相似。
  • 两个 ORB 描述子:返回描述匹配关键点群的 kptmatch;如果没有匹配通过阈值,则返回 None。

原文签名写作 int | kptmatch,但原文正文同时说明可能返回 None,这里保留并明确这一差异。使用 ORB 结果前,应先判断它是否为 None。

阈值与匹配结果不是同一个数:按原文规则,把 ORB 的 threshold 从 85 降到 70 会收紧匹配条件;LBP 返回的汉明距离则是比较后的结果,不能直接当作这个阈值。

色块几何辅助函数​

以下函数接收 Image.find_blobs() 返回的一个 Blob,在需要时计算额外的几何信息。它们是模块级函数,例如 image.get_solidity(blob),不是 Blob 的成员方法;不调用时,基础色块查找流程不承担这部分计算开销。

get_solidity()​

image.get_solidity(blob: blob) -> float

计算色块的实心度:blob.pixels / convex_hull_area,即色块像素数除以凸包面积。

返回 0–1 的浮点数;1.0 表示色块完全填满自己的凸包。例如,色块有 600 个像素,凸包面积为 1000,实心度就是 0.6。

get_convexity()​

image.get_convexity(blob: blob) -> float

计算色块的凸度:convex_hull_perimeter / blob.perimeter,即凸包周长除以色块周长。

返回 0–1 的浮点数;1.0 表示完全凸的色块。它比较的是周长,与上一个函数比较面积的实心度不同。

get_major_axis_line()​

image.get_major_axis_line(blob: blob) -> line

返回沿色块主轴方向的 Line 对象。这里的主轴是色块最小面积旋转矩形的两条主轴中较长的一条。

get_minor_axis_line()​

image.get_minor_axis_line(blob: blob) -> line

返回沿色块次轴方向的 Line 对象。这里的次轴是色块最小面积旋转矩形的两条主轴中较短的一条。

get_enclosing_circle()​

image.get_enclosing_circle(blob: blob) -> circle

返回包围该色块的 Circle 对象。原文只说明它包围色块,没有把它定义为最小包围圆。

get_enclosed_ellipse()​

image.get_enclosed_ellipse(blob: blob) -> Tuple[int, int, int, int, int]

返回五元组 (cx, cy, a, b, rotation),描述色块最小面积旋转矩形的内切椭圆。

元素含义
cx、cy椭圆中心的像素坐标,整数。
a、b两个半轴的像素长度,整数;不是完整轴长。
rotation椭圆旋转角度,单位为度,整数。

这是普通元组,不是带命名属性的 attrtuple;只能通过索引或元组解包读取。例如 ellipse[0] 是中心横坐标,不能写作 ellipse.cx。

常量​

以下常量的类型均为 int,使用时带上 image. 前缀。常量名用于选择格式或算法,不在这里写死其数值;某些常量只存在于启用了相应功能的固件中。

像素格式​

传给 Image 构造函数的 pixformat,或 csi.CSI.pixformat()。

常量说明
image.BINARY1 bit/像素的位图,体积最小;用于阈值与形态学处理,通常不直接由传感器采集。
image.GRAYSCALE8 bit/像素,即每像素 1 字节。对 AprilTag、边缘检测、光流等多数视觉算法处理较快。
image.RGB56516 bit/像素,红 5 位、绿 6 位、蓝 5 位,是默认彩色格式。
image.BAYER8 bit/像素的传感器原始 Bayer 数据;多数图像处理方法不可直接使用。适合按需去马赛克或节省存储像素所需的内存。
image.YUV4224:2:2 色度抽样,每像素 2 字节,每对像素按 Y1, U, Y2, V 打包。只有部分图像处理方法直接支持。
image.JPEGJPEG 压缩缓冲区;逐像素操作前先用 Image.to_grayscale() 或 Image.to_rgb565() 转换。
image.PNGPNG 压缩缓冲区;逐像素操作前先用 Image.to_grayscale() 或 Image.to_rgb565() 转换。

调色板​

用于 Image.to_rainbow()、Image.to_ironbow()、Image.draw_image() 的 color_palette 参数,把灰度图像映射为彩色。本页不使用热成像或事件传感器专用的摄像头调色板设置。

常量说明
image.PALETTE_RAINBOW平滑的彩虹色轮,OpenMV 热成像的默认调色板。
image.PALETTE_IRONBOW非线性的铁红调色板,模拟 FLIR Lepton 热成像取景器的显示效果。

缩放模式​

传给 Image.draw_image()、Image.scale() 或类似缩放方法的 hint 参数。

常量说明
image.AREA缩小时使用区域平均;放大时使用最近邻。
image.BILINEAR双线性缩放;缩小时使用子采样。
image.BICUBIC双三次缩放,质量高于 BILINEAR,但更慢;缩小时使用子采样。

绘图提示​

以下标志可以按位或组合后传给 Image.draw_image() 的 hint 参数,例如 image.HMIRROR | image.VFLIP。

常量说明
image.VFLIP绘制时垂直翻转源图像。
image.HMIRROR绘制时水平镜像源图像。
image.TRANSPOSE绘制时转置源图像,交换 x/y。
image.CENTER让源图像在目标中居中;显式 x/y 偏移改为相对中心,而不是相对左上角。
image.EXTRACT_RGB_CHANNEL_FIRST在缩放之前提取 RGB 通道;未设置时在缩放之后提取。
image.APPLY_COLOR_PALETTE_FIRST在缩放之前应用调色板;未设置时在缩放之后应用。
image.SCALE_ASPECT_KEEP保持宽高比,把源图像完整放入目标区域;比例不同时会留边。
image.SCALE_ASPECT_EXPAND保持宽高比并填满目标区域;比例不同时会裁切。
image.SCALE_ASPECT_IGNORE忽略宽高比,把源图像缩放到填满目标区域。
image.BLACK_BACKGROUND告知透明度混合流程目标已知为全黑,从而跳过目标像素回读,加快刚清空缓冲区上的透明效果。
image.ROTATE_90VFLIP | TRANSPOSE 的快捷组合,顺时针旋转 90 度。
image.ROTATE_180HMIRROR | VFLIP 的快捷组合,旋转 180 度。
image.ROTATE_270HMIRROR | TRANSPOSE 的快捷组合,顺时针旋转 270 度。

JPEG 色度抽样​

写入 JPEG 时,传给 Image.to_jpeg()、Image.compress() 或 Image.save() 的 subsampling 参数。

常量说明
image.JPEG_SUBSAMPLING_AUTO根据 JPEG 质量设置自动选择色度抽样方式。
image.JPEG_SUBSAMPLING_444强制 4:4:4,不压缩色度采样。
image.JPEG_SUBSAMPLING_422强制 4:2:2;向不能正确处理 4:2:0 的第三方播放器传输 MJPEG 时,原文推荐使用此项。
image.JPEG_SUBSAMPLING_420强制 4:2:0 色度抽样。

模板匹配​

传给 Image.find_template() 的 search 参数。

常量说明
image.SEARCH_EX穷举搜索,评估 ROI 内每个位置;最慢,但保证找到最佳匹配。
image.SEARCH_DS菱形搜索,从粗到细,比 SEARCH_EX 快得多;对于高度自相似的模板,可能错过全局最优匹配。

边缘检测​

传给 Image.find_edges() 的 algorithm 参数。

常量说明
image.EDGE_CANNYCanny 检测:梯度幅值、非极大值抑制、滞后阈值处理。质量较高,但更慢。
image.EDGE_SIMPLE对高通滤波结果做阈值处理。更快,但边缘比 EDGE_CANNY 更粗、噪声更多。

ORB 角点检测​

传给 Image.find_keypoints() 的 corner_detector 参数。

常量说明
image.CORNER_AGASTAGAST 角点检测,比 CORNER_FAST 更慢,但关键点更稳定。

AprilTag 家族​

可以按位或组合后传给 Image.find_apriltags() 的 families 参数。每个家族由独立的固件构建选项控制;不支持的家族常量在运行时不存在,不能把它当作值为零的常量。

常量说明
image.TAG36H1136h11 家族,587 个独立 ID,最多 4 位纠错;最常见的家族。

条形码制式​

Image.find_barcodes() 返回的条形码结果通过 BarCode.type 报告以下类型。这里使用属性 type,不是旧版方法 type()。

常量说明
image.EAN2EAN-2 附加条形码。
image.EAN5EAN-5 附加条形码。
image.EAN8EAN-8 条形码。
image.UPCEUPC-E 条形码。
image.ISBN10ISBN-10 条形码。
image.UPCAUPC-A 条形码。
image.EAN13EAN-13 条形码。
image.ISBN13ISBN-13 条形码。
image.I25交叉二五码(Interleaved 2-of-5)。
image.DATABARGS1 DataBar 条形码。
image.DATABAR_EXPGS1 DataBar Expanded 条形码。
image.CODABARCodabar 条形码。
image.CODE39Code 39 条形码。
image.CODE93Code 93 条形码。
image.CODE128Code 128 条形码。

H7 Plus 的功能边界​

OPENMV4P 的官方配置启用了图像读写、PNG、二维码、AprilTag、条形码、Haar、LBP 与关键点等功能。AprilTag 家族只启用 TAG36H11,关键点检测器启用 AGAST;其他家族及 FAST 不列作本板选择。深度图和 GENX320 专用调色板不属于原配 OV5640 的使用范围,PDF417 解码器未实现,也不列为可用类型。

软件图像格式不等于摄像头可直接输出的格式。例如二值图通过图像处理得到,PNG 可由文件解码或编码得到;不要把这些常量直接套进 cam.pixformat()。高分辨率 JPEG 适合存储,常规识别先使用灰度或 RGB565 图像,留出算法工作内存。