@sssxyd/face-liveness-detector 0.4.0-alpha.9 → 0.4.0

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.
Files changed (38) hide show
  1. package/README.en.md +118 -144
  2. package/README.md +23 -49
  3. package/dist/index.esm.js +3170 -2330
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +3170 -2330
  6. package/dist/index.js.map +1 -1
  7. package/dist/types/browser_utils.d.ts +3 -3
  8. package/dist/types/browser_utils.d.ts.map +1 -1
  9. package/dist/types/config.d.ts.map +1 -1
  10. package/dist/types/dlp-color-wheel-detector.d.ts +76 -0
  11. package/dist/types/dlp-color-wheel-detector.d.ts.map +1 -0
  12. package/dist/types/face-detection-engine.d.ts +113 -16
  13. package/dist/types/face-detection-engine.d.ts.map +1 -1
  14. package/dist/types/face-detection-state.d.ts +5 -2
  15. package/dist/types/face-detection-state.d.ts.map +1 -1
  16. package/dist/types/face-frontal-calculator.d.ts +3 -3
  17. package/dist/types/face-frontal-calculator.d.ts.map +1 -1
  18. package/dist/types/image-quality-calculator.d.ts +10 -23
  19. package/dist/types/image-quality-calculator.d.ts.map +1 -1
  20. package/dist/types/motion-liveness-detector.d.ts +34 -19
  21. package/dist/types/motion-liveness-detector.d.ts.map +1 -1
  22. package/dist/types/optical-distortion-detector.d.ts +116 -0
  23. package/dist/types/optical-distortion-detector.d.ts.map +1 -0
  24. package/dist/types/screen-capture-detector.d.ts +74 -115
  25. package/dist/types/screen-capture-detector.d.ts.map +1 -1
  26. package/dist/types/screen-corners-contour-detector.d.ts +78 -0
  27. package/dist/types/screen-corners-contour-detector.d.ts.map +1 -0
  28. package/dist/types/screen-flicker-detector.d.ts +103 -0
  29. package/dist/types/screen-flicker-detector.d.ts.map +1 -0
  30. package/dist/types/screen-moire-pattern-detect.d.ts.map +1 -1
  31. package/dist/types/screen-response-time-detector.d.ts +70 -0
  32. package/dist/types/screen-response-time-detector.d.ts.map +1 -0
  33. package/dist/types/screen-rgb-emission-detect.d.ts.map +1 -1
  34. package/dist/types/types.d.ts +9 -51
  35. package/dist/types/types.d.ts.map +1 -1
  36. package/dist/types/video-frame-collector.d.ts +111 -0
  37. package/dist/types/video-frame-collector.d.ts.map +1 -0
  38. package/package.json +2 -1
@@ -2,10 +2,10 @@
2
2
  * 将绘制图片的canvas转换为mat
3
3
  * @param {any} cv OpenCV实例
4
4
  * @param {HTMLCanvasElement} canvas canvas元素
5
- * @param {boolean} gray 是否转换为灰度图像
6
- * @returns {any | null} - 转换后的Mat对象,如果转换失败则返回null
5
+ * @param {any} dstMat 目标Mat对象,将canvas数据写入此Mat
6
+ * @returns {any | null} - 返回传入的Mat对象,如果转换失败则返回null
7
7
  */
8
- export declare function drawCanvasToMat(cv: any, canvas: HTMLCanvasElement, gray: boolean): any | null;
8
+ export declare function drawCanvasToMat(cv: any, canvas: HTMLCanvasElement, dstMat: any): any | null;
9
9
  export declare function matToGray(cv: any, mat: any): any | null;
