Самый простой известный мне способ - использовать RxARKit
и применять оператор .throttle()
к session.rx.didUpdateFrame
.Я полагаю, что не стоит пропускать столько событий, потому что частота кадров не всегда гарантируется равной 60 кадр / с, поэтому лучше использовать .throttle()
, чтобы получить кадр не чаще, чем через столько же миллисекунд, независимо от того, что на самом делечастота кадров есть.Вы можете вставить результат этого в RxVision
, который позаботится о том, чтобы этот самый кадр был использован CoreML
.
import RxSwift
import RxARKit
import RxVision
let disposeBag = DisposeBag()
let mlRequest: RxVNCoreMLRequest<CVPixelBuffer> = VNCoreMLRequest.rx.request(model: model, imageCropAndScaleOption: .scaleFit)
mlRequest
.observable
.subscribe { [unowned self] (event) in
switch event {
case .next(let completion):
let cvPixelBuffer = completion.value
if let result = completion.request.results?[0] as? VNClassificationObservation {
os_log("results: %@", type: .debug, result.identifier)
}
default:
break
}
}
.disposed(by: disposeBag)
session
.rx
.didUpdateFrame
.throttle(1/20)
.subscribe { event in
switch event {
case .next(let didUpdateFrame):
let frame: ARFrame = didUpdateFrame.frame
let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: frame.capturedImage, orientation: .up, options: requestOptions)
do {
try imageRequestHandler.rx.perform([mlRequest], with: frame.capturedImage) } catch {
print(error)
}
break
default:
break
}
}
.disposed(by: disposeBag)