import Vision import AppKit // Gibt Vision ein Merkmal her, mit dem sich ein Gesicht *wiedererkennen* lässt? // // Öffentlich liefert Vision Rechtecke und Landmarken — beides sagt, wo ein // Gesicht ist, nicht wessen. Für den Vergleich braucht es einen Vektor mit // Abstandsmaß. Geprüft werden zwei Wege. print("=== Weg 1: VNGenerateFaceprintRequest (privat) ===") for name in ["VNGenerateFaceprintRequest", "VNFaceprintObservation", "VNFaceObservation", "VNGenerateImageFeaturePrintRequest"] { print(" \(name): \(NSClassFromString(name) != nil ? "vorhanden" : "FEHLT")") } print("\n=== Weg 2: VNGenerateImageFeaturePrintRequest (öffentlich) ===") /// Ein Testbild: eine Fläche mit einem Muster, damit die Merkmale nicht leer sind. func testImage(hue: CGFloat, shift: CGFloat) -> CGImage { let size = 224 let space = CGColorSpaceCreateDeviceRGB() let ctx = CGContext(data: nil, width: size, height: size, bitsPerComponent: 8, bytesPerRow: 0, space: space, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)! ctx.setFillColor(NSColor(hue: hue, saturation: 0.6, brightness: 0.9, alpha: 1).cgColor) ctx.fill(CGRect(x: 0, y: 0, width: size, height: size)) ctx.setFillColor(NSColor.black.cgColor) for i in 0..<6 { ctx.fillEllipse(in: CGRect(x: 20 + CGFloat(i) * 30 + shift, y: 60 + shift, width: 24, height: 34)) } return ctx.makeImage()! } func featurePrint(_ image: CGImage) -> VNFeaturePrintObservation? { let request = VNGenerateImageFeaturePrintRequest() let handler = VNImageRequestHandler(cgImage: image, options: [:]) do { try handler.perform([request]) return request.results?.first as? VNFeaturePrintObservation } catch { print(" Fehler: \(error.localizedDescription)") return nil } } let a = featurePrint(testImage(hue: 0.1, shift: 0)) let aAgain = featurePrint(testImage(hue: 0.1, shift: 2)) // fast dasselbe let b = featurePrint(testImage(hue: 0.6, shift: 40)) // deutlich anders if let a, let aAgain, let b { print(" Merkmalslänge: \(a.elementCount) Elemente, Typ \(a.elementType.rawValue)") var near: Float = 0, far: Float = 0 try? a.computeDistance(&near, to: aAgain) try? a.computeDistance(&far, to: b) print(" Abstand ähnlich: \(near)") print(" Abstand verschieden: \(far)") print(" Trennschärfe: \(far > near ? "gegeben" : "NICHT gegeben") (Verhältnis \(far / max(near, 0.0001)))") } else { print(" Merkmale nicht berechenbar") } print("\n=== Gesichtserkennung selbst ===") let request = VNDetectFaceLandmarksRequest() let handler = VNImageRequestHandler(cgImage: testImage(hue: 0.1, shift: 0), options: [:]) try? handler.perform([request]) print(" Landmarken-Anfrage lief durch, \(request.results?.count ?? 0) Gesichter im Testmuster (0 erwartet)")