Hi Fellow devs, This is only nominally related to the Vision SDK. I want to detect faces and update my UI based on the results.
The code below does not compile. The line that begins with let request =
throws the following error:
Escaping closure captures mutating 'self' parameter
I understand the problem with trying to modify a struct from within a closure, but I don't know what I'd need to change to be able to update the UI, based on the results from the face detection request.
Any suggestions? thanks, in advance
import SwiftUI
import Vision
struct ContentView: View {
@State var uiImage = UIImage(named: "Ollie")!
@State var faceCount = 0
init() {
let handler = VNImageRequestHandler(cgImage: uiImage.cgImage!, options: [:])
let request = VNDetectFaceRectanglesRequest { _, _ in
self.faceCount = 3
}
try! handler.perform([request])
}
var body: some View {
VStack {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fit)
Text("faces: \(faceCount)")
}
.padding()
}
}
Replace mrbean
with another image in the assets folder.
import SwiftUI
@main
struct DevForumVisionApp: App {
@StateObject var model = VisionModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(model)
}
}
}
import SwiftUI
import Vision
struct ContentView: View {
@EnvironmentObject private var model: VisionModel
var body: some View {
VStack {
Image(uiImage: model.uiImage)
.resizable()
.aspectRatio(contentMode: .fit)
Text("faces: \(model.faceCount)")
}
.onAppear(perform: {
model.run()
})
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(VisionModel())
}
}
class VisionModel: ObservableObject {
@Published private(set) var uiImage = UIImage(named: "mrbean")!
@Published private(set) var faceCount: Int = 0
private(set) var request: VNDetectFaceRectanglesRequest?
private(set) var handler: VNImageRequestHandler?
private(set) var requestOptions = [VNImageOption: Any]()
init() {
}
func run() {
handler = VNImageRequestHandler(cgImage: uiImage.cgImage!, options: requestOptions)
self.request = VNDetectFaceRectanglesRequest() { [weak self] request, error in
if error == nil, let count = request.results?.count {
self?.faceCount = count
}
}
if let request, let handler {
do {
try handler.perform([request])
} catch {
print(error)
}
}
}
}