10
10
  /**
11
11
  * Convert OpenCV Mat to Base64 JPEG image
@@ -1 +1 @@
1
- {"version":3,"file":"browser_utils.d.ts","sourceRoot":"","sources":["../../src/browser_utils.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,GAAG,GAAG,GAAG,IAAI,CAiB7F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,CAWvD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,MAAY,GAAG,MAAM,GAAG,IAAI,CA6BvF"}
1
+ {"version":3,"file":"browser_utils.d.ts","sourceRoot":"","sources":["../../src/browser_utils.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,CAsB3F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,IAAI,CAWvD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAE,MAAY,GAAG,MAAM,GAAG,IAAI,CA6BvF"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AA8EhF;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,UAAU,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAC/C,qBAAqB,CAwBvB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAsDhF;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,UAAU,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAC/C,qBAAqB,CAwBvB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * DLP色轮检测器 - 检测DLP投影仪的特有伪影
3
+ *
4
+ * 核心原理:
5
+ * - DLP投影仪使用单色DMD芯片 + RGB色轮
6
+ * - 色轮以高频率(120-144Hz)轮换RGB颜色
7
+ * - 摄像头如果不同步捕捉,会看到RGB分离现象
8
+ *
9
+ * 特征:
10
+ * 1. 高对比度边界处出现"彩虹纹"(R左/B右分离)
11
+ * 2. 快速移动物体边缘有明显的RGB分离
12
+ * 3. 静止物体通常正常(因为色轮平均后是白色)
13
+ *
14
+ * 检测方法:
15
+ * 1. 找高对比度边界区域
16
+ * 2. 分析边界处R、G、B通道的位置差异
17
+ * 3. 如果R领先,B延后 → DLP特征
18
+ */
19
+ import { VideoFrameCollector } from "./video-frame-collector";
20
+ export interface DLPColorWheelDetectorConfig {
21
+ bufferSize: number;
22
+ edgeThreshold: number;
23
+ minChannelSeparationPixels: number;
24
+ separationConfidenceThreshold: number;
25
+ samplingStride: number;
26
+ }
27
+ export interface DLPColorWheelDetectionResult {
28
+ isScreenCapture: boolean;
29
+ confidence: number;
30
+ hasColorSeparation: boolean;
31
+ colorSeparationPixels: number;
32
+ redLeadPixels?: number;
33
+ blueDelayPixels?: number;
34
+ sampledEdgePixelCount: number;
35
+ estimatedColorWheelFrequency?: number;
36
+ details?: {
37
+ edgeLocations: number[];
38
+ separationDistances: number[];
39
+ };
40
+ }
41
+ export declare class DLPColorWheelDetector {
42
+ private config;
43
+ private frameCollector;
44
+ constructor(frameCollector: VideoFrameCollector, config: DLPColorWheelDetectorConfig);
45
+ /**
46
+ * 获取当前缓冲区中的帧数
47
+ */
48
+ getBufferedFrameCount(): number;
49
+ /**
50
+ * 执行DLP色轮检测分析
51
+ */
52
+ analyze(): DLPColorWheelDetectionResult;
53
+ /**
54
+ * 重置检测器
55
+ * 注意:帧缓冲由 FrameCollector 管理
56
+ */
57
+ reset(): void;
58
+ /**
59
+ * 检测高对比度边界
60
+ * 返回边界的x坐标位置
61
+ */
62
+ private detectHighContrastEdges;
63
+ /**
64
+ * 分析单条边界的RGB分离
65
+ *
66
+ * DLP特征:
67
+ * - R通道的边界比G靠前(向左)
68
+ * - B通道的边界比G靠后(向右)
69
+ */
70
+ private analyzeRGBSeparation;
71
+ /**
72
+ * 找导数数组中的峰值位置
73
+ */
74
+ private findPeakPosition;
75
+ }
76
+ //# sourceMappingURL=dlp-color-wheel-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlp-color-wheel-detector.d.ts","sourceRoot":"","sources":["../../src/dlp-color-wheel-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,MAAM,WAAW,2BAA2B;IAE1C,UAAU,EAAE,MAAM,CAAA;IAGlB,aAAa,EAAE,MAAM,CAAA;IAGrB,0BAA0B,EAAE,MAAM,CAAA;IAGlC,6BAA6B,EAAE,MAAM,CAAA;IAGrC,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,4BAA4B;IAC3C,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAGlB,kBAAkB,EAAE,OAAO,CAAA;IAC3B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,qBAAqB,EAAE,MAAM,CAAA;IAG7B,4BAA4B,CAAC,EAAE,MAAM,CAAA;IAErC,OAAO,CAAC,EAAE;QACR,aAAa,EAAE,MAAM,EAAE,CAAA;QACvB,mBAAmB,EAAE,MAAM,EAAE,CAAA;KAC9B,CAAA;CACF;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAAqB;gBAE/B,cAAc,EAAE,mBAAmB,EAAE,MAAM,EAAE,2BAA2B;IAKpF;;OAEG;IACH,qBAAqB,IAAI,MAAM;IAI/B;;OAEG;IACH,OAAO,IAAI,4BAA4B;IA8HvC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAKb;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAyC/B;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAgE5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -14,15 +14,22 @@ export declare class FaceDetectionEngine extends SimpleEventEmitter {
14
14
  private cv;
15
15
  private human;
16
16
  private engineState;
17
+ private videoFPS;
18
+ private lastDebugLogTime;
19
+ private debugLogLevelPriority;
17
20
  private videoElement;
18
21
  private stream;
19
22
  private frameCanvasElement;
20
23
  private frameCanvasContext;
21
- private faceCanvasElement;
22
- private faceCanvasContext;
23
- private detectionFrameId;
24
+ private animationFrameId;
24
25
  private actualVideoWidth;
25
26
  private actualVideoHeight;
27
+ private preallocatedBgrFrame;
28
+ private preallocatedGrayFrame;
29
+ private isDetectingFrameActive;
30
+ private frameIndex;
31
+ private lastDetectionFrameIndex;
32
+ private lastScreenFeatureDetectionFrameIndex;
26
33
  private detectionState;
27
34
  /**
28
35
  * Constructor
@@ -41,6 +48,37 @@ export declare class FaceDetectionEngine extends SimpleEventEmitter {
41
48
  private getStackTrace;
42
49
  updateOptions(options?: Partial<FaceDetectionEngineOptions>): void;
43
50
  getEngineState(): EngineState;
51
+ /**
52
+ * Atomically transition engine state with validation
53
+ * Ensures state transitions follow the valid state machine
54
+ * @param newState - Target engine state
55
+ * @param context - Debug context for logging
56
+ * @returns true if transition succeeded, false otherwise
57
+ */
58
+ private transitionEngineState;
59
+ /**
60
+ * Check if state transition is valid according to state machine rules
61
+ * Valid transitions:
62
+ * - IDLE -> INITIALIZING, INITIALIZING -> READY, READY -> DETECTING, DETECTING -> READY
63
+ * - Any -> IDLE (error recovery)
64
+ */
65
+ private isValidStateTransition;
66
+ /**
67
+ * Transition detection period state
68
+ * @param newPeriod - Target detection period
69
+ * @returns true if transition succeeded
70
+ */
71
+ private transitionDetectionPeriod;
72
+ /**
73
+ * Partially reset detection state (keeps engine initialized)
74
+ * Used when detection fails but engine should remain ready
75
+ */
76
+ private partialResetDetectionState;
77
+ /**
78
+ * Fully reset detection state and resources
79
+ * Used when stopping detection or reinitializing
80
+ */
81
+ private fullResetDetectionState;
44
82
  /**
45
83
  * Initialize the detection engine
46
84
  * Loads Human.js and OpenCV.js libraries
@@ -60,6 +98,7 @@ export declare class FaceDetectionEngine extends SimpleEventEmitter {
60
98
  startDetection(videoElement: HTMLVideoElement): Promise<void>;
61
99
  /**
62
100
  * Stop face detection
101
+ * Performs comprehensive cleanup to prevent memory leaks and UI freezing
63
102
  * @param success - Whether to display the best collected image
64
103
  */
65
104
  stopDetection(success: boolean): void;
