ios - 如何在 iPhone XS 上使用 ARKit2 和 Vision (VNDetectFaceRectanglesRequest) 时修复 IOAF 代码 GPU 错误
问题描述
在 iPhone XS(使用 iOS 12.1.2 和 Xcode 10.1)上运行 ARKit 时,我在运行 Vision 代码检测面部边界时遇到错误和崩溃/挂起。
我得到的错误是:
2019-01-04 03:03:03.155867-0800 ARKit Vision Demo[12969:3307770] Execution of the command buffer was aborted due to an error during execution. Caused GPU Timeout Error (IOAF code 2)
2019-01-04 03:03:03.155786-0800 ARKit Vision Demo[12969:3307850] Execution of the command buffer was aborted due to an error during execution. Discarded (victim of GPU error/recovery) (IOAF code 5)
[SceneKit] Error: display link thread seems stuck
这发生在 iPhone XS 上,同时运行以下概念验证代码以重现错误(总是在运行应用程序的几秒钟内发生)- https://github.com/xta/ARKit-Vision-Demo
相关的 ViewController.swift 包含有问题的方法:
func classifyCurrentImage() {
guard let buffer = currentBuffer else { return }
let image = CIImage(cvPixelBuffer: buffer)
let options: [VNImageOption: Any] = [:]
let imageRequestHandler = VNImageRequestHandler(ciImage: image, orientation: self.imageOrientation, options: options)
do {
try imageRequestHandler.perform(self.requests)
} catch {
print(error)
}
}
func handleFaces(request: VNRequest, error: Error?) {
DispatchQueue.main.async {
guard let results = request.results as? [VNFaceObservation] else { return }
// TODO - something here with results
print(results)
self.currentBuffer = nil
}
}
使用 Apple 的 ARKit + Vision 的正确方法是什么VNDetectFaceRectanglesRequest
?得到神秘的 IOAF 代码错误是不正确的。
理想情况下,我还想使用 VNTrackObjectRequest 和 VNSequenceRequestHandler 来跟踪请求。
有关于将 VNDetectFaceRectanglesRequest 与 Vision(并且没有 ARKit)一起使用的不错的在线文档。Apple 在这里有一个页面(https://developer.apple.com/documentation/arkit/using_vision_in_real_time_with_arkit),我已经关注了该页面,但我仍然遇到错误/崩溃。
解决方案
对于经历过我刚刚尝试修复此确切错误的痛苦的其他人VNDetectRectanglesRequest
,这是我的解决方案:
似乎使用 CIImage:
let imageRequestHandler = VNImageRequestHandler(ciImage: image, orientation: self.imageOrientation, options: options)
导致 Metal 在我的内存图中保留了大量的内部函数。
我注意到 Apple 的示例项目都使用了这个:
let handler: VNImageRequestHandler! = VNImageRequestHandler(cvPixelBuffer: pixelBuffer,
orientation: orientation,
options: requestHandlerOptions)
切换到使用cvPixelBuffer
而不是CIImage
修复我所有的随机 GPU 超时错误!
我使用这些功能来获取orientation
(我正在使用后置摄像头。我认为您可能需要根据您要执行的操作为前置摄像头镜像):
func exifOrientationForDeviceOrientation(_ deviceOrientation: UIDeviceOrientation) -> CGImagePropertyOrientation {
switch deviceOrientation {
case .portraitUpsideDown:
return .right
case .landscapeLeft:
return .down
case .landscapeRight:
return .up
default:
return .left
}
}
func exifOrientationForCurrentDeviceOrientation() -> CGImagePropertyOrientation {
return exifOrientationForDeviceOrientation(UIDevice.current.orientation)
}
以下为options
:
var requestHandlerOptions: [VNImageOption: AnyObject] = [:]
let cameraIntrinsicData = CMGetAttachment(pixelBuffer, key: kCMSampleBufferAttachmentKey_CameraIntrinsicMatrix, attachmentModeOut: nil)
if cameraIntrinsicData != nil {
requestHandlerOptions[VNImageOption.cameraIntrinsics] = cameraIntrinsicData
}
希望这可以节省我失去的那一周的时间!
推荐阅读
- java - 如何在 Project Reactor 中将 DataBuffer 的通量转换为字节数组的 Mono?
- python-3.x - 针对不同的条件引发不同的异常
- javascript - 如何编写一个将对象推送到对象数组的函数?
- mysql - 何时添加列与添加相关表?
- flutter - 更新用户输入颤动的列
- javascript - 如果 div 有滚动条,如何获取滚动量
- bash - 替换分号后的字符串
- lua - 为什么这个 roblox 对话脚本不起作用
- javascript - 如何使用Javascript旋转从画布中的图像剪切的像素数组
- java - 我如何在 ubuntu 18.04 上设置 java 16