Skip to content

Commit

Permalink
add windowWidth/Height parms
Browse files Browse the repository at this point in the history
  • Loading branch information
luicfrr committed Jul 26, 2024
1 parent 84058bb commit 81ff6de
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 24 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ export default function App() {
| `minFaceSize` | Sets the smallest desired face size, expressed as the ratio of the width of the head to width of the image. | `0.15` |
| `trackingEnabled` | Whether or not to assign faces an ID, which can be used to track faces across images. Note that when contour detection is enabled, only one face is detected, so face tracking doesn't produce useful results. For this reason, and to improve detection speed, don't enable both contour detection and face tracking. | `false` |
| `autoScale` | Should auto scale face bounds, contour and landmarks on native side? If this option is disabled all detection results will be relative to frame coordinates, not to screen/preview. You shouldn't use this option if you want to draw on screen using `Skia Frame Processor`. See [this](https://github.com/luicfrr/react-native-vision-camera-face-detector/issues/30#issuecomment-2058805546) and [this](https://github.com/luicfrr/react-native-vision-camera-face-detector/issues/35) for more details. | `false` |
| `windowWidth` | * Required if you want to use `autoScale`. You must handle your own logic to get screen sizes, with or without statusbar size, etc... | `1.0` |
| `windowHeight` | * Required if you want to use `autoScale`. You must handle your own logic to get screen sizes, with or without statusbar size, etc... | `1.0` |

## 🔧 Troubleshooting

Expand All @@ -183,7 +185,7 @@ If you find other errors while using this package you're wellcome to open a new
This package was tested using the following:

- `react-native`: `0.74.3` (new arch disabled)
- `react-native-vision-camera`: `4.4.1`
- `react-native-vision-camera`: `4.5.0`
- `react-native-worklets-core`: `1.3.3`
- `react-native-reanimated`: `3.12.1`
- `expo`: `51.0.17`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,15 @@ class VisionCameraFaceDetectorPlugin(
proxy: VisionCameraProxy,
options: Map<String, Any>?
) : FrameProcessorPlugin() {
// device display data
private val displayMetrics = proxy.context.resources.displayMetrics
private val density = displayMetrics.density
private val windowWidth = (displayMetrics.widthPixels).toDouble() / density
private val windowHeight = (displayMetrics.heightPixels).toDouble() / density

// detection props
private var autoScale = false
private var faceDetector: FaceDetector? = null
private var runLandmarks = false
private var runClassifications = false
private var runContours = false
private var trackingEnabled = false
private var windowWidth = 1.0
private var windowHeight = 1.0

init {
// handle auto scaling
Expand All @@ -44,7 +40,9 @@ class VisionCameraFaceDetectorPlugin(
var landmarkModeValue = FaceDetectorOptions.LANDMARK_MODE_NONE
var classificationModeValue = FaceDetectorOptions.CLASSIFICATION_MODE_NONE
var contourModeValue = FaceDetectorOptions.CONTOUR_MODE_NONE
var minFaceSize = 0.15f

windowWidth = (options?.get("windowWidth") ?: 1.0) as Double
windowHeight = (options?.get("windowHeight") ?: 1.0) as Double

if (options?.get("performanceMode").toString() == "accurate") {
performanceModeValue = FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE
Expand All @@ -65,14 +63,7 @@ class VisionCameraFaceDetectorPlugin(
contourModeValue = FaceDetectorOptions.CONTOUR_MODE_ALL
}

val minFaceSizeParam = options?.get("minFaceSize").toString()
if (
minFaceSizeParam != "null" &&
minFaceSizeParam != minFaceSize.toString()
) {
minFaceSize = minFaceSizeParam.toFloat()
}

val minFaceSize: Float = (options?.get("minFaceSize") ?: 0.15f) as Float
val optionsBuilder = FaceDetectorOptions.Builder()
.setPerformanceMode(performanceModeValue)
.setLandmarkMode(landmarkModeValue)
Expand Down
12 changes: 9 additions & 3 deletions example/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
StyleSheet,
Text,
Button,
View
View,
useWindowDimensions
} from 'react-native'
import {
Frame,
Expand Down Expand Up @@ -51,6 +52,10 @@ function Index(): JSX.Element {
* @return {JSX.Element} Component
*/
function FaceDetection(): JSX.Element {
const {
width,
height
} = useWindowDimensions()
const {
hasPermission,
requestPermission
Expand All @@ -73,7 +78,9 @@ function FaceDetection(): JSX.Element {
] = useState<boolean>( true )
const faceDetectionOptions = useRef<FaceDetectionOptions>( {
performanceMode: 'fast',
classificationMode: 'all'
classificationMode: 'all',
windowWidth: width,
windowHeight: height
} ).current
const isFocused = useIsFocused()
const appState = useAppState()
Expand Down Expand Up @@ -199,7 +206,6 @@ function FaceDetection(): JSX.Element {
device={ cameraDevice }
onError={ handleCameraMountError }
faceDetectionCallback={ handleFacesDetected }
outputOrientation={ 'device' }
onUIRotationChanged={ handleUiRotation }
faceDetectionOptions={ {
...faceDetectionOptions,
Expand Down
19 changes: 14 additions & 5 deletions ios/VisionCameraFaceDetector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ import SceneKit

@objc(VisionCameraFaceDetector)
public class VisionCameraFaceDetector: FrameProcessorPlugin {
// device display data
private let screenBounds = UIScreen.main.bounds

// detection props
private var autoScale = false
private var faceDetector: FaceDetector! = nil
private var runLandmarks = false
private var runClassifications = false
private var runContours = false
private var trackingEnabled = false
private var windowWidth = 1.0
private var windowHeight = 1.0

public override init(
proxy: VisionCameraProxyHolder,
Expand All @@ -27,6 +26,16 @@ public class VisionCameraFaceDetector: FrameProcessorPlugin {
super.init(proxy: proxy, options: options)
let config = getConfig(withArguments: options)

let windowWidthParam = config?["windowWidth"] as? Double
if windowWidthParam != nil && windowWidthParam != windowWidth {
windowWidth = CGFloat(windowWidthParam!)
}

let windowHeightParam = config?["windowHeight"] as? Double
if windowHeightParam != nil && windowHeightParam != windowHeight {
windowHeight = CGFloat(windowHeightParam!)
}

// handle auto scaling
autoScale = config?["autoScale"] as? Bool == true

Expand Down Expand Up @@ -257,8 +266,8 @@ public class VisionCameraFaceDetector: FrameProcessorPlugin {
var scaleX:CGFloat
var scaleY:CGFloat
if autoScale {
scaleX = screenBounds.size.width / width
scaleY = screenBounds.size.height / height
scaleX = windowWidth / width
scaleY = windowHeight / height
} else {
scaleX = CGFloat(1)
scaleY = CGFloat(1)
Expand Down
15 changes: 15 additions & 0 deletions src/FaceDetector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,21 @@ export interface FaceDetectionOptions {
* @default false
*/
autoScale?: boolean


/**
* Required if you want to use `autoScale`. You must handle your own logic to get screen sizes, with or without statusbar size, etc...
*
* @default 1.0
*/
windowWidth?: number

/**
* Required if you want to use `autoScale`. You must handle your own logic to get screen sizes, with or without statusbar size, etc...
*
* @default 1.0
*/
windowHeight?: number
}

/**
Expand Down

0 comments on commit 81ff6de

Please sign in to comment.