首页 > 解决方案 > 如何在 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),我已经关注了该页面,但我仍然遇到错误/崩溃。

标签: iosswiftcomputer-visionarkitapple-vision

解决方案


对于经历过我刚刚尝试修复此确切错误的痛苦的其他人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
}

希望这可以节省我失去的那一周的时间!


推荐阅读