8

我正在与Vision/AVKit框架一起开发 ARKit 应用程序。我的应用程序识别用于控制视频的手势(“胜利”、“Okey”、“拳头”手势)。所以我用MLModel我的手势分类。

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

var preferredFramesPerSecond: Int { get set }

但我的帧速率还是一样的——120 fps。

在此处输入图像描述

以下是我的制作方法:

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
            }
        }
    }
}

这是Apple对此的评价

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

例如,如果屏幕的最大刷新率为60fps,这也是视图设置为实际帧率的最高帧率。但是,如果您要求较低的帧速率,SceneKit 可能会选择、30或其他一些因素作为实际帧速率。出于这个原因,您需要选择您的应用程序可以始终保持的帧速率。默认值为fps。201560

如何将 View 的帧速率降低到 30 fps

4

1 回答 1

4

我解决了这个问题。SceneKit目前不允许更改帧速率 - 它具有固定的120 fps。所以我改用SpriteKit了框架——它允许我使用30 fps

在此处输入图像描述

以下是我的代码中的更改:

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)
    }
    // ..................
}
于 2018-12-01T21:26:57.430 回答