EasyAR 云识别的图库默认 10 万张图片,同时提供了对图库图片进行操作的 API 接口。这里主要说明的是如何实现云识别。
个人版一个账号只有 28 天的免费使用时间段,初学者一定要在准备学习云识别的时候再建立云图库,否则很快会过期的。
总体说明
云识别主要是在平面图像识别的 Tracker 预制件中添加了Cloudrecognizer游戏对象。
- 通过设置该游戏对象的enable属性,可以实现云识别功能的启用和禁用。
- 通过UseGlobalServiceConfi】属性可以单独配置云识别的图库。
- 通过订阅CloudUpdate事件可以获取识别状态和被识别到的平面图像的“Target”。
云识别同样需要“ImageTarget”游戏对象,只不过通常是动态生成。
上传图片
- 识别前需要将图片上传到图库。
- 进入图库后,能看到已经上传到图库的图片。点击识别图标签下的上传识别图按钮。
- 在弹出窗口中,填写识别图片名称。
- 点击浏览按钮选中要上传的图片。
- 设置宽度,这里宽度的单位是厘米,和 Unity 里的单位不一样。
- 设置完成以后点击确认按钮即可。
在图库界面中,点击上传到图库的图片可以看到图片的具体信息。其中除了图片的名称等基本信息还包括图片的可识别度和可跟踪度,可以用于了解图像是否容易被识别和跟踪。
场景设置
云识别基本内容很少,主要内容是集中在代码里。
- 设置 Main Camera 游戏对象清除标志 Clear Flags 为Solid Color。
- EasyAR/Prefabs/Composites 目录下的 EasyAR_ImageTracker-1_CloudRecognizer-1 预制件拖到场景中。
相关程序控制
在Awake事件中,订阅CloudRecognizerFrameFilter脚本的CloudUpdate事件。该事件每秒运行 2 次左右,每次都会返回状态和被识别的目标队列。
using UnityEngine;
using UnityEngine.UI;
using easyar;
using System;
public class ImageCloudRecognizerController : MonoBehaviour
{
private Text text;
private CloudRecognizerFrameFilter cloudRecognizer;
void Awake()
{
text = GameObject.Find("/Canvas/Text").GetComponent<Text>();
cloudRecognizer = FindObjectOfType<CloudRecognizerFrameFilter>();
cloudRecognizer.CloudUpdate += (status, targets) =>
{
text.text = "Cloud Recognizer status " + status.ToString()
+ Environment.NewLine + "targets count:" + targets.Count;
foreach (var t in targets)
{
text.text += Environment.NewLine +
"uid:" + t.uid() + Environment.NewLine +
"name:" + t.name();
}
text.text += Environment.NewLine + Time.time;
};
}
}
运行效果如下,当识别到图像就能显示该图像在图库的名称和 UID。
每当最下一行的时间变动一次,云识别就计数一次,无论是否识别到图像。
官方示例中使用缓存的说明
在官方的示例中,启动以后,在Awake事件中会读取作为本地缓存的“.etd”文件来加载识别目标图像。
if (UseOfflineCache)
{
if (string.IsNullOrEmpty(OfflineCachePath))
{
OfflineCachePath = Application.persistentDataPath + "/CloudRecognizerSample";
}
if (!Directory.Exists(OfflineCachePath))
{
Directory.CreateDirectory(OfflineCachePath);
}
if (Directory.Exists(OfflineCachePath))
{
var targetFiles = Directory.GetFiles(OfflineCachePath);
foreach (var file in targetFiles)
{
if (Path.GetExtension(file) == ".etd")
{
LoadOfflineTarget(file);
}
}
}
}
在CloudUpdate订阅事件中,遍历读取到的目标图像。
foreach (var target in targets)
{
var uid = target.uid();
if (loadedCloudTargetUids.Contains(uid))
{
continue;
}
LoadCloudTarget(target.Clone() as ImageTarget);
}
如果目标图像没有被缓存,则用Target类的Save方法将目标图像保存成本地的“.etd”文件。
private void LoadCloudTarget(ImageTarget target)
{
...
if (UseOfflineCache && Directory.Exists(OfflineCachePath))
{
if (target.save(OfflineCachePath + "/" + target.uid() + ".etd"))
{
cachedTargetCount++;
}
}
}
在设置跟踪图像的时候,订阅TargetFound方法,只要有一个图像被跟踪,那么就禁用CloudRecognizer组件达到停止云识别的目的。
private void LoadTargetIntoTracker(ImageTargetController controller)
{
controller.Tracker = tracker;
controller.TargetFound += () =>
{
cloudRecognizer.enabled = false;
};
controller.TargetLost += () =>
{
cloudRecognizer.enabled = true;
};
}
视频版地址:https://www.bilibili.com/video/BV1sV411d7dZ/