在Unity中的ARCore扩展图像跟踪/定位API

3
Unity SDK软件包提供的ARCore增强图像示例应用程序会在示例AugmentedImageDatabase中包含的样本图像周围放置一个图片框架。如果找到多个场景中的图像,它将在这些图像周围放置图片框架,并且只有在完全失去跟踪时才会销毁图片框架。
假设您想要仅在最近识别的图像周围显示图片框架,并从先前的图像中删除该框架?检查给定图像的TrackingState并没有帮助,因为默认情况下会扩展跟踪而无法关闭,锚点API也没有提供任何有用的信息。
我通过在持有可跟踪图像的列表超过1时销毁旧会话(并创建新会话)来使其正常工作,但这会导致应用程序在暂停一秒钟后恢复。
是否有更好的方法建议?

你已经有一个列表,其中包含ARCore跟踪的所有增强图像,并称为AugmentedImageController中的m_TempAugmentedImages。为什么不使用m_TempAugmentedImages[m_TempAugmentedImages.Count]呢? - Ali Kanat
问题在于,一旦识别出图像,其跟踪状态就变为TrackingState.Tracking,即使之后再识别新图像。如果使用TrackableQueryFilter.New来填充m_TempAugmentedImages,您可以销毁以前图像上的可视化器并仅显示新图像,但是如果您想返回到先前的某个图像,则此方法不起作用。 - giacomo homunculus
3个回答

2

好的,考虑到谷歌开发人员对此Github 问题的回复,这并不是一个确切的解决方案,但它可以解决问题。就像我在评论中所说的那样,TrackableQueryFilter.Updated会提供在当前帧更新的图像(不仅仅是状态,还包括位置等),因此,在我的手机视野中并被跟踪时,我记录了318帧中m_TempAugmentedImages.Count的日志,我的图像更新了18次。

由于无法知道何时更新图像,并且更新不频繁,所以我想到了检查图像是否在3秒内未更新,如果未更新,则可以销毁该图像。为此,我将public float TimePassed添加到我的AugmentedImageVisualizer脚本中。然后在我的AugmentedImageController脚本中,我添加了以下行来检查像这样在会话中的每个图像的TimePassed:

        foreach (var visualizer in m_Visualizers.Values)
        {
            // if image is Updated TimePassed is assigned to zero for that image
            if (m_TempAugmentedImages.Count != 0 && visualizer.Image == m_TempAugmentedImages[0])
            {

                    visualizer.TimePassed = 0;

            }
            else
            {
                visualizer.TimePassed += Time.deltaTime;
            }

            if (visualizer.TimePassed > 3.0f)
            {
                Debug.Log("Destroy is called");
                m_Visualizers.Remove(visualizer.Image.DatabaseIndex);
                GameObject.Destroy(visualizer.gameObject);
            }              
        }

我已经构建了它,这样你就可以回到之前跟踪的图像,如果你对3秒不满意,也可以降低它。祝好运。


1
如果您想在之前可视化过的图像上显示跟踪情况(并因此破坏了可视化器),该图像的TrackingState几乎肯定不会从“跟踪”状态更改,因此它不会显示为m_TempAugmentedImages中已更新的内容。 - giacomo homunculus
好的,我今天有机会构建和运行这个程序。我们都有一个误解。我今天意识到当你使用TrackableQueryFilter.Updated时,它只返回该帧中已更新的图像。因此,如果您的图像没有更新,则不返回任何内容。但是,这个“更新”并不意味着其状态已更新。可能与图像的位置或理解有关,这种情况并不经常发生。如果我完全解决了这个问题,我会编辑这个问题。 - Ali Kanat
@giacomohomunculus,我已经通过计时器解决了问题并编辑了答案。 - Ali Kanat

1
使用以下代码实现与TrackingState.Tracking和TrackingState.Stopped相同的场景。这里只是使用了AugmentedImageTrackingMethod.FullTracking和AugmentedImageTrackingMethod.LastKnownPose。运行良好,并在Unity Engine中使用不同的图像进行测试。
foreach(AugmentedImage image in images)
    {
        var viz = GetVisualizer(image);

        //Marker is being tracked
        if(image.TrackingState == TrackingState.Tracking && viz == null && image.TrackingMethod == AugmentedImageTrackingMethod.FullTracking)
        {
            AddVisualizer(image);
        }
        //marker is not tracked in camera output
        else if(image.TrackingMethod == AugmentedImageTrackingMethod.LastKnownPose && viz != null)
        {
            RemoveVisualizer(image, viz);
        }
    }

答案参考来源于这里

我已经更新了我的代码,请看一下......https://forum.unity.com/threads/how-to-show-different-prefabs-for-different-images-in-arcore-augmented-image-scene-using-unity.696899/ - zyonneo

0
5个月过去了,这个问题仍然存在,真的很奇怪谷歌竟然没有修复这个问题,并且对Github上的这类问题置之不理。
我找到了一个解决方法,利用了增强图像跟踪方法,虽然不是非常理想,但是这是我找到的唯一有效的方法:在AugmentedImageController.cs文件的Update方法中。
 foreach (var image in m_TempAugmentedImages)
    {

        AugmentedImageVisualizerZreality visualizer = null;
        m_Visualizers.TryGetValue(image.DatabaseIndex, out visualizer);

        if (image.TrackingState == TrackingState.Tracking && visualizer == null)
        {
            // Create an anchor to ensure that ARCore keeps tracking this augmented image.
           // This only fires Tracking and then goes directly to paused, for ever..
            Anchor anchor = image.CreateAnchor(image.CenterPose);
            visualizer = Instantiate(
                AugmentedImageVisualizerPrefab, anchor.transform);
            visualizer.Image = image;
            m_Visualizers.Add(image.DatabaseIndex, visualizer);
        }
        else if (image.TrackingState == TrackingState.Stopped && visualizer != null)
        {
            m_Visualizers.Remove(image.DatabaseIndex);
            GameObject.Destroy(visualizer.gameObject);
        } else if (image.TrackingState == TrackingState.Paused)
        {
            trackingHint.text = "Tracking paused";
        }

        // We take care of hiding and showing here
        switch (image.TrackingMethod)
        {
            case AugmentedImageTrackingMethod.FullTracking:
                visualizer.gameObject.SetActive(true);
                trackingHint.text = "Tracking in progress..";
                break;
            case AugmentedImageTrackingMethod.LastKnownPose:
                visualizer.gameObject.SetActive(false);
                trackingHint.text = "LastKnownPose";
                break;
            case AugmentedImageTrackingMethod.NotTracking:
                trackingHint.text = "NotTracking";
                visualizer.gameObject.SetActive(false);
                break;
        }
    }

这不是一个非常干净的解决方法,但如果你选择ARCore而不是vuforia,它可以起到作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接