Vuforia-PocketCat丨2.完成Vuforia的自定义目标识别

本节讲述自定义目标识别的操作步骤和解析Vuforia自定义目标识别的代码含义,为后面设计做基础


自定义目标识别操作步骤

1、要识别的物体放在ImageTarget下

2、ImageTarget——ImageTargetBehaviour Type设置为User Defined

3、将Vuforia——Perfabs里的UserDefinedTargetBuilder拖放置Hierarchy,勾选其组件的Start scanning automatically


这样,当场景加载完成后,应用就会自动扫描摄像头下的物体,但怎样让Vuforia使用眼前物体,将其作为Image Target呢?因此,我们设置一个Button。当点击此Button时,系统会将眼前物体定义为Image Target。那系统怎样检测到按按钮后就触发该功能的呢?这就需要我们在 BuildNewTarget 和 OnNewTrackableSource(TrackableSource trackableSource) 方法里写代码了


4、新建脚本,实现IUserDefinedTargetEventHandler接口。挂载到UserDefinedTargetBuilder对象上。脚本必须要实现继承接口的三个方法和一个BuildNewTarget方法:

a、void OnInitialized()在Vuforia初始化用完成后调用,即用于初始化;

b、void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)能在摄像头检测到图像质量变化时由Vuforia自动调用;

c、void OnNewTrackableSource(TrackableSource trackableSource),his gets called automatically as soon as you BuildNewTarget with UserDefinedTargetBuildingBehaviour。即当使用UserDefinedTargetBuildingBehaviour的BuildNewTarget时,该方法会自动调用。该方法可写代码用于获取新的追踪对象,并将其添加到dataset

d、void BuildNewTarget(),该方法就是一个单纯的普通方法(1),但它其中的BuildNewTarget()方法是UserfDefinedTargetBuildingBehaviour类继承的UserDefinedTargetBuildingAbstractBehaviour中的方法。我们声明了一个UserfDefinedTargetBuildingBehaviour型变量,并使用它其中的BuildNewTarget方法(2)。(2)与(1)同名,但无任何关系。(1)可以声明为任意名称

我们通过调用UserDefinedTargetBuildingBehaviour内的BuildNewTarget方法,给它传入Target名字和屏幕宽度,该BuildNewTarget方法就会创建一个新Target并将该信息传到事件系统中去,c方法检测到该事件,会自动执行c代码。当然我们需将void BuildNewTarget()绑定在Button上,从而完成一系列操作

//     This will start building a new target and report back to the event handlers as
//     soon as a new TrackableSource is available.
public void BuildNewTarget(string targetName, float screenSizeWidth); 

下面将附上代码并解析其中内容


自定义目标识别代码解析 

using UnityEngine;
using Vuforia;

/// <summary>
/// 实现IUserDefinedTargetEventHandler
/// </summary>
public class IUseDefined : MonoBehaviour, IUserDefinedTargetEventHandler
{
    //This class serves both as an augmentation definition for an ImageTarget in the editor as well as a tracked image target result at runtime
    //需设置为ImageTarget,用于自身实例化、传递出识别图的宽度和名称信息
    public ImageTargetBehaviour imageTargetTemplate;

    //This Component can be used to create new ImageTargets at runtime. It can be configured to start scanning automatically or via a call from an external script. Registered event handlers will be informed of changes in the frame quality as well as new TrackableSources
    //用于获取UserDefinedTargetBuildingBehaviour组件;
    //用于将该类注册到事件系统中。当帧质量发生变化或有新的TrackableSources时就会告知事件系统(UserDefinedTargetBuildingBehaviour中的BuildNewTarget方法可产生告知事件系统new TrackableSource is available)。
    private UserDefinedTargetBuildingBehaviour targetBuildingBehaviour;

