利用自定义识别可以不用上传图片到Vuforia官网,也可以动态生成/修改识别图来达到在本地修改识别图的目的。
利用Vuforia进行自定义图片的识别(自定义识别是不支持虚拟按键的)
1.新建工程并将Vuforia插件导入Unity
2.因为是自定义识别图,不用将图片上传到官网,也就不用下载相应的图片数据包
3.将原始场景中的MainCamera删除,并拖入vuforia预制件中的ARCamera,ImageTarget和UserDefinedTargetBuilder拖入
4.导一个模型进去并放到ImageTarget下面...
5.在ARCamera下面的VuforiaBehaviour下点击OpenVuforiaConfiguration,输入LicenseKey,然后将ImageTarget的类型设置为UserDefined。
6.写脚本,这里脚本名字叫做UDTTest,挂到UserDefinedTargetBuilder下,然后将UserDefinedTargetBuilder脚本的Start scanning auto勾上,表示开启自动扫描
这个脚本,需要用到Vuforia命名空间, System.Linq命名空间,需要实现接口
IUserDefinedTargetEventHandler,具体代码框架如下:
public class UDTTest : MonoBehaviour,IUserDefinedTargetEventHandler
{
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
{
}
public void OnInitialized()
{
}
public void OnNewTrackableSource(TrackableSource trackableSource)
{
}
}
我们需要实现这个接口中所定义的三个方法OnFrameQualityChanged,OnInitialized和OnNewTrackableSource。
代码开始时先定义一个UserDefinedTargetBuildingBehaviour类型的变量,紧接着在Start中为这个变量赋值,这个变量也就是目前这个
UserDefinedTargetBuilder物体中UserDefinedTargetBuildingBehaviour组件的引用(这个组件可以动态修改ImageTarget),然后再将当前类注册为该类型事件。
m_TargetBuildingBehaviour = this.GetComponent();
if (m_TargetBuildingBehaviour!=null)
{
m_TargetBuildingBehaviour.RegisterEventHandler(this);
}
接着实现接口中的三个方法,
OnInitialized():初始化一些数据 需要自定变量来获得一个动态生成的ObjectTracker的引用和新的数据集Datasets,ObjectTracker类封装的方法来管理DataSets类和提供的ImagetargetBuilder和Targetfinder类。
public void OnInitialized()
{
m_objectTracker = TrackerManager.Instance.GetTracker();
if (m_objectTracker != null)
{
m_BuildDataSet = m_objectTracker.CreateDataSet();
m_objectTracker.ActivateDataSet(m_BuildDataSet); //激活数据集
}
}
之后是OnFrameQualityChanged函数,用来更新当前帧质量
先定义一个ImageTargetBuilder.FrameQuality类型的枚举变量,用来记录当前帧图像质量。
public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
{
m_FrameQuality = frameQuality;
if (m_FrameQuality == ImageTargetBuilder.FrameQuality.FRAME_QUALITY_LOW)
{
Debug.Log("Low Camera Image Quality ");
}
}
最后最重要的一个方法OnNewTrackableSource,这里需要声明两个变量,一个是已经动态生成可识别的识别图的数量(int TargetCounte),另一个是ImageTargtBehaviour,也就是这个ImageTarget上的ImageTargtBehaviour。(在Unity编辑器中把ImageTarget拖到这里)
主要代码:
public void OnNewTrackableSource(TrackableSource trackableSource)
{
m_objectTracker.Stop(); //停止追踪才能激活数据集
m_TargetCounter++;
m_objectTracker.DeactivateDataSet(m_BuildDataSet);//创建一个新的数据集
//如果trackable满了或者已经定义了5个识别对象,那么删除旧的DataSet
if (m_BuildDataSet.HasReachedTrackableLimit() || m_BuildDataSet.GetTrackables().Count() > 5)
{
IEnumerable trackables = m_BuildDataSet.GetTrackables();
Trackable oldest = null;
foreach (Trackable trackable in trackables)
{
if (oldest == null || trackable.ID < oldest.ID)
{
oldest = trackable;
}
}
if (oldest != null)
{
m_BuildDataSet.Destroy(oldest, true);
}
}
//定义Trackable并实例化
ImageTargetBehaviour imageTargetCopy = Instantiate(ImageTargetTemplate);
imageTargetCopy.gameObject.name = "UserDefinedTarget-" + m_TargetCounter;
//复制一个Trckable到imageTargetCopy上并让它激活
m_BuildDataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
m_objectTracker.ActivateDataSet(m_BuildDataSet);
m_objectTracker.Start();
}
最后在UserDefinedTargetBuilder下勾上StartScanningAutomatically 自动扫描
再创建一个Button,点击Button动态更新识别图 (最多可以存5张)
public void OnBuildButtonClick()
{
m_TargetBuildingBehaviour.BuildNewTarget("Test2", 50);
//BuildNewTarget(string targetname,float screenSizeWidth) 建立的newtarget,新的ImgTarget
}
结果 开始没有点的时候
我点击了两次,对应两张图片,扫描其他图片是不存在机器人的(这里TargetCounte变成了2)
本文内容参考自加速想象力出版的《AR与VR开发实战》教程。