# Masking Service ## Description Wrapper around Vision framework for generating masks from user taps and contour detection. ## Acceptance Criteria - [ ] `MaskingService` class with methods: - `func generatePersonMask(at point: CGPoint, in image: CGImage) async throws -> CGImage?` - `func generateForegroundMask(at point: CGPoint, in image: CGImage) async throws -> CGImage?` - `func detectContours(in image: CGImage) async throws -> [VNContour]` - [ ] Uses `VNGenerateForegroundInstanceMaskRequest` for person/object masks - [ ] Uses `VNDetectContoursRequest` for wire/line detection - [ ] Mask dilation method: `func dilate(mask: CGImage, by pixels: Int) -> CGImage` - [ ] Mask feathering method: `func feather(mask: CGImage, amount: Float) -> CGImage` - [ ] Returns `nil` when no mask detected at tap location (not an error) - [ ] Unit tests for mask operations ## Technical Notes - `VNGenerateForegroundInstanceMaskRequest` requires iOS 17+ - Point coordinates must be normalized (0-1) for Vision requests - Instance masks can identify multiple separate foreground objects - Use `indexesOfInstancesContainingPoint` to find which instance was tapped ## Edge Cases - No person/object at tap location: return nil, caller shows fallback UI - Multiple overlapping instances: return the one containing the tap point - Vision request fails: throw descriptive error - Image orientation: ensure coordinates are transformed correctly