当应用程序不再需要时,如何从 运行 停止 CoreML?
How to stop CoreML from running when it's no longer needed in the app?
我的应用程序在 CoreML 模型上运行 Vision。运行机器学习模型的相机帧来自 ARKit sceneView(基本上是相机)。我有一个名为 loopCoreMLUpdate()
的方法,它会持续运行 CoreML,以便我们在新相机帧上保持 运行 模型。代码如下所示:
import UIKit
import SceneKit
import ARKit
class MyViewController: UIViewController {
var visionRequests = [VNRequest]()
let dispatchQueueML = DispatchQueue(label: "com.hw.dispatchqueueml") // A Serial Queue
override func viewDidLoad() {
super.viewDidLoad()
// Setup ARKit sceneview
// ...
// Begin Loop to Update CoreML
loopCoreMLUpdate()
}
// This is the problematic part.
// In fact - once it's run there's no way to stop it, is there?
func loopCoreMLUpdate() {
// Continuously run CoreML whenever it's ready. (Preventing 'hiccups' in Frame Rate)
dispatchQueueML.async {
// 1. Run Update.
self.updateCoreML()
// 2. Loop this function.
self.loopCoreMLUpdate()
}
}
func updateCoreML() {
///////////////////////////
// Get Camera Image as RGB
let pixbuff : CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
if pixbuff == nil { return }
let ciImage = CIImage(cvPixelBuffer: pixbuff!)
// Note: Not entirely sure if the ciImage is being interpreted as RGB, but for now it works with the Inception model.
// Note2: Also uncertain if the pixelBuffer should be rotated before handing off to Vision (VNImageRequestHandler) - regardless, for now, it still works well with the Inception model.
///////////////////////////
// Prepare CoreML/Vision Request
let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])
// let imageRequestHandler = VNImageRequestHandler(cgImage: cgImage!, orientation: myOrientation, options: [:]) // Alternatively; we can convert the above to an RGB CGImage and use that. Also UIInterfaceOrientation can inform orientation values.
///////////////////////////
// Run Image Request
do {
try imageRequestHandler.perform(self.visionRequests)
} catch {
print(error)
}
}
}
如您所见,循环效果是由 DispatchQueue
和标签 com.hw.dispatchqueueml
不断调用 loopCoreMLUpdate()
创建的。一旦不再需要 CoreML,有没有办法停止队列?完整代码是 here.
我建议在 viewDidLoad 中使用 运行 coreML 模型,您可以使用 ARSessionDelegate 函数。
func session(_ session: ARSession, didUpdate frame: ARFrame) 方法来获取帧,你可以设置标志,在这里当你想让模型工作和不工作时启用。
像下面这样:
func session(_ session: ARSession, didUpdate frame: ARFrame) {
// 这是我们分析框架的地方
// We return early if currentBuffer is not nil or the tracking state of camera is not normal
// TODO: - Core ML Functionality Commented
guard isMLFlow else { //
return
}
currentBuffer = frame.capturedImage
guard let buffer = currentBuffer, let image = UIImage(pixelBuffer: buffer) else { return }
<Code here to load model>
CoreMLManager.manager.updateClassifications(for: image)
}
我的应用程序在 CoreML 模型上运行 Vision。运行机器学习模型的相机帧来自 ARKit sceneView(基本上是相机)。我有一个名为 loopCoreMLUpdate()
的方法,它会持续运行 CoreML,以便我们在新相机帧上保持 运行 模型。代码如下所示:
import UIKit
import SceneKit
import ARKit
class MyViewController: UIViewController {
var visionRequests = [VNRequest]()
let dispatchQueueML = DispatchQueue(label: "com.hw.dispatchqueueml") // A Serial Queue
override func viewDidLoad() {
super.viewDidLoad()
// Setup ARKit sceneview
// ...
// Begin Loop to Update CoreML
loopCoreMLUpdate()
}
// This is the problematic part.
// In fact - once it's run there's no way to stop it, is there?
func loopCoreMLUpdate() {
// Continuously run CoreML whenever it's ready. (Preventing 'hiccups' in Frame Rate)
dispatchQueueML.async {
// 1. Run Update.
self.updateCoreML()
// 2. Loop this function.
self.loopCoreMLUpdate()
}
}
func updateCoreML() {
///////////////////////////
// Get Camera Image as RGB
let pixbuff : CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
if pixbuff == nil { return }
let ciImage = CIImage(cvPixelBuffer: pixbuff!)
// Note: Not entirely sure if the ciImage is being interpreted as RGB, but for now it works with the Inception model.
// Note2: Also uncertain if the pixelBuffer should be rotated before handing off to Vision (VNImageRequestHandler) - regardless, for now, it still works well with the Inception model.
///////////////////////////
// Prepare CoreML/Vision Request
let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])
// let imageRequestHandler = VNImageRequestHandler(cgImage: cgImage!, orientation: myOrientation, options: [:]) // Alternatively; we can convert the above to an RGB CGImage and use that. Also UIInterfaceOrientation can inform orientation values.
///////////////////////////
// Run Image Request
do {
try imageRequestHandler.perform(self.visionRequests)
} catch {
print(error)
}
}
}
如您所见,循环效果是由 DispatchQueue
和标签 com.hw.dispatchqueueml
不断调用 loopCoreMLUpdate()
创建的。一旦不再需要 CoreML,有没有办法停止队列?完整代码是 here.
我建议在 viewDidLoad 中使用 运行 coreML 模型,您可以使用 ARSessionDelegate 函数。 func session(_ session: ARSession, didUpdate frame: ARFrame) 方法来获取帧,你可以设置标志,在这里当你想让模型工作和不工作时启用。 像下面这样:
func session(_ session: ARSession, didUpdate frame: ARFrame) { // 这是我们分析框架的地方
// We return early if currentBuffer is not nil or the tracking state of camera is not normal
// TODO: - Core ML Functionality Commented
guard isMLFlow else { //
return
}
currentBuffer = frame.capturedImage
guard let buffer = currentBuffer, let image = UIImage(pixelBuffer: buffer) else { return }
<Code here to load model>
CoreMLManager.manager.updateClassifications(for: image)
}