Table of Contents

平面图像跟踪简介

平面图像跟踪(Planar Image Tracking)用于检测与跟踪日常生活中有纹理的平面物体。所谓“平面”的物体,可以是一本书、一张名片或一幅海报这样的小物体,也可以是一面涂鸦墙这样的大型目标。这类物品或事物具有平坦表面、丰富且不重复的纹理。

本篇将概述平面图像检测与跟踪的基本原理、预期效果及平台适配方案,帮助您快速理解功能边界与开发要点。

基本原理

理解这些原理有助于开发者优化识别效果并规避常见问题。

核心流程

  1. 加载预处理阶段

    • 系统加载目标图像,从中提取大量视觉特征点,生成该图像的特征描述并插入到特征库中。
    • 纹理越丰富的图像越容易识别与跟踪,您可以借助 目标图检测工具 提前检查您的目标图像的可识别度。

    参考图左:纹理丰富易识别(5 星);参考图右:元素简单、缺少纹理,不易识别(1星)。
    我们推荐达到 4~5 星质量的图像作为您的目标图像。

  2. 实时检测跟踪阶段

    • 相机捕获画面后,系统会分析当前画面的特征点,与目标图像的特征库进行特征匹配。
    • 通过 PnP(Perspective-n-Point)算法计算图像在 3D 空间中的位姿(位置+旋转)。
    • 一旦目标检测成功,系统就会进入跟踪模式。此时系统会对比连续帧的画面并分析帧与帧之间的运动,从而实现实时的跟踪过程。
  3. 优化机制

    • 跟踪丢失恢复:短暂遮挡或快速运动模糊后,系统自动重新检测目标。
    • 多目标同时跟踪:通过 Simultaneous Number 参数控制单个 Tracker 的并发数量,实现一个 Tracker 调用就可以同时跟踪多个目标。

技术限制

  • 仅支持平面图像(非 3D 物体或动态内容)。
  • 依赖环境光照,过暗或过曝会导致检测困难或跟踪易丢失。
  • 检测时相机不能距离目标过远,保证画面中目标图像在画面中的比例至少有 30%。
  • 多目标跟踪受限于设备性能,通常 PC 端可以同时跟踪 10 个以上目标,移动端可以同时跟踪 4~6 个平面目标。

效果与预期结果

理解了图像检测与跟踪的工作机制与技术限制之后,您还需要对该功能所能达到的效果有个了解。明确这些效果有助于您在开发过程中设定合理的测试标准。

理想效果

  • 精准叠加:虚拟物体与图像边缘对齐。
  • 快速检测:从应用加载到检测成功超低延迟。
  • 稳定跟踪:图像旋转、移动、部分遮挡下仍可维持跟踪。

不理想情况与应对

现象 原因 用户感知 解决方案预览(详见后续章节)
无法识别 图像纹理不足、过小 虚拟物体不出现 优化目标图像,使用工具检测可识别度
跟踪抖动 目标画面占比过小,可跟踪点不足 虚拟物体晃动明显 避免过于远离目标图像,跟踪模式设定 PreferQuality
频繁丢失 图像快速移动或完全遮挡 虚拟物体闪烁/消失 稳定移动设备/目标图像,或增大目标尺寸
多图目标缺失 受硬件性能影响 部分目标图像无法跟踪 权衡运行性能设定合理的 Simultaneous Number 参数

预期结果验证方法

  • 开发阶段:使用 PC 摄像头通过 Unity 编辑器 Play 模式预览。
  • 测试阶段:使用官方 Sample 场景或自建测试图像,覆盖不同光照/角度/距离条件。

目标图像最佳实践

平面图像跟踪的效果非常依赖于目标图像的质量。为了保证识别成功率,建议在准备目标图像时遵循以下准则。

根据使用场景不同,您可以通过多种方式准备目标图像:直接用相机正视角度拍摄目标物体,或先设计图案再打印生产。无论是照片还是设计稿,都可作为模板图片。

基础要求

  • 图像格式:建议为 JPG 或 PNG。
  • 透明通道处理:如果图像带有透明通道,系统会按白色背景处理。若非预期效果,请避免使用透明通道。

核心优化点

  1. 确保丰富的纹理细节
    模板图片应具有足够的细节和边缘变化,避免纯色或简单图形。

    参考图左:纹理丰富的图像可被检测;参考图右:纯色图像无法检测

  2. 避免重复性模式
    遵循重复规律的图案(如棋盘格、条纹)会降低特征点的唯一性。

    参考图:重复模式图像无法被跟踪

  3. 内容充满画面
    主体应尽可能占据整个画面,减少空白区域。

    参考图:左侧主体饱满的图像比右侧留白过多的图像更容易检测和跟踪

  4. 控制长宽比例
    图像不宜过于狭长,短边长度至少应达到长边的 20%。

    参考图:狭长图像难以跟踪

  5. 选择合适的分辨率
    推荐范围:SQCIF(128×96) 到 QVGA(1280×960) 之间。
    过小:特征点不足,识别率下降。
    过大:生成 Target 数据时带来不必要的内存开销增长、计算时间增多。