Skip to content
Back to skills

Ax Vision

ASecurity

Computer vision with Vision framework -- subject segmentation, hand/body pose, person detection, text recognition (OCR), barcode/QR detection, document scanning, DataScannerViewController, and diagnostics

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aigoswiftangularapiperformance

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add Kasempiternal/axiom-v2 --skill ax-vision --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ax Vision?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ax Vision
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kasempiternal-ax-vision/badge)](https://www.skillsdirectory.com/skills/kasempiternal-ax-vision)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ax-vision
description: Computer vision with Vision framework -- subject segmentation, hand/body pose, person detection, text recognition (OCR), barcode/QR detection, document scanning, DataScannerViewController, and diagnostics
license: MIT
---
# Vision Framework — Computer Vision

## Quick Patterns

### Subject Segmentation (iOS 17+)
```swift
let request = VNGenerateForegroundInstanceMaskRequest()
let handler = VNImageRequestHandler(cgImage: image)
try handler.perform([request])

guard let obs = request.results?.first as? VNInstanceMaskObservation else { return }
let mask = try obs.createScaledMask(for: obs.allInstances, croppedToInstancesContent: false)
```

### VisionKit Subject Lifting (iOS 16+)
```swift
let interaction = ImageAnalysisInteraction()
interaction.preferredInteractionTypes = .imageSubject
imageView.addInteraction(interaction)
```

### Hand Pose Detection (iOS 14+)
```swift
let request = VNDetectHumanHandPoseRequest()
request.maximumHandCount = 2
try handler.perform([request])
let thumbTip = try observation.recognizedPoint(.thumbTip) // 21 landmarks per hand
```

### Text Recognition (OCR)
```swift
let request = VNRecognizeTextRequest()
request.recognitionLevel = .accurate // or .fast for real-time
request.recognitionLanguages = ["en-US"]
try handler.perform([request])
for obs in request.results as? [VNRecognizedTextObservation] ?? [] {
    let text = obs.topCandidates(1).first?.string
}
```

### Barcode/QR Detection
```swift
let request = VNDetectBarcodesRequest()
request.symbologies = [.qr, .ean13] // specify only what you need
try handler.perform([request])
for barcode in request.results as? [VNBarcodeObservation] ?? [] {
    let payload = barcode.payloadStringValue
}
```

### DataScannerViewController (iOS 16+ live camera)
```swift
let scanner = DataScannerViewController(
    recognizedDataTypes: [.barcode(symbologies: [.qr]), .text(textContentType: .URL)],
    qualityLevel: .balanced, recognizesMultipleItems: false,
    isHighFrameRateTrackingEnabled: true, isGuidanceEnabled: true
)
scanner.delegate = self
present(scanner, animated: true) { try? scanner.startScanning() }
```

### Document Scanning
```swift
// Built-in UI: VNDocumentCameraViewController (iOS 13+)
// Programmatic: VNDetectDocumentSegmentationRequest (iOS 15+)
// Structured extraction: RecognizeDocumentsRequest (iOS 26+)
```

---

## Decision Tree

```
What do you need?
|
+-- Isolate subject from background?
|   +-- System UI (long-press to lift) -> VisionKit ImageAnalysisInteraction
|   +-- Custom pipeline / HDR / large images -> VNGenerateForegroundInstanceMaskRequest
|   +-- Exclude hands from object -> Combine subject mask + hand pose
|
+-- Segment people?
|   +-- All people, one mask -> VNGeneratePersonSegmentationRequest (iOS 15+)
|   +-- Separate mask per person (up to 4) -> VNGeneratePersonInstanceMaskRequest (iOS 17+)
|
+-- Detect hand pose / gestures?
|   +-- Just hand location -> VNDetectHumanRectanglesRequest
|   +-- 21 landmarks -> VNDetectHumanHandPoseRequest (pinch = thumb-index distance)
|
+-- Detect body pose?
|   +-- 2D normalized -> VNDetectHumanBodyPoseRequest (18 joints, iOS 14+)
|   +-- 3D real-world -> VNDetectHumanBodyPose3DRequest (17 joints, iOS 17+)
|   +-- Action classification -> Body pose + CreateML model
|
+-- Recognize text?
|   +-- Real-time camera + need UI -> DataScannerViewController (iOS 16+)
|   +-- Processing image -> VNRecognizeTextRequest (.fast or .accurate)
|   +-- Structured docs (tables) -> RecognizeDocumentsRequest (iOS 26+)
|
+-- Detect barcodes/QR?
|   +-- Real-time camera + UI -> DataScannerViewController
|   +-- Processing image -> VNDetectBarcodesRequest
|
+-- Scan documents?
|   +-- Built-in UI -> VNDocumentCameraViewController (iOS 13+)
|   +-- Custom pipeline -> VNDetectDocumentSegmentationRequest
|   +-- Structured data -> RecognizeDocumentsRequest (iOS 26+)
|
+-- Issue / not working?
    -> See Diagnostics section below
```

---

## Anti-Patterns

### Processing on main thread
Vision is resource-intensive. Always run on background queue. Blocking main thread freezes UI.

### Ignoring confidence scores
Low confidence landmarks are unreliable (occlusion, blur, edge of frame). Always check `point.confidence > 0.5`.

### Forgetting coordinate conversion
Vision uses lower-left origin, normalized 0-1. UIKit uses top-left. Flip Y: `uiY = (1 - visionY) * height`.

### Setting maximumHandCount too high
Performance scales with count. Set to minimum needed (typically 2).

### Using ARKit when Vision suffices
Vision body pose works offline on still images. ARKit requires rear camera, AR session, supported devices.

### Enabling all barcode symbologies
Fewer symbologies = faster scanning. Specify only what you need.

### Processing every camera frame for scanning
Skip frames (every 3rd), use region of interest, use `.fast` recognition level.

### Using VNImageRequestHandler for video
Use `VNSequenceRequestHandler` for video/camera -- maintains inter-frame state for temporal smoothing. Creating a new `VNImageRequestHandler` per frame discards temporal context, causing jittery results.

---

## Deep Patterns

### Request Handlers

**VNImageRequestHandler**: Single image analysis. Initialize with CGImage/CIImage/CVPixelBuffer/URL. One handler per image.

**VNSequenceRequestHandler**: Video/camera sequences. Create once, reuse across frames. Maintains inter-frame state for smoother results with pose, segmentation, and document detection.

### Subject Instance Masks

`VNInstanceMaskObservation` provides:
- `allInstances` (IndexSet of foreground instances)
- `instanceMask` (CVPixelBuffer with UInt8 labels, 0=background)
- `instanceAtPoint(_:)` for tap-to-select
- `createScaledMask(for:croppedToInstancesContent:)` -- soft segmentation mask

Use `croppedToInstancesContent: false` for compositing (matches input resolution). Use `true` for tight crop around selection.

### Composite with CoreImage
```swift
let filter = CIFilter(name: "CIBlendWithMask")!
filter.setValue(CIImage(cgImage: sourceImage), forKey: kCIInputImageKey)
filter.setValue(CIImage(cvPixelBuffer: mask), forKey: kCIInputMaskImageKey)
filter.setValue(newBackground, forKey: kCIInputBackgroundImageKey)
let composited = filter.outputImage
```

### Hand Landmarks (21 points)
Wrist (1) + Thumb (4: CMC, MP, IP, Tip) + 4 Fingers (4 each: MCP, PIP, DIP, Tip).
Groups: `.all`, `.thumb`, `.indexFinger`, `.middleFinger`, `.ringFinger`, `.littleFinger`.
Chirality: `observation.chirality` (.left/.right/.unknown).

### Gesture Recognition (Pinch example)
```swift
let thumbTip = try observation.recognizedPoint(.thumbTip)
let indexTip = try observation.recognizedPoint(.indexTip)
guard thumbTip.confidence > 0.5, indexTip.confidence > 0.5 else { return }
let distance = hypot(thumbTip.location.x - indexTip.location.x, thumbTip.location.y - indexTip.location.y)
let isPinching = distance < 0.05
```
Use evidence accumulation over multiple frames (3+ frames of pinch before triggering).

### Body Landmarks (18 2D / 17 3D)
Face (5): nose, eyes, ears. Arms (6): shoulders, elbows, wrists. Torso (7): neck, shoulders, hips, root. Legs (6): hips, knees, ankles.
Groups: `.all`, `.face`, `.leftArm`, `.rightArm`, `.torso`, `.leftLeg`, `.rightLeg`.

3D body pose (iOS 17+): returns `simd_float4x4` positions in meters, estimated `bodyHeight`, `cameraOriginMatrix`.

### Text Recognition Details

| Level | Speed | Accuracy | Best For |
|-------|-------|----------|----------|
| `.fast` | Real-time | Good | Camera, signs, large text |
| `.accurate` | Slower | Excellent | Documents, receipts, handwriting |

Key properties: `recognitionLanguages` (order matters -- first determines ML model), `usesLanguageCorrection` (disable for codes/serials), `customWords` (domain vocabulary), `minimumTextHeight`, `regionOfInterest`.

For real-time scanning, build evidence over frames with a string tracker (accumulate same result N times before accepting).

### Barcode Revisions
- Rev 1 (iOS 11+): One code at a time, 1D codes return lines
- Rev 2 (iOS 15+): Codabar, GS1, MicroQR, better ROI
- Rev 3 (iOS 16+): ML-based, multiple codes, better bounding boxes

### Document Extraction (iOS 26+)
```swift
let request = RecognizeDocumentsRequest()
let observations = try await request.perform(on: imageData)
guard let doc = observations.first?.document else { return }

for table in doc.tables {
    for row in table.rows { for cell in row { print(cell.content.text.transcript) } }
}

for data in doc.text.detectedData {
    switch data.match.details {
    case .emailAddress(let e): print(e.emailAddress)
    case .phoneNumber(let p): print(p.phoneNumber)
    case .link(let url): print(url)
    default: break
    }
}
```

### Person Instance Segmentation
Up to 4 people separately. >4 people: may miss or combine. Use `VNDetectFaceRectanglesRequest` to count, fallback to single mask if crowded.

### Isolate Object Excluding Hand
Combine `VNGenerateForegroundInstanceMaskRequest` (class-agnostic) + `VNDetectHumanHandPoseRequest` (hand landmarks) -> calculate convex hull of hand points -> subtract hand region from subject mask using CoreImage -> get bounding box of remaining mask.

---

## Diagnostics

### Root Causes (by frequency)
1. Environment (lighting, occlusion, edge of frame) -- 40%
2. Confidence threshold (ignoring low confidence) -- 30%
3. Threading (blocking main thread) -- 15%
4. Coordinates (lower-left vs top-left) -- 10%
5. API availability (iOS version) -- 5%

### Symptom Table

| Symptom | Likely Cause | Fix |
|---------|-------------|-----|
| Subject not detected | Small/blurry/low contrast | Crop closer, improve lighting |
| Hand landmarks nil/low confidence | Edge of frame, parallel to camera, gloves | Adjust framing, prompt user |
| Body pose skipped frames | Person bent over, flowing clothing | Prompt upright, increase contrast |
| UI freezes | Main thread processing | Move to background queue |
| Overlays in wrong position | Coordinate conversion | Flip Y: `(1 - visionY) * height` |
| >4 people missing | Instance mask limit | Fallback to single person mask |
| Text not detected | Blurry, small, stylized font | Lower `minimumTextHeight`, use `.accurate` |
| Wrong characters (OCR) | Language correction fixing codes | Disable `usesLanguageCorrection` for codes |
| Text recognition slow | `.accurate` for real-time | Switch to `.fast`, use `regionOfInterest` |
| Barcode not detected | Wrong symbology, code too small | Don't filter symbologies, crop closer |
| DataScanner blank | Camera denied, not supported | Check `isSupported` + `isAvailable` first |
| Document edges not detected | Low contrast, non-rectangular | Use contrasting background |
| Perspective correction wrong | Corner order / coordinate system | Normalize corners, convert coordinates |

### Quick Diagnostic Code
```swift
// 1. Check detection
try handler.perform([request])
print("Results: \(request.results?.count ?? 0)")

// 2. Check confidence (for pose)
for (key, point) in try observation.recognizedPoints(.all) {
    if point.confidence < 0.3 { print("LOW: \(key)") }
}

// 3. Check threading
assert(!Thread.isMainThread, "Vision must run on background queue")
```

---

## Related

- `ax-camera` -- Camera capture pipeline (feeds into Vision)
- `ax-coreml` -- Custom ML models (when Vision APIs don't cover your use case)
- `ax-foundation-models` -- Apple on-device LLM (text generation, not computer vision)
- WWDC: 2019-234, 2021-10041, 2022-10024, 2022-10025, 2025-272, 2023-10176

### API Availability Reference

| API | iOS |
|-----|-----|
| VNDetectBarcodesRequest | 11+ |
| VNDetectFaceRectanglesRequest/Landmarks | 11+ |
| VNDocumentCameraViewController | 13+ |
| VNRecognizeTextRequest | 13+ |
| VNDetectHumanHandPoseRequest | 14+ |
| VNDetectHumanBodyPoseRequest | 14+ |
| VNGeneratePersonSegmentationRequest | 15+ |
| VNDetectDocumentSegmentationRequest | 15+ |
| DataScannerViewController | 16+ |
| VisionKit ImageAnalysisInteraction | 16+ |
| VNGenerateForegroundInstanceMaskRequest | 17+ |
| VNGeneratePersonInstanceMaskRequest | 17+ |
| VNDetectHumanBodyPose3DRequest | 17+ |
| RecognizeDocumentsRequest | 26+ |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.