来自 ARKit 的深度数据
Depth data from ARKit
是否可以从 ARKit 访问 AVDepthData? ARFrame 包含相机的图像,但不包含其深度信息。
我试图创建一个单独的 AVCaptureSession 来接收 AVDepthData,但我无法 运行 AVCaptureSession 与 ARKit 同时。 ARSCNView 更新或 AVCaptureDepthDataOutputDelegate 被调用,但不会同时调用。
arkit 也使用 AVCaptureSession,所以现在不可能在 AVCaptureSession 进行时使用 arscnview,因为它会调用委托 - (void)sessionWasInterrupted:(ARSession *)session;
唯一的方法是使用replay kit来录制arkit屏幕。
正如在 this thread and mentioned in this video 中的回答,不,当您处于世界跟踪模式时,ARKit 不会为您提供 AVDepthData
。为您提供 AVDepthData
的唯一时间是当您使用 iPhone X 处于面部跟踪模式时。
在iOS13中你可以使用frameSemantics
let configuration = ARWorldTrackingConfiguration()
configuration.frameSemantics = .personSegmentationWithDepth
然后,在 ARSessionDelegate 回调中,您可以从 ARFrame 访问估计的深度数据
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
这需要很长时间(大约 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 对世界的看法。
是否可以从 ARKit 访问 AVDepthData? ARFrame 包含相机的图像,但不包含其深度信息。
我试图创建一个单独的 AVCaptureSession 来接收 AVDepthData,但我无法 运行 AVCaptureSession 与 ARKit 同时。 ARSCNView 更新或 AVCaptureDepthDataOutputDelegate 被调用,但不会同时调用。
arkit 也使用 AVCaptureSession,所以现在不可能在 AVCaptureSession 进行时使用 arscnview,因为它会调用委托 - (void)sessionWasInterrupted:(ARSession *)session; 唯一的方法是使用replay kit来录制arkit屏幕。
正如在 this thread and mentioned in this video 中的回答,不,当您处于世界跟踪模式时,ARKit 不会为您提供 AVDepthData
。为您提供 AVDepthData
的唯一时间是当您使用 iPhone X 处于面部跟踪模式时。
在iOS13中你可以使用frameSemantics
let configuration = ARWorldTrackingConfiguration()
configuration.frameSemantics = .personSegmentationWithDepth
然后,在 ARSessionDelegate 回调中,您可以从 ARFrame 访问估计的深度数据
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
这需要很长时间(大约 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 对世界的看法。