@sssxyd/face-liveness-detector 0.4.1-beta.1 → 0.4.1-beta.3
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/dist/index.esm.js +30 -10
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +30 -10
- package/dist/index.js.map +1 -1
- package/dist/types/face-detection-engine.d.ts.map +1 -1
- package/dist/types/motion-liveness-detector.d.ts +2 -1
- package/dist/types/motion-liveness-detector.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1562,8 +1562,10 @@ class MotionDetectionResult {
|
|
|
1562
1562
|
// 是否为活体
|
|
1563
1563
|
isLively;
|
|
1564
1564
|
details;
|
|
1565
|
-
|
|
1565
|
+
debug;
|
|
1566
|
+
constructor(isLively, details, debug = {}) {
|
|
1566
1567
|
this.isLively = isLively;
|
|
1568
|
+
this.debug = debug;
|
|
1567
1569
|
this.details = details;
|
|
1568
1570
|
}
|
|
1569
1571
|
getMessage() {
|
|
@@ -1629,7 +1631,7 @@ class MotionLivenessDetector {
|
|
|
1629
1631
|
return this.config;
|
|
1630
1632
|
}
|
|
1631
1633
|
isReady() {
|
|
1632
|
-
return this.
|
|
1634
|
+
return this.normalizedLandmarksHistory.length >= 5; // 只需要5帧就能检测
|
|
1633
1635
|
}
|
|
1634
1636
|
reset() {
|
|
1635
1637
|
this.eyeAspectRatioHistory = [];
|
|
@@ -1661,10 +1663,17 @@ class MotionLivenessDetector {
|
|
|
1661
1663
|
this.normalizedLandmarksHistory.shift();
|
|
1662
1664
|
}
|
|
1663
1665
|
}
|
|
1666
|
+
else {
|
|
1667
|
+
return this.createEmptyResult({
|
|
1668
|
+
reason: '缺少面部关键点,无法进行活体检测',
|
|
1669
|
+
landmarks: currentKeypoints.landmarks
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1664
1672
|
// 数据不足时,继续收集
|
|
1665
|
-
if (this.
|
|
1666
|
-
return
|
|
1667
|
-
|
|
1673
|
+
if (!this.isReady()) {
|
|
1674
|
+
return this.createEmptyResult({
|
|
1675
|
+
reason: '数据收集中,帧数不足',
|
|
1676
|
+
collectedFrames: this.normalizedLandmarksHistory.length
|
|
1668
1677
|
});
|
|
1669
1678
|
}
|
|
1670
1679
|
// 【检测1】眼睛微妙波动 - 任何EAR变化都是活体
|
|
@@ -1700,7 +1709,10 @@ class MotionLivenessDetector {
|
|
|
1700
1709
|
}
|
|
1701
1710
|
catch (error) {
|
|
1702
1711
|
console.warn('[MotionLivenessDetector]', error);
|
|
1703
|
-
return this.createEmptyResult(
|
|
1712
|
+
return this.createEmptyResult({
|
|
1713
|
+
reason: '活体检测异常',
|
|
1714
|
+
error: error.message
|
|
1715
|
+
});
|
|
1704
1716
|
}
|
|
1705
1717
|
}
|
|
1706
1718
|
/**
|
|
@@ -3009,7 +3021,7 @@ class MotionLivenessDetector {
|
|
|
3009
3021
|
}
|
|
3010
3022
|
return normalized;
|
|
3011
3023
|
}
|
|
3012
|
-
createEmptyResult() {
|
|
3024
|
+
createEmptyResult(debug = {}) {
|
|
3013
3025
|
return new MotionDetectionResult(true, {
|
|
3014
3026
|
frameCount: 0,
|
|
3015
3027
|
eyeAspectRatioStdDev: 0,
|
|
@@ -3020,7 +3032,7 @@ class MotionLivenessDetector {
|
|
|
3020
3032
|
hasEyeMovement: false,
|
|
3021
3033
|
hasMouthMovement: false,
|
|
3022
3034
|
hasMuscleMovement: false
|
|
3023
|
-
});
|
|
3035
|
+
}, debug);
|
|
3024
3036
|
}
|
|
3025
3037
|
getStatistics() {
|
|
3026
3038
|
return {
|
|
@@ -3952,7 +3964,8 @@ class FaceDetectionEngine extends SimpleEventEmitter {
|
|
|
3952
3964
|
if (!motionResult.isLively) {
|
|
3953
3965
|
this.emitDebug('motion-detection', 'Motion liveness check failed - possible photo attack', {
|
|
3954
3966
|
details: motionResult.details,
|
|
3955
|
-
|
|
3967
|
+
debug: motionResult.debug,
|
|
3968
|
+
message: motionResult.getMessage(),
|
|
3956
3969
|
}, 'warn');
|
|
3957
3970
|
this.emitDetectorInfo({
|
|
3958
3971
|
code: DetectionCode.FACE_NOT_LIVE,
|
|
@@ -3962,10 +3975,17 @@ class FaceDetectionEngine extends SimpleEventEmitter {
|
|
|
3962
3975
|
return;
|
|
3963
3976
|
}
|
|
3964
3977
|
this.emitDebug('motion-detection', 'Motion liveness check passed', {
|
|
3965
|
-
|
|
3978
|
+
debug: motionResult.debug,
|
|
3979
|
+
details: motionResult.details,
|
|
3966
3980
|
}, 'warn');
|
|
3967
3981
|
this.detectionState.liveness = true;
|
|
3968
3982
|
}
|
|
3983
|
+
else {
|
|
3984
|
+
this.emitDebug('motion-detection', 'Motion liveness detector not ready yet', {
|
|
3985
|
+
debug: motionResult.debug,
|
|
3986
|
+
details: motionResult.details,
|
|
3987
|
+
}, 'warn');
|
|
3988
|
+
}
|
|
3969
3989
|
// 计算面部大小比例,不达标则跳过当前帧
|
|
3970
3990
|
const faceRatio = (faceBox[2] * faceBox[3]) / (this.actualVideoWidth * this.actualVideoHeight);
|
|
3971
3991
|
if (faceRatio <= this.options.collect_min_face_ratio) {
|