查看 Markdown

Results 类型

Results 是每个 LibreYOLO 模型统一的单图返回类型。它带有十八个可选的载荷槽位,每种任务形态一个,并且只填充模型真正产出的那些。

Results 对象

一个 Results 描述一张图像。单张图像的源返回一个,列表源或目录返回一个列表, stream=True 则返回一个逐个产出它们的生成器。

属性类型含义
orig_shape(int, int)原始图像的高和宽
pathstr输入来自磁盘时的源路径
namesdict[int, str]类别索引到类别名
speeddict[str, float]每个阶段的毫秒数
track_id张量结果来自 track() 时的跟踪 ID
frame_idxint视频和流源的帧索引
restore_scaleint复原结果输出对输入的放大倍数;其他情况下都是 1

Python
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9t.pt")result = model(SAMPLE_IMAGE) print(result.orig_shape, result.path)print(result.boxes.xyxy)print(result.boxes.conf)print(result.names[int(result.boxes.cls[0])])

载荷槽位

除非模型产出了它,否则每个槽位都是 None。一个家族填哪个槽位,由它的任务决定。

槽位任务
boxesBoxesdetect
masksMaskssegment
keypointsKeypointspose
probsProbsclassify
obbOBBobb
gazeGazegaze
pointsPointspoint
semantic_maskSemanticMasksemantic
panopticPanopticSegmentationpanoptic
depth_mapDepthMapdepth
normal_mapNormalMapnormal
edgesEdgeMapedge
restoredRestoredImagerestore
matteMattematte
ocrOCRRegionsocr
embeddingsEmbeddingsembed
identitiesIdentitiesembed,带图库(gallery)
meshesMeshesmesh

result.normalsresult.normal_map 的可读写别名。

多个槽位可以同时被填上。分割模型会同时填 boxesmasks;视线模型用人脸框填 boxes,用角度填 gaze;网格模型用人体框填 boxes,并让 meshes 与之逐行对齐。

Boxes

一张图像的检测框。

成员返回
xyxy原始图像像素下的角点坐标
xywh像素下的中心点和尺寸
xyxyn归一化到 [0, 1] 的角点
xywhn归一化到 [0, 1] 的中心点和尺寸
conf每个框的置信度
cls每个框的类别索引
id每个框的跟踪 ID,没有则为 None
is_track存在跟踪 ID 时为 True
data打包后的张量

with_id(id)with_orig_shape(orig_shape) 返回一个替换了对应字段的新 Boxes

Masks

一张图像的实例掩码。data 是掩码张量;xy 返回每个实例以像素表示的轮廓, xyn 返回归一化后的轮廓。

Keypoints

姿态关键点,与 boxes 逐行对齐。xy 是每个关键点的坐标对,xyn 是归一化后的 坐标对。数据带第三个通道时 conf 就是它,否则为 Nonehas_visible 是一个 布尔数组,conf > 0 的地方为真;没有置信度通道时全为真。

Points

一张图像的点定位。data 的形状是 (N, 4),每行是 x, y, class, confidence。 坐标是绝对像素;xyclsconf 把这些列拆开,xyn 则把坐标归一化。

Probs

分类分数。top1 是获胜的索引,top5 是最好的五个索引,top1conftop5conf 是它们的分数。

OBB

旋转框。data 每行存 7 或 8 个值:xywhr、一个可选的跟踪 ID,然后是置信度和 类别。

成员返回
xywhr中心点、尺寸,以及以弧度表示的旋转角
xyxyxyxy以像素表示的四个角点
xyxyxyxyn归一化后的四个角点
xyxy以像素表示的轴对齐外接框
conf, cls, id, is_trackBoxes 上的一样

Gaze

每张人脸的视线角度,以弧度表示,形状为 (N, 2),与 boxes 里的人脸框逐行 对齐。第 0 列是俯仰角(pitch),第 1 列是偏航角(yaw),采用 L2CS 约定:偏航角 为正时视线朝被摄者的左侧转,俯仰角为正时视线向下转。pitch_degyaw_deg 换算成角度,direction_3d 返回单位方向向量。

SemanticMask

稠密语义图,形状为 (H, W),是原始图像画布上的整数类别 ID。255 是忽略值, 永远不算作一个类别(SemanticMask.IGNORE_INDEX)。classes 列出出现过的类别 ID,class_mask(class_id) 返回某一个类别的布尔掩码。

PanopticSegmentation

每个像素恰好属于一个互不重叠的分段,把 stuff 区域和 thing 实例统一起来。data 是一张 (H, W) 的整数分段 ID 图;分段 ID 0 表示无标注 (PanopticSegmentation.IGNORE_INDEX)。segments_info 是一个 dict 列表,每个 分段一项,每项至少包含 {"id": int, "category_id": int},其中 id 对应图里的 一个值,category_idnames 的索引。segment_ids 列出出现过的 ID, segment_mask(segment_id) 返回某一个分段的布尔掩码。

thing 与 stuff 的区分是类别的属性,不是分段的属性。载荷可以把它反规范化到每个 分段上,写成 "isthing": bool,这么做的时候,这个值必须和类别级别的映射一致。

DepthMap

