ImageTracking_MultiTarget_SameImage

注意

该页面内容将于近期更新。

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

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

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

从一张图像创建多个target

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

sample中加载了Texture2D,并在这之后创建了多个 target。

private void Start()
{
    imageTracker = Session.GetComponentInChildren<ImageTrackerFrameFilter>();
    HandleTrackerEvents(imageTracker);
    var source = new ImageTargetController.Texture2DSourceData()
    {
        Texture = TargetTexture,
        Name = TargetTexture.name,
        Scale = 0.09f
    };
    if (!source.IsTextureLoadable)
    {
        throw new Exception($"Error loading target Texture2D data for {source.Name}: {source.TextureUnloadableReason}");
    }
    LoadTexture2DData(source);
}

private unsafe void LoadTexture2DData(ImageTargetController.Texture2DSourceData source)
{
    var data = source.Texture.GetRawTextureData<byte>();
    var size = new Vector2Int(source.Texture.width, source.Texture.height);
    var pixelFormat = source.TexturePixelFormat.Value;
    var scale = source.Scale;

    var ptr = data.GetUnsafeReadOnlyPtr();
    int oneLineLength = size.x * ((pixelFormat == PixelFormat.RGBA8888 || pixelFormat == PixelFormat.BGRA8888) ? 4 : ((pixelFormat == PixelFormat.RGB888 || pixelFormat == PixelFormat.BGR888) ? 3 : 1));
    int totalLength = oneLineLength * size.y;
    using (var buffer = easyar.Buffer.create(totalLength))
    {
        for (int i = 0; i < size.y; i++)
        {
            buffer.tryCopyFrom(new IntPtr(ptr), oneLineLength * i, totalLength - oneLineLength * (i + 1), oneLineLength);
        }
        using (var image = easyar.Image.create(buffer, pixelFormat, size.x, size.y, size.x, size.y))
        {
            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.Source 为上面的 ImageTarget ,这样 controller 可以使用 ImageTargetController.DataSource.Target 来初始化。

var target = targetOptional.Value;
var go = new GameObject(name + " <" + i + ">", typeof(ImageTargetController));
var controller = go.GetComponent<ImageTargetController>();

HandleTargetControllerEvents(controller);
controller.TargetDataLoad += (_) => target.Dispose();
controller.Source = new ImageTargetController.TargetSourceData
{
    Target = 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");
            }
        }
    }
}