@@ -68,23 +107,83 @@ export declare class FaceDetectionEngine extends SimpleEventEmitter {
68
107
  * @returns Current configuration
69
108
  */
70
109
  getOptions(): FaceDetectionEngineOptions;
110
+ private updateVideoFPS;
111
+ /**
112
+ * Adjust detect_frame_delay to ensure main detection interval is at least 3 frames
113
+ * This is important for proper spacing of corner detection, feature detection, and main detection
114
+ */
115
+ private adjustDetectFrameDelay;
116
+ /**
117
+ * Get the frame interval for main face detection based on videoFPS and detect_frame_delay
118
+ * Uses Math.ceil to ensure actual interval >= configured delay
119
+ * @returns Number of frames between detections
120
+ */
121
+ private getDetectionFrameInterval;
122
+ /**
123
+ * Check if main face detection should be performed this frame
124
+ * @returns true if enough frames have passed since last detection
125
+ */
126
+ private shouldPerformMainDetection;
71
127
  /**
72
- * Reset detection state
128
+ * Check if screen corner detection should be performed this frame
129
+ * Executes once per main detection interval
130
+ * Logic:
131
+ * - If mainInterval <= 2: disabled (insufficient frames)
132
+ * - If mainInterval > 2: executes at calculated point, unless it's the last frame
133
+ * @returns true if conditions are met
73
134
  */
74
- private resetDetectionState;
135
+ private shouldPerformScreenCornersDetection;
75
136
  /**
76
- * Schedule next detection frame
137
+ * Check if screen feature detection (multi-frame) should be performed this frame
138
+ * Logic:
139
+ * - Executes at calculated point in the cycle (40% position)
140
+ * - If missed, can execute at last frame of cycle (fallback)
141
+ * @returns true if conditions are met
77
142
  */
78
- private scheduleNextDetection;
143
+ private shouldPerformScreenFeatureDetection;
79
144
  /**
80
145
  * Cancel pending detection frame
81
146
  */
82
147
  private cancelPendingDetection;
83
148
  /**
84
149
  * Main detection loop
150
+ * Called every frame via requestAnimationFrame
151
+ * Orchestrates the detection pipeline with clear separation of concerns
85
152
  */
86
153
  private detect;
154
+ /**
155
+ * Check if current frame should be captured based on detection scheduling
156
+ */
157
+ private shouldCaptureFrame;
158
+ /**
159
+ * Capture video frame and convert to BGR and Grayscale Mat objects
160
+ * @returns {Object | null} Object with bgrFrame and grayFrame, or null if failed
161
+ */
162
+ private captureAndPrepareFrames;
163
+ /**
164
+ * Perform screen detection (corners and multi-frame features)
165
+ * @returns true if screen is detected, false otherwise
166
+ */
167
+ private performScreenDetection;
168
+ /**
169
+ * Perform main face detection and handle results
170
+ */
171
+ private performFaceDetection;
172
+ /**
173
+ * Clean up frame Mat objects
174
+ * Note: Both BGR and Gray Mats are preallocated and reused
175
+ * They are only deleted in clearPreallocatedMats()
176
+ */
177
+ private cleanupFrames;
87
178
  private getPerformActionCount;
179
+ /**
180
+ * Detect screen by corners and contours analysis (fast detection)
181
+ */
182
+ private detectScreenCorners;
183
+ /**
184
+ * Detect screen by multi-frame feature analysis
185
+ */
186
+ private detectScreenFeatures;
88
187
  /**
89
188
  * Handle single face detection
90
189
  */
@@ -121,22 +220,20 @@ export declare class FaceDetectionEngine extends SimpleEventEmitter {
121
220
  private emitDebug;
122
221
  /**
123
222
  * Draw video frame to canvas (internal use, not converted to Base64)
223
+ * Handles potential runtime resolution changes from camera stream
124
224
  * @returns {HTMLCanvasElement | null} Canvas after drawing, returns null if failed
125
225
  */
126
226
  private drawVideoToCanvas;
127
227
  private clearFrameCanvas;
128
- private clearFaceCanvas;
129
228
  /**
130
- * canvas 转换为 Base64 JPEG 图片数据
131
- * @param {HTMLCanvasElement} canvas - 输入的 canvas
132
- * @returns {string | null} Base64 格式的 JPEG 图片数据
229
+ * Ensure preallocated Mat objects exist with correct dimensions
230
+ * Creates both BGR and Gray Mat for reuse
133
231
  */
134
- private canvasToBase64;
232
+ private ensurePreallocatedMats;
135
233
  /**
136
- * Capture current video frame (returns Base64)
137
- * @param {Box} box - Face box
138
- * @returns {string | null} Base64 encoded JPEG image data
234
+ * Clear preallocated Mat objects
235
+ * Called when resolution changes or detection stops
139
236
  */
140
- private captureFrame;
237
+ private clearPreallocatedMats;
141
238
  }
142
239
  //# sourceMappingURL=face-detection-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"face-detection-engine.d.ts","sourceRoot":"","sources":["../../src/face-detection-engine.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,0BAA0B,EAQ3B,MAAM,SAAS,CAAA;AAChB,OAAO,EAAmF,WAAW,EAAE,MAAM,SAAS,CAAA;AAEtH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAwBpD;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB;IACzD,OAAO,CAAC,OAAO,CAAuB;IAEtC,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,WAAW,CAAgC;IAGnD,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,kBAAkB,CAAiC;IAC3D,OAAO,CAAC,kBAAkB,CAAwC;IAClE,OAAO,CAAC,iBAAiB,CAAiC;IAC1D,OAAO,CAAC,iBAAiB,CAAwC;IAEjE,OAAO,CAAC,gBAAgB,CAAsB;IAE9C,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,iBAAiB,CAAY;IAErC,OAAO,CAAC,cAAc,CAAgB;IAEtC;;;OAGG;gBACS,OAAO,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC;IAMzD;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;OAEG;IACH,OAAO,CAAC,aAAa;IAerB,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,GAAG,IAAI;IASlE,cAAc,IAAI,WAAW;IAI7B;;;;;;OAMG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkLjC;;;;;;;OAOG;IACG,cAAc,CAAC,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoJnE;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IA8BrC;;;OAGG;IACH,UAAU,IAAI,0BAA0B;IAMxC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;YACW,MAAM;IA6DpB,OAAO,CAAC,qBAAqB;IAY7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqPxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkDzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,uBAAuB;IA6B/B,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAuCpB;;OAEG;IACH,OAAO,CAAC,SAAS;IAgBjB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAwDzB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,eAAe;IAWvB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;OAIG;IACH,OAAO,CAAC,YAAY;CA+BrB"}
1
+ {"version":3,"file":"face-detection-engine.d.ts","sourceRoot":"","sources":["../../src/face-detection-engine.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { DetectionPeriod, LivenessAction } from "./enums";
2
2
  import { MotionLivenessDetector } from "./motion-liveness-detector";
3
3
  import { ScreenCaptureDetector } from './screen-capture-detector';
4
- import { ResolvedEngineOptions } from "./types";
4
+ import { ScreenCornersContourDetector } from './screen-corners-contour-detector';
5
5
  /**
6
6
  * Internal detection state interface
7
7
  */
@@ -19,9 +19,12 @@ export declare class DetectionState {
19
19
  lastFrontalScore: number;
20
20
  motionDetector: MotionLivenessDetector | null;
21
21
  liveness: boolean;
22
+ realness: boolean;
22
23
  screenDetector: ScreenCaptureDetector | null;
24
+ cornersContourDetector: ScreenCornersContourDetector | null;
23
25
  constructor(options: Partial<DetectionState>);
24
26
  reset(): void;
27
+ updateVideoFPS(fps: number): void;
25
28
  needFrontalFace(): boolean;
26
29
  isReadyToVerify(minCollectCount: number): boolean;
27
30
  onActionStarted(nextAction: LivenessAction, timeoutMills: number, timeoutCallback: () => void): void;
@@ -32,5 +35,5 @@ export declare class DetectionState {
32
35
  */
33
36
  private clearActionVerifyTimeout;
34
37
  }
35
- export declare function createDetectionState(options: ResolvedEngineOptions): DetectionState;
38
+ export declare function createDetectionState(fps: number, strictPhotoDetection: boolean): DetectionState;
36
39
  //# sourceMappingURL=face-detection-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"face-detection-state.d.ts","sourceRoot":"","sources":["../../src/face-detection-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAwB,MAAM,SAAS,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AACnE,OAAO,EAAE,qBAAqB,EAA6B,MAAM,2BAA2B,CAAA;AAC5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAE/C;;GAEG;AACH,qBAAa,cAAc;IACvB,MAAM,EAAE,eAAe,CAAyB;IAChD,SAAS,EAAE,MAAM,CAAoB;IACrC,YAAY,EAAE,MAAM,CAAI;IACxB,oBAAoB,EAAE,MAAM,CAAI;IAChC,gBAAgB,EAAE,MAAM,CAAI;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAO;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAO;IACnC,gBAAgB,EAAE,GAAG,CAAC,cAAc,CAAC,CAAY;IACjD,aAAa,EAAE,cAAc,GAAG,IAAI,CAAO;IAC3C,mBAAmB,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAO;IAChE,gBAAgB,EAAE,MAAM,CAAI;IAC5B,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAO;IACpD,QAAQ,EAAE,OAAO,CAAQ;IACzB,cAAc,EAAE,qBAAqB,GAAG,IAAI,CAAO;gBAEvC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC;IAI5C,KAAK,IAAI,IAAI;IAeb,eAAe,IAAI,OAAO;IAK1B,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO;IAUjD,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,GAAG,IAAI;IASpG,iBAAiB,IAAI,IAAI;IASzB,aAAa,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI;IAKpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAMnC;AAID,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CA4BnF"}
1
+ {"version":3,"file":"face-detection-state.d.ts","sourceRoot":"","sources":["../../src/face-detection-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAwB,MAAM,SAAS,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAA;AAGhF;;GAEG;AACH,qBAAa,cAAc;IACvB,MAAM,EAAE,eAAe,CAAyB;IAChD,SAAS,EAAE,MAAM,CAAoB;IACrC,YAAY,EAAE,MAAM,CAAI;IACxB,oBAAoB,EAAE,MAAM,CAAI;IAChC,gBAAgB,EAAE,MAAM,CAAI;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAO;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAO;IACnC,gBAAgB,EAAE,GAAG,CAAC,cAAc,CAAC,CAAY;IACjD,aAAa,EAAE,cAAc,GAAG,IAAI,CAAO;IAC3C,mBAAmB,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAO;IAChE,gBAAgB,EAAE,MAAM,CAAI;IAC5B,cAAc,EAAE,sBAAsB,GAAG,IAAI,CAAO;IACpD,QAAQ,EAAE,OAAO,CAAQ;IACzB,QAAQ,EAAE,OAAO,CAAQ;IACzB,cAAc,EAAE,qBAAqB,GAAG,IAAI,CAAO;IACnD,sBAAsB,EAAE,4BAA4B,GAAG,IAAI,CAAO;gBAEtD,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC;IAI5C,KAAK,IAAI,IAAI;IAgBb,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAYjC,eAAe,IAAI,OAAO;IAK1B,eAAe,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO;IAUjD,eAAe,CAAC,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,IAAI,GAAG,IAAI;IASpG,iBAAiB,IAAI,IAAI;IASzB,aAAa,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI;IAMpC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAMnC;AAID,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,GAAG,cAAc,CAM/F"}
@@ -32,7 +32,7 @@ export interface AngleAnalysisResult {
32
32
  * @param {any} cv - OpenCV 实例(用于轮廓对称性检测)
33
33
  * @param {FaceResult} face - 人脸检测结果(包含 rotation 和 annotations 信息)
34
34
  * @param {Array<GestureResult>} gestures - 检测到的手势/表情数组(可选)
35
- * @param {any} matImage - OpenCV Mat 对象(图像数据,用于轮廓检测)
35
+ * @param {any} grayFrame - OpenCV Mat 对象(图像数据,用于轮廓检测)
36
36
  * @param {FaceFrontalFeatures} config - 正对度配置参数(包含角度阈值)
37
37
  * @returns {number} 正对度评分 (0-1),1 表示完全正对
38
38
  *
@@ -42,9 +42,9 @@ export interface AngleAnalysisResult {
42
42
  * if (score > 0.9) {
43
43
  * console.log('人脸足够正对')
44
44
  * }
45
- * mat.delete()
45
+ * grayFrame.delete()
46
46
  */
47
- export declare function calcFaceFrontal(cv: any, face: FaceResult, gestures: Array<GestureResult>, matImage: any, config: FaceFrontalFeatures): number;
47
+ export declare function calcFaceFrontal(cv: any, face: FaceResult, gestures: Array<GestureResult>, grayFrame: any, config: FaceFrontalFeatures): number;
48
48
  /**
49
49
  * 使用手势识别方法检查人脸正对度
50
50
  *
@@ -1 +1 @@
1
- {"version":3,"file":"face-frontal-calculator.d.ts","sourceRoot":"","sources":["../../src/face-frontal-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAG7C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,EAC9B,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAgCR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,OAAO,CAUpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CA8BhG;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,CAUvE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiD1G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAwChG"}
1
+ {"version":3,"file":"face-frontal-calculator.d.ts","sourceRoot":"","sources":["../../src/face-frontal-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAG7C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,GAAG,EACP,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,EAC9B,SAAS,EAAE,GAAG,EACd,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAgCR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,OAAO,CAUpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CA8BhG;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,CAUvE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiD1G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAwChG"}
@@ -1,14 +1,7 @@
1
1
  /**
2
- * 人脸图像质量检测模块 (统一版)
2
+ * 图像质量检测模块
3
3
  *
4
- * 综合检测人脸图像的:
5
- * 1. 完整度检测 - 人脸是否完整在框内
6
- * 2. 模糊度检测 - 图像是否清晰
7
- * 3. 轮廓清晰度 - 轮廓的连通性和完整度
8
- *
9
- * 使用混合检测策略,结合 Human.js 和 OpenCV.js 优势
10
4
  */
11
- import { FaceResult } from '@vladmandic/human';
12
5
  import { ImageQualityFeatures } from './types';
13
6
  /**
14
7
  * 单个检测指标的结果
@@ -37,30 +30,24 @@ export interface ImageQualityResult {
37
30
  suggestions?: string[];
38
31
  }
39
32
  /**
40
- * 计算图像质量(完整度 + 清晰度)
33
+ * 计算图像清晰度评分
41
34
  *
42
- * 综合检测:
43
- * - 人脸完整度(Human.js边界 + OpenCV轮廓)
44
- * - 图像清晰度(拉普拉斯方差 + Sobel梯度)
35
+ * 综合检测图像的清晰度,使用两个指标:
36
+ * - 拉普拉斯方差 (60%):检测边缘清晰程度
37
+ * - Sobel 梯度清晰度 (40%):检测纹理梯度强度
45
38
  *
46
39
  * @param cv - OpenCV.js 对象,用于执行图像处理操作
47
- * @param matImage - OpenCV Mat 对象,包含灰度图像数据
48
- * @param face - 人脸检测结果,包含人脸框位置和其他检测信息
49
- * @param imageWidth - 图片宽度(像素),用于边界检查和完整度计算
50
- * @param imageHeight - 图片高度(像素),用于边界检查和完整度计算
40
+ * @param grayFrame - OpenCV Mat 对象,包含灰度图像数据(已ROI裁剪)
51
41
  * @param config - 检测配置对象,包含:
52
- * - require_full_face_in_bounds: 是否要求人脸完全在边界内
53
- * - use_opencv_enhancement: 是否使用 OpenCV 增强检测
54
- * - min_laplacian_variance: 拉普拉斯方差最小阈值
55
- * - min_gradient_sharpness: 梯度清晰度最小阈值
42
+ * - min_laplacian_variance: 拉普拉斯方差最小阈值(默认 40)
43
+ * - min_gradient_sharpness: 梯度清晰度最小阈值(默认 0.15)
56
44
  * @param threshold - 综合质量评分阈值 (0-1),大于等于此值判定为通过
57
45
  * @returns 综合质量检测结果,包含:
58
46
  * - passed: 是否通过质量检测
59
47
  * - score: 综合质量评分 (0-1)
60
- * - completenessReasons: 完整度不通过原因列表
48
+ * - metrics: 各维度详细指标(拉普拉斯方差、梯度清晰度、综合质量)
61
49
  * - blurReasons: 清晰度不通过原因列表
62
- * - metrics: 各维度详细指标(完整度、拉普拉斯方差、梯度清晰度、综合质量)
63
50
  * - suggestions: 改进建议列表
64
51
  */
65
- export declare function calcImageQuality(cv: any, matImage: any, face: FaceResult, imageWidth: number, imageHeight: number, config: ImageQualityFeatures, threshold: number): ImageQualityResult;
52
+ export declare function calcImageQuality(cv: any, grayFrame: any, config: ImageQualityFeatures, threshold: number): ImageQualityResult;
66
53
  //# sourceMappingURL=image-quality-calculator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image-quality-calculator.d.ts","sourceRoot":"","sources":["../../src/image-quality-calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAI9C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAEjC,MAAM,EAAE,OAAO,CAAA;IAEf,KAAK,EAAE,MAAM,CAAA;IAEb,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAA;IAErB,OAAO,EAAE;QACP,YAAY,EAAE,mBAAmB,CAAA;QACjC,iBAAiB,EAAE,mBAAmB,CAAA;QACtC,iBAAiB,EAAE,mBAAmB,CAAA;QACtC,cAAc,EAAE,mBAAmB,CAAA;KACpC,CAAA;IAED,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,GAAG,EACP,QAAQ,EAAE,GAAG,EACb,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAoEpB"}
1
+ {"version":3,"file":"image-quality-calculator.d.ts","sourceRoot":"","sources":["../../src/image-quality-calculator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAoC9C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAEjC,MAAM,EAAE,OAAO,CAAA;IAEf,KAAK,EAAE,MAAM,CAAA;IAEb,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAA;IAErB,OAAO,EAAE;QACP,YAAY,EAAE,mBAAmB,CAAA;QACjC,iBAAiB,EAAE,mBAAmB,CAAA;QACtC,iBAAiB,EAAE,mBAAmB,CAAA;QACtC,cAAc,EAAE,mBAAmB,CAAA;KACpC,CAAA;IAED,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB;AAID;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,GAAG,EACP,SAAS,EAAE,GAAG,EACd,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,MAAM,GAChB,kBAAkB,CAkFpB"}
@@ -55,14 +55,10 @@ export interface MotionLivenessDetectorOptions {
55
55
  * 使用光流、关键点跟踪和面部特征分析
56
56
  */
57
57
  export declare class MotionLivenessDetector {
58
- private readonly minMotionThreshold;
59
- private readonly minKeypointVariance;
60
- private readonly frameBufferSize;
61
- private readonly eyeAspectRatioThreshold;
62
- private readonly motionConsistencyThreshold;
63
- private readonly minOpticalFlowThreshold;
64
- private readonly strictPhotoDetection;
58
+ private config;
65
59
  private frameBuffer;
60
+ private frameWidth;
61
+ private frameHeight;
66
62
  private keypointHistory;
67
63
  private faceAreaHistory;
68
64
  private eyeAspectRatioHistory;
@@ -70,8 +66,9 @@ export declare class MotionLivenessDetector {
70
66
  private opticalFlowHistory;
71
67
  private pupilSizeHistory;
72
68
  private cv;
73
- constructor(options?: Partial<MotionLivenessDetectorOptions>);
69
+ constructor(strictPhotoDetection?: boolean);
74
70
  setCVInstance(cvInstance: any): void;
71
+ getOptions(): Required<MotionLivenessDetectorOptions>;
75
72
  isReady(): boolean;
76
73
  /**
77
74
  * 重置运动检测状态
@@ -113,14 +110,16 @@ export declare class MotionLivenessDetector {
113
110
  /**
114
111
  * 计算光流幅度(需要 OpenCV)
115
112
  * 检测帧之间的像素运动
113
+ *
114
+ * 针对5帧短视频优化的参数:
115
+ * - pyr_scale: 0.8(更陡峭的金字塔,保留细节)
116
+ * - levels: 2(减少层级数,适合小尺寸视频)
117
+ * - winsize: 7(更小的窗口,捕捉微小运动)
116
118
  */
117
119
  private analyzeOpticalFlow;
118
- /**
119
- * 将 canvas 转换为 OpenCV Mat,支持可选的灰度转换
120
- */
121
- private canvasToMat;
122
120
  /**
123
121
  * 计算光流的平均幅度
122
+ * 包含诊断日志用于调试
124
123
  */
125
124
  private calculateFlowMagnitude;
126
125
  /**
@@ -151,6 +150,10 @@ export declare class MotionLivenessDetector {
151
150
  * 用于检测嘴巴张开的变化
152
151
  */
153
152
  private calculateMouthAspectRatio;
153
+ /**
154
+ * 计算面部中心(所有关键点的平均位置)
155
+ */
156
+ private calculateFaceCenter;
154
157
  /**
155
158
  * 计算两个点之间的距离
156
159
  */
@@ -167,6 +170,12 @@ export declare class MotionLivenessDetector {
167
170
  * 计算人脸区域方差
168
171
  */
169
172
  private calculateFaceAreaVariance;
173
+ /**
174
+ * 计算人脸区域的变化率 - 用于检测呼吸或其他微妙运动
175
+ * 活体在呼吸或说话时,面部区域会有微小的周期性变化
176
+ * 照片:变化很小或波动随机
177
+ */
178
+ private calculateFaceAreaChangeRate;
170
179
  /**
171
180
  * 计算数字数组的方差
172
181
  */
@@ -182,19 +191,25 @@ export declare class MotionLivenessDetector {
182
191
  private calculateOverallMotionScore;
183
192
  /**
184
193
  * 根据运动分析确定面部是否活跃
185
- * 修复:改进对真实面部运动的识别,减少误判
194
+ * 【针对5帧场景优化】:改为"多数票"制,使用6个独立指标
195
+ *
196
+ * 6个检测指标(互相独立):
197
+ * 1. 关键点变化 - 照片无法改变关键点位置
198
+ * 2. 光流幅度 - 照片产生的光流极低
199
+ * 3. 运动类型 - 照片只能是'none'
200
+ * 4. 眼睛运动(眨眼)- 照片眼睛无法眨动
201
+ * 5. 嘴巴运动 - 照片嘴巴完全静止
202
+ * 6. 面部区域变化 - 照片无法产生呼吸迹象
203
+ *
204
+ * 判决规则:
205
+ * - 数据充足(>= 5帧):需要至少2个指标支持才判定为活体
206
+ * - 数据不足(< 5帧):需要至少3个指标支持
186
207
  */
187
208
  private determineLiveness;
188
209
  /**
189
210
  * 分析失败时创建空结果
190
211
  */
191
212
  private createEmptyResult;
192
- /**
193
- * 验证运动的物理约束
194
- * 照片微动的运动往往会违反物理约束(如速度跳跃)
195
- * 真实面部运动应该表现出光滑的加速度和速度变化
196
- */
197
- private validatePhysicalConstraints;
198
213
  /**
199
214
  * 获取运动检测结果(用于调试)
200
215
  */
@@ -1 +1 @@
1
- {"version":3,"file":"motion-liveness-detector.d.ts","sourceRoot":"","sources":["../../src/motion-liveness-detector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"motion-liveness-detector.d.ts","sourceRoot":"","sources":["../../src/motion-liveness-detector.ts"],"names":[],"mappings":"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"}