稠密的相对逆深度图,形状为 (H, W),是原始图像画布上的浮点数。值越大表示离 相机越近。这些值是相对的,不是以米为单位的度量值。minmaxmean 只在 有限值上计算,normalized() 把整张图重新缩放到 [0, 1]

NormalMap

稠密的表面法线场,原始图像画布上的 float32 (H, W, 3),采用 OpenCV 相机坐标 系:+x 向右,+y 向下,+z 指向场景内部。法线朝向相机,所以一个正对相机的 平面是 (0, 0, -1)。每个像素都是单位向量。assert_normalized(atol=1e-4) 会 检查这条不变式。

EdgeMap

稠密的边缘概率图,原始图像画布上的 float32 (H, W),其中 0 是非边缘,1 是 边缘。保留连续的图,是为了把阈值留给调用方决定:binary(threshold=0.5) 应用一 个阈值,array 返回 numpy 视图。

RestoredImage

复原后的 RGB 图像,(H, W, 3) uint8。做超分辨率时,画布是输入的 Results.restore_scale 倍。array 返回 numpy 视图,save(path) 把图像写入 磁盘。

Matte

软的不透明度遮罩(matte),原始图像画布上取值在 [0, 1] 的 float32 (H, W)1 是完全前景,0 是完全背景。在 0.5 处取阈值,软遮罩就涵盖了硬的去背景掩码, 同时保留了二值掩码会丢掉的抗锯齿边缘。array 返回 numpy 视图。

在 matte 结果上,Results.cutout(image=None) 返回一个 RGBA 的 (H, W, 4) uint8 数组,它的第四个通道就是遮罩,Results.save(path, image=None) 则把这份抠像写成 背景透明的 PNG。两者在给了 image 时从中取 RGB,否则从 Results.path 重新 加载。

OCRRegions

定位到的文字连同它们的转写。data(N, 4, 2) 的浮点多边形,坐标为原始图像 像素,四个点按左上、右上、右下、左下排列;区域本身按阅读顺序给出,从上到下再从 左到右。texts 是 N 条转写组成的列表。conf 是每个区域的识别分数,det_conf 是检测分数,两者都是 (N,)

检测四边形是真正的多边形,所以它们不会填充 Results.boxesxyxy 给出轴对齐 的外接框。

Embeddings

来自 embed 任务的 L2 归一化向量,形状始终是 (N, D)。整图结果只带一行,也没 有检测框;区域嵌入向量与 boxes 逐行对齐。因为每一行都已归一化,余弦相似度就 是一次点积。

成员返回
dimD
normalized重新归一化后的各行
similarity(other)与另一个 Embeddings 或张量之间的成对余弦相似度
verify(i, j, threshold=0.4)i 行和第 j 行匹配时为 True

Identities

带名字的图库匹配结果,与 embeddings 逐行对齐。把一个 Gallery 传给 embed 预测时产出。name 是一个列表,低于匹配阈值的项为 None,而且绝不会去猜那个 最接近但低于阈值的名字。score 是匹配分数数组,data 把两者配成对。

Meshes

参数化的人体网格,与 boxes 里的人体框逐行对齐。所有东西都在原始图像的相机 坐标系下。transl 以米为单位,+z 指向背离相机的方向;verticesjoints3d 也是米制,并且已经包含了 transljoints2d 是原始图像画布上的 像素坐标,而不是网络看到的那块裁剪图上的坐标。没有任何字段带世界坐标系或重力 坐标系。

不同人体模型的参数布局不一样,所以关于形状的一切都没有写死。body_model 指出 用的是哪种参数化,各种数量则从张量里读回来:num_verticesnum_jointsnum_betashas_verticesparams 返回参数 dict,save_obj(path, index=0) 写出一个网格。字段有 global_orientbody_posebetastranslverticesfacesjoints3djoints2dconffocal_lengthextras

body_model="mhr",旋转用的是以弧度表示的欧拉角,而不是轴角;body_pose 是一个扁平的按关节排列的参数向量,而不是每个关节一个三元组;betas 是身份 blendshape 系数。骨架尺度、手部姿态和面部表情放在 extras 里。

转换与选择

每个载荷都带有 to(*args, **kwargs)cpu()cuda()numpy(),在 Results 上调用其中之一,会一次性作用到所有被填充的槽位上。

Python
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreYOLO9t.pt")result = model(SAMPLE_IMAGE) # 所有载荷一起转移result = result.cpu().numpy() # 行数据,先是普通 dict,再是 JSONprint(result.summary()[:1])print(result.to_json())

result[idx] 在所有逐行对齐的载荷上按行做选择。len(result) 是检测数量,没有 检测框时则是点的数量。result.update(...) 返回一份替换了指定槽位的副本;它接受 所有槽位,外加 track_idrestore_scale

summary 与 to_json

summary(normalize=False, decimals=5, embeddings=False) 返回一个普通 dict 的 列表,按被填充的槽位,每个检测、分段、点或区域对应一行。to_json(**kwargs) 把 自己的参数转给 summary,返回 JSON 字符串。

plot() 把稠密的法线或边缘结果渲染成它们各自约定的可视化形式;对其他类型的 结果它会抛异常。其他任务的标注图像来自 predict(save=True)

槽位名称、形状、属性与默认值读取自 v1.5.0 的 libreyolo/utils/results.py。语义引自各载荷类的文档字符串。