【问题标题】:Depth data from ARKit来自 ARKit 的深度数据
【发布时间】:2017-08-15 23:41:48
【问题描述】:

是否可以从 ARKit 访问 AVDepthData? ARFrame 包含相机的图像,但不包含其深度信息。

我尝试创建一个单独的 AVCaptureSession 来接收 AVDepthData,但我无法与 ARKit 同时运行 AVCaptureSession。 ARSCNView 更新或 AVCaptureDepthDataOutputDelegate 被调用,但绝不会同时调用两者。

【问题讨论】:

    标签: avcapturesession ios11 arkit


    【解决方案1】:

    正如this 线程中的回答和video 中提到的那样,不,当您处于世界跟踪模式时,ARKit 不会为您提供AVDepthData。向您提供AVDepthData 的唯一时间是您使用 iPhone X 处于面部跟踪模式时。

    【讨论】:

    • 是的,在我在 Stack Overflow 上发布这个问题大约一个月后,Apple 更新了 ARKit API 以包含用于面部跟踪的 AVDepthData,并最终在该线程中回复了我。此后,我向 Apple 提交了一份错误报告,要求在 World Tracking Mode 期间请求 AVDepthData。所以这是目前正确的答案,但希望苹果将来会再次更新 API。
    • 如果他们没有办法从后置(主)摄像头获得估计深度,那么为什么它的名称中甚至还有“AR”?这不是增强现实的基本前提吗?
    【解决方案2】:

    这需要很长时间(大约 15 秒),但我使用重复调用 hitTest 构建了一个深度捕获函数。这可能是非常不理想的,但我想不出绘制图像的最佳方式,这是我发现我真正理解到足以实现的第一种方式:

    let height = Int(arView.frame.height)
    let width = Int(arView.frame.width)
    
    
    UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), true, 0)
    while y < height {
      var x = 0
      while x < width {
        let location = CGPoint(x: x, y: y)
        let results = arView.hitTest(location, types: [.featurePoint, .existingPlane, .estimatedVerticalPlane, .estimatedHorizontalPlane, .existingPlaneUsingGeometry, .existingPlaneUsingExtent])
        let alpha = results.isEmpty ? 1.0 : (1.0 / CGFloat(results.count))
        for result in results {
          let value = 1.0 / (result.distance + 1.0)
          switch result.type {
            case .featurePoint:
              UIColor(red: value, green: 0, blue: 0, alpha: alpha).setFill()
            case .existingPlane:
              UIColor(red: 0, green: 1, blue: 0, alpha: alpha).setFill()
            case .estimatedVerticalPlane:
              UIColor(red: 0, green: 0, blue: value, alpha: alpha).setFill()
            case .estimatedHorizontalPlane:
              UIColor(red: 0, green: 0, blue: value, alpha: alpha).setFill()
            case .existingPlaneUsingGeometry:
              UIColor(red: value, green: value, blue: value, alpha: alpha).setFill()
            case .existingPlaneUsingExtent:
              UIColor(red: value, green: value, blue: value, alpha: alpha).setFill()
            default:
              UIColor.black.setFill()
          }
          UIRectFill(CGRect(x: x, y: y, width: 1, height: 1))
        }
    
        x += 1
      }
    
      y += 1
    
    }
    
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    imgView.image = image

    您可以根据需要调整颜色。无论如何,我认为这让我很好地了解了 ARKit 对世界的看法。

    【讨论】:

      【解决方案3】:

      arkit 也使用 AVCaptureSession,所以现在不可能在 AVCaptureSession 进行时使用 arscnview,因为它会调用委托 - (void)sessionWasInterrupted:(ARSession *)session; 唯一的方法是使用replay kit录制arkit屏幕。

      【讨论】:

      • 好的,但是在这种情况下,这个项目如何能够同时访问 AVCaptureSession 呢? github.com/AFathi/ARVideoKit
      • 如果使用 RealityKit,您可以从委托方法访问帧,该方法提供捕获的最新相机帧。
      【解决方案4】:

      在 iOS 13 中你可以使用 frameSemantics

      let configuration = ARWorldTrackingConfiguration()
      configuration.frameSemantics = .personSegmentationWithDepth
      

      然后,在 ARSessionDelegate 回调中,您可以从 ARFrame 访问estimatedDepthData

      func session(_ session: ARSession, didUpdate frame: ARFrame) {
           let estimatedDepthData = frame.estimatedDepthData
           ....
      }
      

      你也可以检查

      https://developer.apple.com/documentation/arkit/arframe/3152989-estimateddepthdata

      https://developer.apple.com/documentation/arkit/arframe/2984226-segmentationbuffer

      【讨论】:

      • 使用上述方法时,我得到以下异常:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'This set of frame semantics is not supported on this configuration' 所以我猜即使在 iOS13 上,这仍然不支持:\
      猜你喜欢
      • 2021-06-16
      • 2020-03-24
      • 2023-03-08
      • 1970-01-01
      • 2021-07-27
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多