阅读 318

EasyAR4.0使用说明(Unity3D)四----云识别

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;
  };
}
复制代码

视频版地址:www.bilibili.com/video/BV1sV…