我后来越来越觉得,无人机 AI 项目里有一类问题很容易被轻描淡写。
不是模型能不能识别,而是识别结果能不能追溯到那一秒的飞行状态。
一个框如果只停留在视频画面里,它是识别结果。一个框如果能带着时间、姿态、镜头、位置一起回到平台,它才有机会变成业务线索。
对时不是附属工作
照片相对简单一点。很多照片自带拍摄时间、相机位置、云台信息,可以用照片里的元数据作为主锚点,再拿 OSD 做校验。
视频复杂得多。
视频里每一帧都有自己的显示时间。AI 抽到某一帧时,不能用“第几帧 / 30”粗暴推时间。实际视频帧率、编码时间戳和播放时长可能并不完全按标称帧率走。
所以我现在会把视频帧时间写成这样的链路:
视频创建时间 + frame PTS -> 识别帧绝对时间 -> 前后 OSD -> 插值后的姿态和位置
这条链路缺了,后面的定位就会飘。
OSD 不是每一帧都有
现场数据里,OSD 常常是按较低频率上报。视频是连续的,OSD 是离散的。要把某一帧放到地图上,通常要找它前后两条 OSD,再对位置、姿态、云台角度做插值。
这里有几个容易出错的地方:
- yaw 跨 0/360 度时要按最短方向插值;
- 云台快速转动时,最近 OSD 也可能不代表这一帧;
- 变焦变化会改变视场角,不能只插位置;
- 多载荷设备要按 payload_index 找对镜头;
- OSD 中断后的视频片段,只能保留识别结果,不能继续给地理坐标。
我会要求结果里保留这些字段
如果系统只保存一个 targetLng、targetLat,以后复盘基本没法查。
我更希望 AI 结果至少保留:
| 字段 | 用途 |
|---|---|
| framePtsSec | 回到视频帧 |
| frameTime | 回到识别时刻 |
| osdPrevTime / osdNextTime | 判断是否有足够近的姿态数据 |
| interpolationRatio | 说明这一帧离前后 OSD 的位置 |
| payloadIndex | 找回对应镜头 |
| lensType | 判断是否需要不同相机参数 |
| motionState | 标记高速运动、转向、变焦等不稳定状态 |
| geoStatus | 区分已定位、不可定位、低可信定位 |
这些字段看起来啰嗦,但它们决定了后面能不能解释结果。
有识别,无坐标,也是一种正确结果
我以前会本能地想把每个识别框都落到地图上。现在不会了。
如果识别帧找不到可靠 OSD,或者相机姿态缺失,正确做法不是补一个看起来差不多的点,而是把结果标成“有识别,无可信坐标”。
这对产品展示没那么漂亮,但对项目交付更可靠。
留给下次
OSD 对时要尽早进数据结构设计,不要等 AI 已经跑完、页面已经做好,再回头补姿态链路。到那个时候,很多信息已经丢了,能补回来的只是样子,补不回可信度。