如何在 C# 中使用 HoloLens 2 在 2D UWP 应用程序中获取 Eye-gaze 位置

Posted

技术标签:

【中文标题】如何在 C# 中使用 HoloLens 2 在 2D UWP 应用程序中获取 Eye-gaze 位置【英文标题】:How do I acquire the Eye-gaze location within 2D UWP Apps with HoloLens 2 in C# 【发布时间】:2021-11-25 07:49:39 【问题描述】:

在线文档如 - 2D app design considerations: UI/UX 声明在 2D UWP 应用中

当用户使用运动控制器注视某物或点时,会发生触摸悬停事件。这包含一个 PointerPoint,其中 PointerType 为 Touch,但 IsInContact 为 false。

这意味着眼睛注视会自动映射到 HoloLens 2 上的 2D 应用程序窗口,并且可以通过 PointerMovedEvent 等事件获得。然而,根据我的测试,我发现它不是眼睛凝视甚至是基于头部的凝视作为触摸悬停事件传递到应用程序中,但在 HoloLens 2 上,它实际上是手指通过手投射的指向光线如果您指向 3D 空间中的 2D 应用程序窗口框架,则可以识别。但如果有人知道眼睛注视实际上被映射并在 2D UWP 应用程序窗口中可用,请告诉我。

下一个方法似乎是利用SpatialPointPose API

我可以在应用启动时获取 HoloLens 的起始位置,并使用以下代码行保持对该位置的固定引用:

  private async void Page_Loaded(object sender, RoutedEventArgs e)
     
        if (EyesPose.IsSupported() == true)
           
            var ret = await EyesPose.RequestAccessAsync();
            originLocator = SpatialLocator.GetDefault(); 
            originRefFrame = originLocator.CreateStationaryFrameOfReferenceAtCurrentLocation();
            coordinateSystem = originRefFrame .CoordinateSystem;
           
         gazeTimer.Start();
    

然后使用该参考系获取坐标系我也取得了成功 然后通过使用调度计时器,我可以将其与感知时间戳一起传递以获取 SpatialPointPose 对象:

然后我可以从中检索眼睛注视原点和注视方向,并在 xaml 文本块中显示和更新屏幕上的值:

private void GazeTimer_Tick(object sender, object e)
    
      timestamp = PerceptionTimestampHelper.FromHistoricalTargetTime(DateTime.Now);
      spPose = SpatialPointerPose.TryGetAtTimestamp( coordinateSystem, timestamp );

      if (spPose.Eyes != null && spPose.Eyes.IsCalibrationValid)
            
                if (spPose.Eyes.Gaze != null)
                
                   OriginXtextBlock.Text = spPose.Eyes.Gaze.Value.Origin.X.ToString();
                   OriginYtextBlock.Text = spPose.Eyes.Gaze.Value.Origin.Y.ToString();
                   OriginZtextBlock.Text = spPose.Eyes.Gaze.Value.Origin.Z.ToString();
                   DirectionXtextBlock.Text = spPose.Eyes.Gaze.Value.Direction.X.ToString();
                   DirectionYtextBlock.Text = spPose.Eyes.Gaze.Value.Direction.Y.ToString();
                   DirectionZtextBlock.Text = spPose.Eyes.Gaze.Value.Direction.Z.ToString();
                 
            
    

但是,我还没有找到一种方法来获取 UWP 2D 应用程序窗口框架在 3D 空间中的边界框位置,或者找到有关应用程序窗口像素分辨率如何映射到该框架的详细信息,以便我能够以某种方式解决眼睛注视指针在 2d 应用程序窗口内相交的 x,y 屏幕坐标。

我基本上希望通过在线帮助文​​档中描述的眼睛凝视获得类似的结果(这似乎实际上是针对手指识别的手部识别实现的)。但是,如果它没有通过指针事件之类的东西公开,如果有办法完成查询 2D 应用程序窗口框架的位置并解析正在相交的屏幕坐标的最后一英里,我可以使用 SpatialPointPose api通过眼睛凝视射线。

【问题讨论】:

2D App 将被放置在 Holographic OS shell 中,没有任何 API 可以从系统 shell 中获取应用窗口的位置。同样,Holographic OS shell 不提供让您退回到头部注视并开始显示头部注视光标以与 2d 应用程序交互的方法。此外,Microsoft 建议您避免将光标直接附加到用户的视线上,因为这可能会因为投射的视线信号中的轻微偏移而导致“游标”效果。 更多信息请见:Design recommendations @HoloSheep 你能做到吗? @yaali 还没有,有什么想法吗? 【参考方案1】:

2D app design considerations 文档中描述的凝视行为适用于第一代 HoloLens。

在 HoloLens 2 上,Gaze 将在 2D 应用中触发指针事件当用户处于选择模式时。这是为了防止应用在 HoloLens 2 中使用 Gaze 时出现“无意弹出或不需要的交互”问题。现在,Gaze 交互只是有意发生的。

我们将更新文档以澄清。

2D 应用无法找到其在全息空间中的位置,因此无法将 SpatialPointerPose 映射到 2D 应用的坐标空间中。此 API 仅对全息应用有用。

【讨论】:

以上是关于如何在 C# 中使用 HoloLens 2 在 2D UWP 应用程序中获取 Eye-gaze 位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Unity 中获取 HoloLens 2 和 MRTK 的眼动追踪数据?

在 Unity 开发中使用 FileOpenPicker 应用程序合约 Hololens 2

Hololens - 访问相机框架

统一关闭 Hololens 2 中的启动画面

如何将HoloLens 2仿真器与本地UDP发送器连接

在 HoloLens 2 中用手在平面上绘制