ARKit – SceneView以120 fps渲染其内容(但我需要30 fps)

时间:2018-12-01 13:37:30

标签: swift scenekit augmented-reality arkit apple-vision

我正在与Vision / AVKit框架一起开发ARKit应用。我的应用程序识别用于控制视频的手势(“胜利”,“奥奇”,“拳头”手势)。因此,我使用MLModel对手势进行分类。

应用程序运行正常,但视图的内容以 120 fps 呈现。我不需要这样的帧速率。这对于我的应用程序来说太多了,对CPU来说是沉重的负担。我试图使用SceneKit的instance属性将帧速率降低到 30 fps

var preferredFramesPerSecond: Int { get set }

但是我的帧频仍然是120 fps。

enter image description here

这就是我的方法:

import UIKit
import AVKit
import SceneKit
import ARKit
import Vision

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView! 
    var avPlayerView = AVPlayerViewController()
    private let player = AVQueuePlayer()
    let clips = ["AA", "BB", "CC"]
    private var token: NSKeyValueObservation?
    var number: Int = 0
    var once: Bool = true    
    let dispatchQueueML = DispatchQueue(label: "net.aaa.iii") 
    var visionRequests = [VNRequest]()

    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
        sceneView.showsStatistics = true
        sceneView.preferredFramesPerSecond = 30     // HERE IT GOES
        sceneView.rendersContinuously = true

        let scene = SCNScene()
        sceneView.scene = scene
        sceneView.scene.background.contents = UIColor.black.withAlphaComponent(0)

        guard let selectedModel = try? VNCoreMLModel(for: handsModel().model) else {
            fatalError("Couldn't load a model.")
        }

        let classificationRequest = VNCoreMLRequest(model: selectedModel, 
                                        completionHandler: classificationCompleteHandler)
        classificationRequest.imageCropAndScaleOption = VNImageCropAndScaleOption.centerCrop
        visionRequests = [classificationRequest]       
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.addAllVideosToPlayer()
        present(avPlayerView, animated: true,
                            completion: { self.player.play() })

        let configuration = ARWorldTrackingConfiguration()
        configuration.isAutoFocusEnabled = false
        sceneView.session.run(configuration)
    }

    func addAllVideosToPlayer() {
        avPlayerView.player = player
        // .........................
    }
    func toggleNextVideo() {
        // ..............
    }
    func togglePreviousVideo() {
        // ..............
    }

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

    DispatchQueue.main.async {
        if (topPredictionScore != nil && topPredictionScore! > 0.01) {  
            if (topPredictionName == "FistGesture") && (self.once == false) {
                self.once = true
            }
            if (topPredictionName == "OkeyGesture") && (self.once == true) {
                self.toggleNextVideo()
                self.once = false
            }
        }
    }
}

这是苹果公司所说的

  

SceneKit根据显示视图的屏幕的功能来选择与您喜欢的帧速率尽可能接近的实际帧速率。实际帧频通常是屏幕最大刷新率的一个因素,以提供一致的帧频。

     

例如,如果屏幕的最大刷新率是60 fps,则它也是视图设置为实际帧率的最高帧率。但是,如果您要求较低的帧速率,SceneKit可能会选择302015或其他因素作为实际帧速率。因此,您想选择一个您的应用可以持续保持的帧频。默认值为60 fps。

如何将视图的帧频降低到30 fps

1 个答案:

答案 0 :(得分:1)

我解决了这个问题。 SceneKit目前不允许更改帧频-它具有固定的 120 fps 。因此,我改用SpriteKit框架-它允许我使用 30 fps

enter image description here

这是我的代码中的更改:

import SpriteKit

class ViewController: UIViewController, ARSKViewDelegate {

    @IBOutlet weak var sceneView: ARSKView!
    // ....................

    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView.delegate = self
        sceneView.preferredFramesPerSecond = 30     // NOW IT WORKS 

        let scene = SKScene()
        sceneView.presentScene(scene)
    }
    // ..................
}