ImageTracking_CloudRecognition¶
演示如何使用云识别功能。
演示如何创建和使用本地缓存
演示如何在跟踪时停止网络请求
运行前配置¶
使用云识别需配置服务器访问信息,这些信息可以在EasyAR官网的开发中心中 云识别管理页面 中获得。在Unity中输入这些信息有两种方法:
一种是全局配置, EasyAR 配置 Image Tracking > Cloud Recognition (CRS) > Service Access [Global]
另一种是在场景中配置,它只对当前场景有效。
用法¶
详解¶
触发云识别¶
从EasyAR Sense 4.1开始,所有 CloudRecognizer 的请求都由用户代码触发,SDK内部将不再触发从服务器发送和接收数据的调用。也就是说你可以自由控制请求的频次。
cloudRecognizer.Resolve(requestTimeout, (result) => {});
最低请求间隔限制为300ms。
周期性地触发云识别¶
private void Update()
{
AutoResolve();
}
在这个sample中,如果target在被跟踪或是前一次的resolve未完成或时间间隔未到达预设值(1s)的时候,resolve不会被调用。
private void AutoResolve(OutputFrame oframe, Matrix4x4 displayCompensation)
{
var time = Time.realtimeSinceStartup;
if (!resolveOn || isTracking || resolveInfo.Running || time - resolveInfo.ResolveTime < resolveInterval) { return; }
resolveInfo.Running = true;
resolveInfo.ResolveTime = time;
...
}
云识别结果¶
云识别是EasyAR的独立功能,可以在不与图像跟踪一起使用。如果在识别之后不需要跟踪,直接使用resolve结果即可。
cloudRecognizer.Resolve(requestTimeout, (result) =>
{
...
resolveInfo.CloudStatus = result.Status;
...
var target = result.Target;
...
});
跟踪云返回的target¶
如果需要跟踪服务器识别到的图像,就需要用到result中的target信息。
在这个sample中target被clone了一份,因为它会在ImageTargetController中被引用,因此需要保留一份内部object的引用。
cloudRecognizer.Resolve(requestTimeout, (result) =>
{
...
var target = result.Target;
if (target.OnSome)
{
var targetValue = target.Value;
if (!loadedCloudTargetUids.Contains(targetValue.uid()))
{
LoadCloudTarget(targetValue.Clone());
}
}
});
创建一个有 ImageTargetController 的 GameObject ,并将resolve回调中的 ImageTarget 赋给 ImageTargetController.Source ,这样controller可以使用 ImageTargetController.DataSource.Target 来初始化。
private void LoadCloudTarget(ImageTarget target)
{
...
var go = new GameObject(uid);
targetObjs.Add(go);
var targetController = go.AddComponent<ImageTargetController>();
targetController.TargetDataLoad += (_) => target.Dispose();
targetController.Source = new ImageTargetController.TargetSourceData
{
Target = target
};
LoadTargetIntoTracker(targetController);
}
没有必要多次加载同一个target,并且这样做也会失败。
if (!loadedCloudTargetUids.Contains(targetValue.uid()))
{
LoadCloudTarget(targetValue.Clone());
}
使用离线缓存¶
一个好的实践是,将识别到的target保持在文件存储中,以便在下次启动时加载。这会对下次应用启动时的识别有好处,可以减少响应时间,而且可以在离线状态下使用识别过的target。
可以使用 ImageTarget.save 将target保存为 .etd 文件。
target.save(OfflineCachePath + "/" + target.uid() + ".etd")
然后可以在下次运行时通过 ImageTargetController.DataSource.TargetDataFile 类型的数据使用 .etd 文件创建target。
private void LoadOfflineTarget(string file)
{
var go = new GameObject(Path.GetFileNameWithoutExtension(file) + "-offline");
targetObjs.Add(go);
var targetController = go.AddComponent<ImageTargetController>();
targetController.Source = new ImageTargetController.TargetDataFileSourceData
{
PathType = PathType.Absolute,
Path = file,
};
LoadTargetIntoTracker(targetController);
}