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/