Skip to content

Add face detection#787

Merged
scarlac merged 6 commits into
teslamotors:masterfrom
mike-rbrts:master
May 12, 2026
Merged

Add face detection#787
scarlac merged 6 commits into
teslamotors:masterfrom
mike-rbrts:master

Conversation

@mike-rbrts
Copy link
Copy Markdown
Contributor

Summary

Adds real-time face detection to <Camera />, available on both iOS and Android via a single cross-platform API. Face detection is opt-in (faceDetectionEnabled) and emits one event per frame with bounding boxes (normalized 0–1, top-left, preview-space) and head-pose Euler angles (degrees) for each detected face.

API added

<Camera
  faceDetectionEnabled
  faceDetectionThrottleMs={100}              // optional, defaults to 100ms (~10 events/sec)
  onFaceDetected={(e) => {
    // e.nativeEvent.faces: FaceData[]
    // each: { id, yaw, pitch, roll, boundsX, boundsY, boundsWidth, boundsHeight }
  }}
  onFaceDetectionInstallStatus={(e) => {     // Android only
    // e.nativeEvent.state: 'pending' | 'downloading' | 'installing' | 'ready' | 'failed'
  }}
/>
Prop / Event Platform Notes
faceDetectionEnabled: boolean iOS + Android Opt-in. Default false — zero cost when off.
faceDetectionThrottleMs: number iOS + Android Min ms between emits. Default 100. Hot-updatable on Android without rebinding.
onFaceDetected: (event) => void iOS + Android Empty faces array when no faces detected.
onFaceDetectionInstallStatus: (event) => void Android only Reports MLKit module download progress (see Android note).

Implementation

iOS — Apple Vision (VNDetectFaceRectanglesRequest, revision 3). Built into the OS, no extra dependency, no module download.

  • New FaceDetector.swift owns the Vision request, throttling, and coordinate transform.
  • RealCamera attaches an AVCaptureVideoDataOutput only while detection is enabled, dispatching frames on a dedicated visionQueue (off the session queue and off main).
  • currentVisionOrientation is recomputed on device-orientation and camera-flip changes so Vision sees an upright image; front-camera mirroring is handled via *Mirrored CGImagePropertyOrientation values.
  • SimulatorCamera gets no-op stubs.

Android — Google ML Kit, unbundled variant (com.google.android.gms:play-services-mlkit-face-detection:17.1.0). The model is downloaded by Play Services on first use rather than bundled in the APK.

  • New FaceAnalyzer.kt (an ImageAnalysis.Analyzer) owns module-install lifecycle, throttling, and detection.
  • A second ImageAnalysis use case is added to the existing CameraX binding so face detection coexists with barcode scanning.
  • MIN_FACE_SIZE = 0.15, PERFORMANCE_MODE_FAST, tracking enabled, no landmarks/classifications — keeps inference cheap.
  • Front-camera bounding boxes are X-mirrored in CKCamera.onFaceDetected so JS coordinates match what the user sees in the (auto-mirrored) preview.
  • Module-install state is surfaced to JS via onFaceDetectionInstallStatus so apps can show a loading state on first run. README documents the optional <meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="face" /> manifest tag for apps that want Play Services to pre-download the model after install (no APK size impact).

Notes for reviewers

  • Additive only. No breaking changes; no existing prop/event renamed or repurposed.
  • Zero runtime cost when disabled. No AVCaptureVideoDataOutput (iOS) or face ImageAnalysis use case (Android) is attached unless faceDetectionEnabled is true.
  • Throttling is enforced natively so the bridge isn't crossed for frames JS doesn't need.
  • Both architectures supported — Old Arch (CKCameraManager.mm / oldarch/CKCameraManager.kt) and Fabric (CKCameraViewComponentView.mm / newarch/CKCameraManager.kt). Codegen spec updated in src/specs/CameraNativeComponent.ts.
  • Coordinate parity across platforms. Both platforms emit boundsX/Y/Width/Height as 0–1 in top-left preview space, with positive yaw = head-turned-right. iOS converts Vision's bottom-left origin and radians; Android divides MLKit's pixel rectangles by upright image dimensions and mirrors the front camera.
  • One new Android dependency: play-services-mlkit-face-detection:17.1.0 (unbundled — does not increase APK size).

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in, cross-platform face detection API to <Camera />, emitting per-frame face bounding boxes (normalized) and head-pose angles, implemented natively with Apple Vision (iOS) and ML Kit (Android), plus docs and an example UI.

Changes:

  • Adds new JS/Fabric props + event types for face detection (faceDetectionEnabled, faceDetectionThrottleMs, onFaceDetected, onFaceDetectionInstallStatus).
  • Implements iOS face detection via AVCaptureVideoDataOutput + Vision request with native throttling.
  • Implements Android face detection via a CameraX ImageAnalysis analyzer using unbundled ML Kit + install-state eventing.

Reviewed changes

Copilot reviewed 20 out of 22 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/specs/CameraNativeComponent.ts Extends codegen spec with face detection props/events.
src/CameraProps.ts Adds public TS types for face payloads + install state.
src/Camera.ios.tsx Applies -1 sentinel default for faceDetectionThrottleMs.
src/Camera.android.tsx Applies -1 sentinel default for faceDetectionThrottleMs.
ios/ReactNativeCameraKit/SimulatorCamera.swift Adds no-op protocol stubs for simulator implementation.
ios/ReactNativeCameraKit/RealCamera.swift Adds Vision queue, video output plumbing, orientation handling, and per-frame callback.
ios/ReactNativeCameraKit/FaceDetector.swift New Vision-based detector with throttling + coordinate adjustment.
ios/ReactNativeCameraKit/CameraView.swift Wires new props into camera instance + event emission.
ios/ReactNativeCameraKit/CameraProtocol.swift Extends camera protocol with face detection methods.
ios/ReactNativeCameraKit/CKCameraViewComponentView.mm Emits Fabric onFaceDetected event with typed payload.
ios/ReactNativeCameraKit/CKCameraManager.mm Exports iOS Old Arch props for face detection enable/throttle + event.
example/src/CameraExample.tsx Adds UI toggle + overlay rendering for detected faces and install banner.
example/ios/Podfile.lock Bumps example pod version to match updated library version.
example/images/faceDetection.png Adds example UI icon asset.
android/src/oldarch/java/com/rncamerakit/CKCameraManager.kt Registers new events + props for Old Arch.
android/src/newarch/java/com/rncamerakit/CKCameraManager.kt Registers new events + props for New Arch.
android/src/main/java/com/rncamerakit/events/FaceDetectionInstallStatusEvent.kt New event for ML Kit module install lifecycle.
android/src/main/java/com/rncamerakit/events/FaceDetectedEvent.kt New event carrying face payload array.
android/src/main/java/com/rncamerakit/FaceAnalyzer.kt New CameraX analyzer: module install + throttled ML Kit detection.
android/src/main/java/com/rncamerakit/CKCamera.kt Binds additional ImageAnalysis use case + mirrors front-camera bounds.
android/build.gradle Adds unbundled ML Kit face detection dependency.
README.md Documents new face detection props/events and Android pre-download option.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread android/src/main/java/com/rncamerakit/FaceAnalyzer.kt Outdated
Comment thread example/src/CameraExample.tsx
Comment thread ios/ReactNativeCameraKit/CameraView.swift Outdated
Comment thread ios/ReactNativeCameraKit/RealCamera.swift Outdated
Comment thread ios/ReactNativeCameraKit/RealCamera.swift
Comment thread ios/ReactNativeCameraKit/FaceDetector.swift
@scarlac scarlac merged commit d71096b into teslamotors:master May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants