ARKit – sceneView 以 120 fps 渲染其内容(但我需要 30 fps)
ARKit – sceneView renders its content at 120 fps (but I need 30 fps)
我正在开发 ARKit 应用以及 Vision
/AVKit
框架。我的应用程序识别用于控制视频的手势(“胜利”、“好”、“拳头”手势)。所以我使用 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 chooses an actual frame rate that is as close as possible to your preferred frame rate based on the capabilities of the screen the view is displayed on. The actual frame rate is usually a factor of the maximum refresh rate of the screen to provide a consistent frame rate.
For example, if the maximum refresh rate of the screen is 60
fps, that is also the highest frame rate the view sets as the actual frame rate. However, if you ask for a lower frame rate, SceneKit might choose 30
, 20
, 15
or some other factor to be the actual frame rate. For this reason, you want to choose a frame rate that your app can consistently maintain. The default value is 60
fps.
如何将视图的帧率降低到 30 fps?
我解决了这个问题。 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)
}
// ..................
}
我正在开发 ARKit 应用以及 Vision
/AVKit
框架。我的应用程序识别用于控制视频的手势(“胜利”、“好”、“拳头”手势)。所以我使用 MLModel
对我的手势进行分类。
应用程序运行良好,但视图内容以 120 fps 呈现。我不需要这样的帧率。这对我的应用程序来说太多了,对 CPU 来说是一个沉重的负担。我尝试使用 SceneKit 的实例 属性:
将帧速率降低到 30 fpsvar 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 chooses an actual frame rate that is as close as possible to your preferred frame rate based on the capabilities of the screen the view is displayed on. The actual frame rate is usually a factor of the maximum refresh rate of the screen to provide a consistent frame rate.
For example, if the maximum refresh rate of the screen is
60
fps, that is also the highest frame rate the view sets as the actual frame rate. However, if you ask for a lower frame rate, SceneKit might choose30
,20
,15
or some other factor to be the actual frame rate. For this reason, you want to choose a frame rate that your app can consistently maintain. The default value is60
fps.
如何将视图的帧率降低到 30 fps?
我解决了这个问题。 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)
}
// ..................
}