Add more detailed logging to object detection flow

This commit is contained in:
2026-01-24 13:08:30 -05:00
parent 316db3e1eb
commit 7d3794767f
2 changed files with 27 additions and 1 deletions

View File

@@ -241,15 +241,23 @@ final class EditorViewModel {
} }
private func handleObjectTap(at point: CGPoint, in image: CGImage) async throws { private func handleObjectTap(at point: CGPoint, in image: CGImage) async throws {
DebugLogger.log("handleObjectTap at \(point)")
DebugLogger.log("Calling maskingService.generateForegroundMask...")
let mask = try await maskingService.generateForegroundMask(at: point, in: image) let mask = try await maskingService.generateForegroundMask(at: point, in: image)
DebugLogger.log("generateForegroundMask returned")
DebugLogger.imageInfo("Object mask", image: mask)
guard let mask = mask else { guard let mask = mask else {
DebugLogger.log("No mask returned - prompting for brush tool")
errorMessage = "Couldn't detect object. Try the brush tool to select manually." errorMessage = "Couldn't detect object. Try the brush tool to select manually."
return return
} }
maskPreview = mask maskPreview = mask
showingMaskConfirmation = true showingMaskConfirmation = true
DebugLogger.state("Object mask preview set, showing confirmation")
} }
private func handleWireTap(at point: CGPoint, in image: CGImage) async throws { private func handleWireTap(at point: CGPoint, in image: CGImage) async throws {

View File

@@ -157,35 +157,48 @@ actor MaskingService {
} }
func generateForegroundMask(at point: CGPoint, in image: CGImage) async throws -> CGImage? { func generateForegroundMask(at point: CGPoint, in image: CGImage) async throws -> CGImage? {
DebugLogger.processing("generateForegroundMask at \(point)")
DebugLogger.log("Image: \(image.width)x\(image.height)")
let request = VNGenerateForegroundInstanceMaskRequest() let request = VNGenerateForegroundInstanceMaskRequest()
DebugLogger.log("Created VNGenerateForegroundInstanceMaskRequest")
let handler = VNImageRequestHandler(cgImage: image, options: [:]) let handler = VNImageRequestHandler(cgImage: image, options: [:])
DebugLogger.log("Created VNImageRequestHandler, performing request...")
do { do {
try handler.perform([request]) try handler.perform([request])
DebugLogger.log("Vision request completed successfully")
} catch { } catch {
DebugLogger.error("Vision request failed", error: error)
throw MaskingError.requestFailed(error) throw MaskingError.requestFailed(error)
} }
guard let result = request.results?.first else { guard let result = request.results?.first else {
DebugLogger.log("No results from Vision request")
return nil return nil
} }
DebugLogger.log("Got Vision result with \(result.allInstances.count) instances")
// Normalize point to Vision coordinates (0-1, origin bottom-left) // Normalize point to Vision coordinates (0-1, origin bottom-left)
let visionPoint = CGPoint( let visionPoint = CGPoint(
x: point.x / CGFloat(image.width), x: point.x / CGFloat(image.width),
y: 1.0 - point.y / CGFloat(image.height) y: 1.0 - point.y / CGFloat(image.height)
) )
DebugLogger.log("Vision point: \(visionPoint)")
// Find instance at tap point // Find instance at tap point
let instances = result.allInstances let instances = result.allInstances
var targetInstance: IndexSet? var targetInstance: IndexSet?
DebugLogger.log("Checking \(instances.count) instances for tap point...")
for instance in instances { for instance in instances {
let indexSet = IndexSet(integer: instance) let indexSet = IndexSet(integer: instance)
if let maskPixelBuffer = try? result.generateScaledMaskForImage(forInstances: indexSet, from: handler) { if let maskPixelBuffer = try? result.generateScaledMaskForImage(forInstances: indexSet, from: handler) {
// Check if point is within this instance's mask // Check if point is within this instance's mask
if isPoint(visionPoint, inMask: maskPixelBuffer, imageSize: CGSize(width: image.width, height: image.height)) { if isPoint(visionPoint, inMask: maskPixelBuffer, imageSize: CGSize(width: image.width, height: image.height)) {
DebugLogger.log("Found instance \(instance) at tap point")
targetInstance = indexSet targetInstance = indexSet
break break
} }
@@ -193,11 +206,16 @@ actor MaskingService {
} }
guard let instance = targetInstance else { guard let instance = targetInstance else {
DebugLogger.log("No instance found at tap point")
return nil return nil
} }
DebugLogger.log("Generating mask for selected instance...")
let maskPixelBuffer = try result.generateScaledMaskForImage(forInstances: instance, from: handler) let maskPixelBuffer = try result.generateScaledMaskForImage(forInstances: instance, from: handler)
return convertPixelBufferToCGImage(maskPixelBuffer) DebugLogger.log("Mask generated, converting to CGImage...")
let cgImage = convertPixelBufferToCGImage(maskPixelBuffer)
DebugLogger.imageInfo("Generated mask", image: cgImage)
return cgImage
} }
func generateAllForegroundMasks(in image: CGImage) async throws -> CGImage? { func generateAllForegroundMasks(in image: CGImage) async throws -> CGImage? {