    //The ObjectTracker encapsulates methods to manage DataSets and provides access to the ImageTargetBuilder and TargetFinder classes
    //ObjectTracker用于产生DataSet,可打开关闭数据集,将新的识别图记录到DataSet
    private ObjectTracker objectTracker;

    //DataSet,数据集,记录了上传Vuforia服务器中识别图的相关信息(识别图)。放在外面可以用于后面方法的关闭、打开数据集,给数据集添加信息
    private DataSet dataSet;

    //定义识别图数量,用于定义新增加的识别图的名字
    private int targetCounter = 0;

    //声明识别图的当前画质的变量,可用于将当前识别图画质引用赋值给该变量,做一些事情
    public ImageTargetBuilder.FrameQuality currentQuality;

    void Start()
    {
        targetBuildingBehaviour = GetComponent<UserDefinedTargetBuildingBehaviour>();

        //将当前类注册到UserDefinedTargetBuildingBehaviour的事件系统
        targetBuildingBehaviour.RegisterEventHandler(this);
    }

    /// <summary>
    /// 在Vuforia初始化完成时调用
    /// </summary>
    public void OnInitialized()
    {
        // Returns the instance of the given tracker type See the Tracker base class for  a list of available tracker classes. This function will return null if the tracker  of the given type has not been initialized.
        objectTracker = TrackerManager.Instance.GetTracker<ObjectTracker>();   //当能获取到时返回新实例,获取不到时返回null
        if (objectTracker != null)
        {
            //创建新的dataSet
            dataSet = objectTracker.CreateDataSet();
            //激活dataSet
            objectTracker.ActivateDataSet(dataSet);
        }
    }

    /// <summary>
    /// 当摄像头检测到图像质量发生变化时,由Vuforia自动调用
    /// </summary>
    public void OnFrameQualityChanged(ImageTargetBuilder.FrameQuality frameQuality)
    {
        currentQuality = frameQuality;
    }

    /// <summary>
    /// 当事件系统显示new TrackableSource is available时,将自动调用该方法。因为该特性所以该方法用于将识别图添加到数据集
    /// 并且由于该方法和下面的方法涉及到事件系统,这是我们将该类注册到事件系统中去的原因
    /// </summary>
    /// TrackableSource:An opaque handle(不透明的句柄) for creating a new Trackable in a DataSet.
    public void OnNewTrackableSource(TrackableSource trackableSource)
    {
        targetCounter++;
        //取消激活数据集
        objectTracker.DeactivateDataSet(dataSet);
        //获取已经定义好的ImageTarget,并将其实例化,用于添加到数据集
        ImageTargetBehaviour imageTargetCopy = Instantiate(imageTargetTemplate);
        //imageTarget在Hierarchy实例化了但还没有名字,我们需给它定义一个名字
        imageTargetCopy.gameObject.name = "UserTarget" + targetCounter;

        //Adds a single trackable from a source and a given gameobject to this dataset
        //将实例化的新识别图Trackable赋值给数据集
        //public abstract DataSetTrackableBehaviour CreateTrackable(TrackableSource trackableSource, GameObject gameObject);
        dataSet.CreateTrackable(trackableSource, imageTargetCopy.gameObject);
    }

    /// <summary>
    /// 此方法绑定在按钮上,用于开始创建新对象(ImageTarget)并向事件系统发送new TrackableSource is available
    /// 注意,是开始创建而不是该方法就能创建好了,它需要和OnNewTrackableSource配合使用
    /// </summary>
    public void IBuildNewTarget()
    {
        //创建新的target的名字,用于BuildNewTarget方法。上文创建的是新的ImageTarget的名字,用于在Hierarchy里显示
        string targetName = string.Format(imageTargetTemplate.TrackableName + targetCounter);

        //This will start building a new target and report back to the event handlers as soon as a new TrackableSource is available.
        //创建新对象
        targetBuildingBehaviour.BuildNewTarget(targetName, imageTargetTemplate.GetSize().x);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38239050/article/details/80754029