MultiTarget

本页部分描述可能与4.5版本有出入。页面更新将于近期上线。

演示同时跟踪多个目标的各种做法。

  • 演示如何使用一个tracker同时跟踪多个目标 (MultiTarget_SingleTracker)

  • 演示如何使用多个tracker同时跟踪多个目标 (MultiTarget_MultiTracker)

  • 演示如何同时跟踪多个相同目标 (MultiTarget_SameImage)

  • 演示如何使用自定义代码加载图像目标 (MultiTarget_SameImage)

  • 演示如何同时跟踪多个不同类型的目标 (MultiTarget_MultiType)

用法

MultiTarget_SingleTracker

../../_images/image_31.png

MultiTarget_MultiTracker

../../_images/image_28.png

MultiTarget_SameImage

../../_images/image_30.png

MultiTarget_MultiType

../../_images/image_29.png

详解

使用一个tracker同时跟踪多个目标

为了跟踪多个目标,需要增加 ImageTrackerFrameFilter.SimultaneousNum 到需求的最大可以同时被跟踪到的target数量,并设置每个target的 Tracker 。跟踪越多物体会消耗越多CPU资源。

../../_images/image_s3_1.png ../../_images/image_s3_2.png

同时跟踪的目标数量

ImageTrackerFrameFilter.SimultaneousNum 可以随时修改并将立即生效。

../../_images/image_s3_12.gif

使用多个tracker同时跟踪多个目标

与使用一个tracker跟踪多个目标相同,只需要设置每个tracker的 ImageTrackerFrameFilter.SimultaneousNum 以及每个target的 Tracker 即可。

../../_images/image_s3_3.png ../../_images/image_s3_4.png ../../_images/image_s3_5.png ../../_images/image_s3_6.png ../../_images/image_s3_7.png ../../_images/image_s3_8.png

使用多个tracker和一个tracker跟踪多个目标有所不同。在这两个sample中,最大可同时跟踪的target数量分别是 4(1+1+2) = 4,两个相同,但是在这些target可以被如何跟踪上有所不同。

在使用单个 tracker的时候, 6 个target中的任意 4 个可以在同一帧中被跟踪到。

而在多tracker的sample设置中只有 namecard + idback + 4 ar games 中的 2 个可以在同一帧中被跟踪到。这是因为加载进一个tracker中的target只能被这个tracker所跟踪。也就是说,在这个sample中,namecard 只能被 ImageTracker_1 跟踪,而 ImageTracker_3 可以同时跟踪 4 ar games 中的任意 2 个却不能跟踪 namecard

在性能上使用多个tracker和一个tracker并没有区别,因此可以根据需要的组合来选择对应的策略。

从一张图像创建多个target

为使同一张图片不会从文件存储中加载多次,这个sample使用了完全自定义的方法来加载image target。

sample中启动了一个 coroutine 来加载图像文件,并在这之后创建了多个 target。

private void Start()
{
    StartCoroutine(FileUtil.LoadFile("namecard.jpg", PathType.StreamingAssets, (buffer) =>
    {
        StartCoroutine(LoadImageBuffer(buffer.Clone(), "namecard", 0.09f));
    }));
}

在图像文件加载成为 easyar.Buffer 后,在另一个线程中解码 buffer 为 easyar.Image ,确保渲染不会被阻塞。然后使用这个 image 来创建target。

private IEnumerator LoadImageBuffer(easyar.Buffer buffer, string name, float scale)
{
    using (buffer)
    {
        Optional<Image> imageOptional = null;
        bool taskFinished = false;
        EasyARController.Instance.Worker.Run(() =>
        {
            imageOptional = ImageHelper.decode(buffer);
            taskFinished = true;
        });

        while (!taskFinished)
        {
            yield return 0;
        }
        if (imageOptional.OnNone)
        {
            throw new Exception("invalid buffer");
        }
        using (var image = imageOptional.Value)
        {
            CreateMultipleTargetsFromOneImage(image, 10, name, scale);
        }
    }
}

使用 ImageTarget.createFromParameters 方法来直接创建 ImageTarget

using (var param = new ImageTargetParameters())
{
    param.setImage(image);
    param.setName(name);
    param.setScale(scale);
    param.setUid(Guid.NewGuid().ToString());
    param.setMeta(string.Empty);
    var targetOptional = ImageTarget.createFromParameters(param);
    ...
}

创建一个有 ImageTargetControllerGameObject 并设置 ImageTargetController.TargetSource 为上面的 ImageTarget ,这样 controller 可以使用 ImageTargetController.DataSource.Target 来初始化。

var target = targetOptional.Value;
GameObject Target = new GameObject(name + " <" + i + ">");
var controller = Target.AddComponent<ImageTargetController>();
AddTargetControllerEvents(controller);

controller.SourceType = ImageTargetController.DataSource.Target;
controller.TargetSource = target;
controller.Tracker = ImageTracker;

通过这个方法,你可以使用一个预先创建好的target来配置 ImageTargetController ,包括手动创建的target或是 CloudRecognizer 回调中返回的target。

循环上面的过程来生成场景中的多个target。

private void CreateMultipleTargetsFromOneImage(Image image, int count, string name, float scale)
{
    for (int i = 0; i < count; i++)
    {
        using (var param = new ImageTargetParameters())
        {
            ...
            var targetOptional = ImageTarget.createFromParameters(param);
            if (targetOptional.OnSome)
            {
                var target = targetOptional.Value;
                ...
            }
            else
            {
                throw new Exception("invalid parameter");
            }
        }
    }
}

同时跟踪多个不同类型的目标

同时跟踪多个不同类型的目标与使用多个tracker同时跟踪多个image target类似,唯一的区别是使用哪个类型的 tracker 和 target。

../../_images/image_s3_9.png ../../_images/image_s3_10.png ../../_images/image_s3_11.png