-1

我正在开发一个具有 Vision 框架功能(处理 CoreML 模型)的 ARKit 应用程序。

loopCoreMLUpdate()函数生成一个循环,导致非常高的能量影响(CPU=70%,GPU=66%)。

如何处理此任务并将能量影响降低到低水平

这个循环问题的解决方法是什么,可以帮助我减少 CPU/GPU 工作量

这是我的代码:

import UIKit
import SpriteKit
import ARKit
import Vision

class ViewController: UIViewController, ARSKViewDelegate {

    @IBOutlet weak var sceneView: ARSKView!
    let dispatchQueueML = DispatchQueue(label: "AI")
    var visionRequests = [VNRequest]()

    // .........................................
    // .........................................

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let configuration = AROrientationTrackingConfiguration()
        sceneView.session.run(configuration)

        loopCoreMLUpdate()
    }

    func loopCoreMLUpdate() {          
        dispatchQueueML.async {
            self.loopCoreMLUpdate()  // SELF-LOOP LEADS TO A VERY HIGH IMPACT
            self.updateCoreML()
        }
    }

    func updateCoreML() {
        let piBuffer: CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
        if piBuffer == nil { return }
        let ciImage = CIImage(cvPixelBuffer: piBuffer!)
        let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])

        do {
            try imageRequestHandler.perform(self.visionRequests)
        } catch {
            print(error)
        }
    }
    // .........................................
    // .........................................
}
4

1 回答 1

2

是的,你标记的那条线肯定是个大问题。你不是在这里循环;您正在尽可能快地生成新的异步任务,甚至在前一个任务完成之前。在任何情况下,您都试图比创建它们更快地捕获 CVPixelBuffer,这是一种巨大的浪费。

如果要捕获帧,则无需创建紧密循环来对其进行采样。您将自己设置为 ARSessionDelegate 并实施session(_:didUpdate:)。当有新框架可用时,系统会告诉您。(可以创建自己的渲染循环,但您不在这里这样做,除非您真的需要自己的渲染管道,否则不应该这样做。)

请记住,您将很快收到很多帧。30fps 或 60fps 很常见,但也可以高达 120fps。您不能使用所有时间片(其他事情也需要处理器时间)。关键是您通常无法跟上帧速率,并且需要缓冲以供以后处理,或丢帧,或两者兼而有之。这是实时处理中非常正常的一部分。

对于这种分类系统,您可能希望选择您的实际帧速率,可能低至 10-20fps,并跳过帧以保持该速率。对数十个几乎相同的帧进行分类可能没有帮助。

也就是说,请确保您已阅读实时捕获中的识别对象。感觉这就是您正在尝试做的事情,并且有很好的示例代码可用。

于 2018-12-02T15:55:58.403 回答