@rick427/react-native-liveness 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -6
- package/lib/module/livenessScoring.js +8 -14
- package/lib/module/livenessScoring.js.map +1 -1
- package/lib/typescript/src/livenessScoring.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +6 -4
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/livenessScoring.ts +8 -20
- package/src/types.ts +5 -4
package/README.md
CHANGED
|
@@ -226,16 +226,17 @@ The circle guide layers three animations built entirely with `Animated` + `react
|
|
|
226
226
|
|
|
227
227
|
## How liveness scoring works
|
|
228
228
|
|
|
229
|
-
Each camera frame is scored across
|
|
229
|
+
Each camera frame is scored across three signals at up to **20 fps** (ML Kit is throttled via `runAtTargetFps` while the preview renders at 60 fps):
|
|
230
230
|
|
|
231
231
|
| Signal | Weight | Detail |
|
|
232
232
|
|---|---|---|
|
|
233
|
-
| Face detected |
|
|
234
|
-
| Face size |
|
|
235
|
-
| Head pose |
|
|
236
|
-
| Eyes open | 30% | Average of left/right eye open probability from ML Kit. |
|
|
233
|
+
| Face detected | 25% | ML Kit found a face in the frame. |
|
|
234
|
+
| Face size | 30% | Face width is 15–80% of the frame. Soft-edge scoring at boundaries. |
|
|
235
|
+
| Head pose | 45% | Yaw < ±25° and pitch < ±25° from frontal. Soft decay outside range. |
|
|
237
236
|
|
|
238
|
-
|
|
237
|
+
Eye openness is intentionally excluded — this is **passive** liveness detection. Natural blinks are involuntary and must not penalise the user.
|
|
238
|
+
|
|
239
|
+
Liveness is confirmed once `confirmFrames` consecutive frames all score above `livenessThreshold`. Bad frames decay the streak by 1 instead of resetting it, making detection resilient to momentary noise.
|
|
239
240
|
|
|
240
241
|
---
|
|
241
242
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
// Eye openness is intentionally excluded — passive liveness detection does not
|
|
4
|
+
// require gestures. Natural blinks are involuntary and must never penalise the
|
|
5
|
+
// user. Liveness is confirmed via face presence, size, and frontal pose only.
|
|
3
6
|
const WEIGHTS = {
|
|
4
|
-
faceDetected: 0.
|
|
5
|
-
faceSize: 0.
|
|
6
|
-
headPose: 0.
|
|
7
|
-
eyesOpen: 0.3
|
|
7
|
+
faceDetected: 0.25,
|
|
8
|
+
faceSize: 0.3,
|
|
9
|
+
headPose: 0.45
|
|
8
10
|
};
|
|
9
11
|
|
|
10
12
|
// Loosened from 0.20 / 0.65 — gives more room for the user to breathe
|
|
@@ -41,17 +43,12 @@ export function scoreFrame(face, frameWidth) {
|
|
|
41
43
|
const yawScore = Math.abs(face.yawAngle) <= MAX_YAW_DEG ? 1.0 : Math.max(0, 1 - (Math.abs(face.yawAngle) - MAX_YAW_DEG) / MAX_YAW_DEG);
|
|
42
44
|
const pitchScore = Math.abs(face.pitchAngle) <= MAX_PITCH_DEG ? 1.0 : Math.max(0, 1 - (Math.abs(face.pitchAngle) - MAX_PITCH_DEG) / MAX_PITCH_DEG);
|
|
43
45
|
const headPose = (yawScore + pitchScore) / 2;
|
|
44
|
-
|
|
45
|
-
// ML Kit returns -1 when classification is disabled or unavailable
|
|
46
|
-
const leftEye = face.leftEyeOpenProbability >= 0 ? face.leftEyeOpenProbability : 0.5;
|
|
47
|
-
const rightEye = face.rightEyeOpenProbability >= 0 ? face.rightEyeOpenProbability : 0.5;
|
|
48
|
-
const eyesOpen = (leftEye + rightEye) / 2;
|
|
49
|
-
const total = WEIGHTS.faceDetected * 1.0 + WEIGHTS.faceSize * faceSize + WEIGHTS.headPose * headPose + WEIGHTS.eyesOpen * eyesOpen;
|
|
46
|
+
const total = WEIGHTS.faceDetected * 1.0 + WEIGHTS.faceSize * faceSize + WEIGHTS.headPose * headPose;
|
|
50
47
|
return {
|
|
51
48
|
total,
|
|
52
49
|
faceSize,
|
|
53
50
|
headPose,
|
|
54
|
-
eyesOpen
|
|
51
|
+
eyesOpen: 0
|
|
55
52
|
};
|
|
56
53
|
}
|
|
57
54
|
export function rollingAverage(scores) {
|
|
@@ -67,9 +64,6 @@ export function getFeedback(face, frameWidth, livenessConfirmed) {
|
|
|
67
64
|
const yawBad = Math.abs(face.yawAngle) >= MAX_YAW_DEG;
|
|
68
65
|
const pitchBad = Math.abs(face.pitchAngle) >= MAX_PITCH_DEG;
|
|
69
66
|
if (yawBad || pitchBad) return 'Look straight ahead';
|
|
70
|
-
const leftEye = face.leftEyeOpenProbability >= 0 ? face.leftEyeOpenProbability : 1;
|
|
71
|
-
const rightEye = face.rightEyeOpenProbability >= 0 ? face.rightEyeOpenProbability : 1;
|
|
72
|
-
if (leftEye < 0.4 || rightEye < 0.4) return 'Open your eyes';
|
|
73
67
|
return 'Hold still...';
|
|
74
68
|
}
|
|
75
69
|
//# sourceMappingURL=livenessScoring.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["WEIGHTS","faceDetected","faceSize","headPose","
|
|
1
|
+
{"version":3,"names":["WEIGHTS","faceDetected","faceSize","headPose","FACE_SIZE_MIN","FACE_SIZE_MAX","FACE_SIZE_SOFT_MARGIN","MAX_YAW_DEG","MAX_PITCH_DEG","scoreFrame","face","frameWidth","detected","total","eyesOpen","faceWidthRatio","bounds","width","Math","max","yawScore","abs","yawAngle","pitchScore","pitchAngle","rollingAverage","scores","length","reduce","a","b","getFeedback","livenessConfirmed","yawBad","pitchBad"],"sourceRoot":"../../src","sources":["livenessScoring.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"livenessScoring.d.ts","sourceRoot":"","sources":["../../../src/livenessScoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"livenessScoring.d.ts","sourceRoot":"","sources":["../../../src/livenessScoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAoBzD,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CA8CzE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAGvD;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,OAAO,GACzB,eAAe,CAajB"}
|
|
@@ -16,7 +16,7 @@ export type FaceData = {
|
|
|
16
16
|
smilingProbability: number;
|
|
17
17
|
};
|
|
18
18
|
export type LivenessState = 'idle' | 'scanning' | 'confirmed' | 'countdown' | 'capturing' | 'done' | 'error';
|
|
19
|
-
export type FeedbackMessage = 'Position your face in the circle' | 'Move closer' | 'Move farther away' | 'Look straight ahead' | 'Hold still...' | 'Stay still' | '
|
|
19
|
+
export type FeedbackMessage = 'Position your face in the circle' | 'Move closer' | 'Move farther away' | 'Look straight ahead' | 'Hold still...' | 'Stay still' | 'Liveness confirmed' | '';
|
|
20
20
|
export type CaptureResult = {
|
|
21
21
|
photo: PhotoFile;
|
|
22
22
|
livenessScore: number;
|
|
@@ -40,12 +40,14 @@ export type LivenessCameraProps = {
|
|
|
40
40
|
*/
|
|
41
41
|
countdownFrom?: number;
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
43
|
+
* Per-frame score (0–1) a frame must reach to count as a good frame.
|
|
44
|
+
* Defaults to 0.65. Scored on face presence, size, and head pose only —
|
|
45
|
+
* eye openness is not used (passive detection, no gestures required).
|
|
44
46
|
*/
|
|
45
47
|
livenessThreshold?: number;
|
|
46
48
|
/**
|
|
47
|
-
* Number of consecutive
|
|
48
|
-
*
|
|
49
|
+
* Number of consecutive good frames required to confirm liveness.
|
|
50
|
+
* Defaults to 7 (~350ms at 20fps).
|
|
49
51
|
*/
|
|
50
52
|
confirmFrames?: number;
|
|
51
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,eAAe,GACvB,kCAAkC,GAClC,aAAa,GACb,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,YAAY,GACZ,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,eAAe,GACvB,kCAAkC,GAClC,aAAa,GACb,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,YAAY,GACZ,oBAAoB,GACpB,EAAE,CAAC;AAEP,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEjC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,GAAG;IAC1E;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAE7B;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rick427/react-native-liveness",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Liveness detection library for React Native using Vision Camera v4 and ML Kit",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
package/src/livenessScoring.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { FaceData, FeedbackMessage } from './types';
|
|
2
2
|
|
|
3
|
+
// Eye openness is intentionally excluded — passive liveness detection does not
|
|
4
|
+
// require gestures. Natural blinks are involuntary and must never penalise the
|
|
5
|
+
// user. Liveness is confirmed via face presence, size, and frontal pose only.
|
|
3
6
|
const WEIGHTS = {
|
|
4
|
-
faceDetected: 0.
|
|
5
|
-
faceSize: 0.
|
|
6
|
-
headPose: 0.
|
|
7
|
-
eyesOpen: 0.3,
|
|
7
|
+
faceDetected: 0.25,
|
|
8
|
+
faceSize: 0.3,
|
|
9
|
+
headPose: 0.45,
|
|
8
10
|
} as const;
|
|
9
11
|
|
|
10
12
|
// Loosened from 0.20 / 0.65 — gives more room for the user to breathe
|
|
@@ -63,20 +65,12 @@ export function scoreFrame(face: FaceData, frameWidth: number): FrameScore {
|
|
|
63
65
|
);
|
|
64
66
|
const headPose = (yawScore + pitchScore) / 2;
|
|
65
67
|
|
|
66
|
-
// ML Kit returns -1 when classification is disabled or unavailable
|
|
67
|
-
const leftEye =
|
|
68
|
-
face.leftEyeOpenProbability >= 0 ? face.leftEyeOpenProbability : 0.5;
|
|
69
|
-
const rightEye =
|
|
70
|
-
face.rightEyeOpenProbability >= 0 ? face.rightEyeOpenProbability : 0.5;
|
|
71
|
-
const eyesOpen = (leftEye + rightEye) / 2;
|
|
72
|
-
|
|
73
68
|
const total =
|
|
74
69
|
WEIGHTS.faceDetected * 1.0 +
|
|
75
70
|
WEIGHTS.faceSize * faceSize +
|
|
76
|
-
WEIGHTS.headPose * headPose
|
|
77
|
-
WEIGHTS.eyesOpen * eyesOpen;
|
|
71
|
+
WEIGHTS.headPose * headPose;
|
|
78
72
|
|
|
79
|
-
return { total, faceSize, headPose, eyesOpen };
|
|
73
|
+
return { total, faceSize, headPose, eyesOpen: 0 };
|
|
80
74
|
}
|
|
81
75
|
|
|
82
76
|
export function rollingAverage(scores: number[]): number {
|
|
@@ -100,11 +94,5 @@ export function getFeedback(
|
|
|
100
94
|
const pitchBad = Math.abs(face.pitchAngle) >= MAX_PITCH_DEG;
|
|
101
95
|
if (yawBad || pitchBad) return 'Look straight ahead';
|
|
102
96
|
|
|
103
|
-
const leftEye =
|
|
104
|
-
face.leftEyeOpenProbability >= 0 ? face.leftEyeOpenProbability : 1;
|
|
105
|
-
const rightEye =
|
|
106
|
-
face.rightEyeOpenProbability >= 0 ? face.rightEyeOpenProbability : 1;
|
|
107
|
-
if (leftEye < 0.4 || rightEye < 0.4) return 'Open your eyes';
|
|
108
|
-
|
|
109
97
|
return 'Hold still...';
|
|
110
98
|
}
|
package/src/types.ts
CHANGED
|
@@ -33,7 +33,6 @@ export type FeedbackMessage =
|
|
|
33
33
|
| 'Look straight ahead'
|
|
34
34
|
| 'Hold still...'
|
|
35
35
|
| 'Stay still'
|
|
36
|
-
| 'Open your eyes'
|
|
37
36
|
| 'Liveness confirmed'
|
|
38
37
|
| '';
|
|
39
38
|
|
|
@@ -65,13 +64,15 @@ export type LivenessCameraProps = {
|
|
|
65
64
|
countdownFrom?: number;
|
|
66
65
|
|
|
67
66
|
/**
|
|
68
|
-
*
|
|
67
|
+
* Per-frame score (0–1) a frame must reach to count as a good frame.
|
|
68
|
+
* Defaults to 0.65. Scored on face presence, size, and head pose only —
|
|
69
|
+
* eye openness is not used (passive detection, no gestures required).
|
|
69
70
|
*/
|
|
70
71
|
livenessThreshold?: number;
|
|
71
72
|
|
|
72
73
|
/**
|
|
73
|
-
* Number of consecutive
|
|
74
|
-
*
|
|
74
|
+
* Number of consecutive good frames required to confirm liveness.
|
|
75
|
+
* Defaults to 7 (~350ms at 20fps).
|
|
75
76
|
*/
|
|
76
77
|
confirmFrames?: number;
|
|
77
78
|
|