@sssxyd/face-liveness-detector 0.4.0-alpha.9 → 0.4.1-beta.1
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.en.md +115 -146
- package/README.md +21 -52
- package/dist/index.esm.js +2218 -3077
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2218 -3077
- package/dist/index.js.map +1 -1
- package/dist/types/browser_utils.d.ts +3 -3
- package/dist/types/browser_utils.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/dlp-color-wheel-detector.d.ts +76 -0
- package/dist/types/dlp-color-wheel-detector.d.ts.map +1 -0
- package/dist/types/face-detection-engine.d.ts +59 -20
- package/dist/types/face-detection-engine.d.ts.map +1 -1
- package/dist/types/face-detection-state.d.ts +1 -5
- package/dist/types/face-detection-state.d.ts.map +1 -1
- package/dist/types/face-frontal-calculator.d.ts +3 -3
- package/dist/types/face-frontal-calculator.d.ts.map +1 -1
- package/dist/types/image-quality-calculator.d.ts +10 -23
- package/dist/types/image-quality-calculator.d.ts.map +1 -1
- package/dist/types/motion-liveness-detector.d.ts +258 -124
- package/dist/types/motion-liveness-detector.d.ts.map +1 -1
- package/dist/types/optical-distortion-detector.d.ts +116 -0
- package/dist/types/optical-distortion-detector.d.ts.map +1 -0
- package/dist/types/screen-capture-detector.d.ts +74 -115
- package/dist/types/screen-capture-detector.d.ts.map +1 -1
- package/dist/types/screen-corners-contour-detector.d.ts +78 -0
- package/dist/types/screen-corners-contour-detector.d.ts.map +1 -0
- package/dist/types/screen-flicker-detector.d.ts +103 -0
- package/dist/types/screen-flicker-detector.d.ts.map +1 -0
- package/dist/types/screen-moire-pattern-detect.d.ts.map +1 -1
- package/dist/types/screen-response-time-detector.d.ts +70 -0
- package/dist/types/screen-response-time-detector.d.ts.map +1 -0
- package/dist/types/screen-rgb-emission-detect.d.ts.map +1 -1
- package/dist/types/types.d.ts +8 -54
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/video-frame-collector.d.ts +111 -0
- package/dist/types/video-frame-collector.d.ts.map +1 -0
- package/package.json +2 -1
|
@@ -1,203 +1,337 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* 活体检测器 - 微妙运动检测版本 + 照片几何特征检测
|
|
3
|
+
*
|
|
4
|
+
* 双重检测策略:
|
|
5
|
+
* 1. 正向检测:检测生物特征(微妙眨眼、细微张嘴、面部肌肉微动)
|
|
6
|
+
* 2. 逆向检测:检测照片几何特征(平面约束、透视变换规律、交叉比率)
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ 关键理解 ⚠️
|
|
9
|
+
* MediaPipe 返回的 Z 坐标(深度)是从2D图像【推断】出来的,不是真实的物理深度!
|
|
10
|
+
* - 对真实人脸:推断出正确的 3D 结构
|
|
11
|
+
* - 对照片人脸:也可能推断出"假"的 3D 结构(因为照片上的人脸看起来也像 3D 的)
|
|
12
|
+
*
|
|
13
|
+
* 因此,检测策略优先级:
|
|
14
|
+
* 1. 【最可靠】2D 几何约束检测(单应性、交叉比率、透视变换规律)——物理定律,无法欺骗
|
|
15
|
+
* 2. 【次可靠】生物特征时序检测(眨眼时间、对称性)——行为模式
|
|
16
|
+
* 3. 【辅助参考】Z 坐标分析——可能被欺骗,仅作辅助
|
|
4
17
|
*/
|
|
5
18
|
import type { FaceResult } from '@vladmandic/human';
|
|
6
19
|
import type { Box } from '@vladmandic/human';
|
|
7
20
|
/**
|
|
8
|
-
*
|
|
21
|
+
* 活体检测结果
|
|
9
22
|
*/
|
|
10
23
|
export declare class MotionDetectionResult {
|
|
11
|
-
motionScore: number;
|
|
12
|
-
opticalFlowMagnitude: number;
|
|
13
|
-
keypointVariance: number;
|
|
14
|
-
eyeMotionScore: number;
|
|
15
|
-
mouthMotionScore: number;
|
|
16
|
-
motionType: MotionType;
|
|
17
24
|
isLively: boolean;
|
|
18
25
|
details: {
|
|
19
26
|
frameCount: number;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
eyeAspectRatioStdDev: number;
|
|
28
|
+
mouthAspectRatioStdDev: number;
|
|
29
|
+
eyeFluctuation: number;
|
|
30
|
+
mouthFluctuation: number;
|
|
31
|
+
muscleVariation: number;
|
|
32
|
+
hasEyeMovement: boolean;
|
|
33
|
+
hasMouthMovement: boolean;
|
|
34
|
+
hasMuscleMovement: boolean;
|
|
35
|
+
isPhoto?: boolean;
|
|
36
|
+
photoConfidence?: number;
|
|
37
|
+
homographyScore?: number;
|
|
38
|
+
perspectiveScore?: number;
|
|
39
|
+
crossRatioScore?: number;
|
|
40
|
+
depthVariation?: number;
|
|
41
|
+
crossFramePattern?: number;
|
|
25
42
|
};
|
|
26
|
-
constructor(
|
|
27
|
-
|
|
28
|
-
avgKeypointDistance: number;
|
|
29
|
-
maxKeypointDistance: number;
|
|
30
|
-
faceAreaVariance: number;
|
|
31
|
-
eyeAspectRatioVariance: number;
|
|
32
|
-
mouthAspectRatioVariance: number;
|
|
33
|
-
});
|
|
34
|
-
/**
|
|
35
|
-
* 获取活体检测结果信息
|
|
36
|
-
* 如果活跃,返回空字符串,否则返回非活体检测的原因
|
|
37
|
-
*/
|
|
38
|
-
getMessage(minMotionScore: number, minKeypointVariance: number): string;
|
|
43
|
+
constructor(isLively: boolean, details: any);
|
|
44
|
+
getMessage(): string;
|
|
39
45
|
}
|
|
40
|
-
export type MotionType = 'none' | 'rotation' | 'translation' | 'breathing' | 'micro_expression';
|
|
41
|
-
/**
|
|
42
|
-
* 运动活体检测选项
|
|
43
|
-
*/
|
|
44
46
|
export interface MotionLivenessDetectorOptions {
|
|
45
|
-
minMotionThreshold?: number;
|
|
46
|
-
minKeypointVariance?: number;
|
|
47
47
|
frameBufferSize?: number;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
eyeMinFluctuation?: number;
|
|
49
|
+
mouthMinFluctuation?: number;
|
|
50
|
+
muscleMinVariation?: number;
|
|
51
|
+
activityThreshold?: number;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
54
|
+
* 活体检测器 - 超敏感微动作版本 + 照片几何特征检测
|
|
55
|
+
*
|
|
56
|
+
* 双重策略:
|
|
57
|
+
* 1. 检测生物微动(正向)
|
|
58
|
+
* 2. 检测照片几何约束(逆向)- 更可靠
|
|
56
59
|
*/
|
|
57
60
|
export declare class MotionLivenessDetector {
|
|
58
|
-
private
|
|
59
|
-
private readonly minKeypointVariance;
|
|
60
|
-
private readonly frameBufferSize;
|
|
61
|
-
private readonly eyeAspectRatioThreshold;
|
|
62
|
-
private readonly motionConsistencyThreshold;
|
|
63
|
-
private readonly minOpticalFlowThreshold;
|
|
64
|
-
private readonly strictPhotoDetection;
|
|
65
|
-
private frameBuffer;
|
|
66
|
-
private keypointHistory;
|
|
67
|
-
private faceAreaHistory;
|
|
61
|
+
private config;
|
|
68
62
|
private eyeAspectRatioHistory;
|
|
69
63
|
private mouthAspectRatioHistory;
|
|
70
|
-
private
|
|
71
|
-
private
|
|
72
|
-
private
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
private faceLandmarksHistory;
|
|
65
|
+
private normalizedLandmarksHistory;
|
|
66
|
+
private leftEyeEARHistory;
|
|
67
|
+
private rightEyeEARHistory;
|
|
68
|
+
private frameTimestamps;
|
|
69
|
+
private rigidMotionHistory;
|
|
70
|
+
private homographyErrors;
|
|
71
|
+
private depthConsistencyScores;
|
|
72
|
+
private planarityScores;
|
|
73
|
+
constructor();
|
|
74
|
+
getOptions(): Required<MotionLivenessDetectorOptions>;
|
|
75
75
|
isReady(): boolean;
|
|
76
|
+
reset(): void;
|
|
77
|
+
analyzeMotion(faceResult: FaceResult, faceBox: Box): MotionDetectionResult;
|
|
76
78
|
/**
|
|
77
|
-
*
|
|
79
|
+
* 检测眼睛的微妙波动(任何变化)
|
|
80
|
+
* 防护:排除透视畸变、噪声,确保是真实的连续或周期性波动
|
|
78
81
|
*/
|
|
79
|
-
|
|
82
|
+
private detectEyeFluctuation;
|
|
80
83
|
/**
|
|
81
|
-
*
|
|
84
|
+
* 检测嘴巴的微妙波动(任何变化)
|
|
85
|
+
* 防护:排除噪声,确保是真实的张嘴/闭嘴动作
|
|
82
86
|
*/
|
|
83
|
-
|
|
87
|
+
private detectMouthFluctuation;
|
|
84
88
|
/**
|
|
85
|
-
*
|
|
89
|
+
* 【关键】检测真实的嘴巴张嘴→闭嘴动作
|
|
90
|
+
*
|
|
91
|
+
* 原理类似眨眼,需要检测下降和上升的连续段
|
|
86
92
|
*/
|
|
87
|
-
private
|
|
93
|
+
private detectRealMouthMovement;
|
|
88
94
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* 照片微动:通常表现为只有光流或只有噪声,或两者都非常低
|
|
95
|
+
* 检测面部肌肉的微动(关键点位置微妙变化)
|
|
96
|
+
* 关键:允许刚性运动+生物特征(真人摇头),拒绝纯刚性运动(照片旋转)
|
|
92
97
|
*
|
|
93
|
-
*
|
|
94
|
-
* - 大幅度头部运动(旋转/平移): 高keypoint variance, 中等optical flow
|
|
95
|
-
* - 微妙表情运动: 中等optical flow, 低keypoint variance
|
|
96
|
-
* - 照片微动: 两者都很低,或严重不匹配(一个近零一个不近零)
|
|
98
|
+
* 【重要修复】使用归一化坐标进行比较,消除人脸在画面中移动的影响
|
|
97
99
|
*/
|
|
98
|
-
private
|
|
100
|
+
private detectMuscleMovement;
|
|
99
101
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
+
* 【防护机制】检测照片透视畸变(倾角拍摄)
|
|
103
|
+
*
|
|
104
|
+
* 原理:
|
|
105
|
+
* - 照片是平面:所有关键点Z坐标(深度)应该相同且恒定
|
|
106
|
+
* - 当从倾角看平面照片时,虽然会产生2D投影变形,但深度仍然固定在一个平面
|
|
107
|
+
* - 真实活体:脸部有Z坐标深度,不同区域有深度差异(鼻子、下巴等突出)
|
|
108
|
+
*
|
|
109
|
+
* 返回值:照片平面性得分(0-1,越接近1越可能是平面照片)
|
|
102
110
|
*/
|
|
103
|
-
private
|
|
111
|
+
private detectPhotoPlanarity;
|
|
104
112
|
/**
|
|
105
|
-
*
|
|
113
|
+
* 【防护机制】检测刚性运动(照片被拿着旋转/平移)
|
|
114
|
+
*
|
|
115
|
+
* 原理:
|
|
116
|
+
* - 照片所有关键点运动是【刚性的】→ 所有点以相同方向、相似幅度移动
|
|
117
|
+
* - 活体肌肉运动是【非刚性的】→ 不同部位独立运动(眼睛、嘴、脸颊等)
|
|
118
|
+
*
|
|
119
|
+
* 【重要修复】使用归一化坐标进行比较
|
|
120
|
+
*
|
|
121
|
+
* 返回值 0-1:值越接近1说明是刚性运动(照片运动)
|
|
106
122
|
*/
|
|
107
|
-
private
|
|
123
|
+
private detectRigidMotion;
|
|
108
124
|
/**
|
|
109
|
-
*
|
|
110
|
-
* 使用网格标志点(来自 MediaPipe Face Mesh 模型的 468 个点)
|
|
125
|
+
* 计算角度的平均值(考虑循环性)
|
|
111
126
|
*/
|
|
112
|
-
private
|
|
127
|
+
private calculateMeanAngle;
|
|
113
128
|
/**
|
|
114
|
-
*
|
|
115
|
-
*
|
|
129
|
+
* 检测序列是否呈现【往复波动】而不是【单向变化】
|
|
130
|
+
*
|
|
131
|
+
* 原理:
|
|
132
|
+
* - 真实眨眼/表情:值会【往复波动】 如 0.4 → 0.3 → 0.4 → 0.5
|
|
133
|
+
* - 照片透视变形:值会【单向变化】 如 0.4 → 0.3 → 0.25 → 0.2
|
|
134
|
+
*
|
|
135
|
+
* 返回值:true = 检测到往复波动(活体特征)
|
|
116
136
|
*/
|
|
117
|
-
private
|
|
137
|
+
private detectOscillation;
|
|
118
138
|
/**
|
|
119
|
-
*
|
|
139
|
+
* 【关键】检测真实眨眼(连续的闭眼→睁眼周期)
|
|
140
|
+
*
|
|
141
|
+
* 原理:
|
|
142
|
+
* - 真实眨眼:快速下降(EAR↓ 1-2帧)→ 保持低值(EAR低 2-3帧)→ 快速上升(EAR↑ 1-2帧)
|
|
143
|
+
* - 噪声或光线变化:孤立的异常值,前后没有连续的变化模式
|
|
144
|
+
*
|
|
145
|
+
* 返回值:true = 检测到完整或部分眨眼周期
|
|
146
|
+
*/
|
|
147
|
+
private detectRealBlink;
|
|
148
|
+
/**
|
|
149
|
+
* 【新增防护】检测左右眼对称性
|
|
150
|
+
*
|
|
151
|
+
* 原理:
|
|
152
|
+
* - 真实眨眼:左右眼几乎同时闭合和睁开,EAR变化高度同步
|
|
153
|
+
* - 照片透视畸变:根据偏转方向,一只眼睛可能比另一只变化更大
|
|
154
|
+
*
|
|
155
|
+
* 返回值 0-1:越接近1说明左右眼越对称(越像真实眨眼)
|
|
120
156
|
*/
|
|
121
|
-
private
|
|
157
|
+
private detectEyeSymmetry;
|
|
122
158
|
/**
|
|
123
|
-
*
|
|
159
|
+
* 【新增防护】检测眨眼时间模式
|
|
160
|
+
*
|
|
161
|
+
* 原理:
|
|
162
|
+
* - 真实眨眼非常快:完整周期 100-400ms(3-12帧@30fps)
|
|
163
|
+
* - 手动摆动照片:周期通常 500ms-2000ms(15-60帧@30fps)
|
|
164
|
+
*
|
|
165
|
+
* 返回值:true = 检测到符合真实眨眼的快速时间模式
|
|
124
166
|
*/
|
|
125
|
-
private
|
|
167
|
+
private detectBlinkTiming;
|
|
126
168
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
169
|
+
* 【新增防护】检测运动-形变相关性
|
|
170
|
+
*
|
|
171
|
+
* 原理:
|
|
172
|
+
* - 照片偏转攻击:刚性运动越大 → EAR/MAR形变越大(高度相关)
|
|
173
|
+
* - 真实活体:眨眼/张嘴与头部运动无关(低相关或无相关)
|
|
174
|
+
*
|
|
175
|
+
* 返回值 0-1:越接近1说明运动和形变越相关(越像照片攻击)
|
|
130
176
|
*/
|
|
131
|
-
private
|
|
177
|
+
private detectMotionDeformCorrelation;
|
|
132
178
|
/**
|
|
133
|
-
*
|
|
179
|
+
* 【关键】检测最近几帧是否有运动
|
|
180
|
+
*
|
|
181
|
+
* 防护:某人在检测开始时眨眼,之后就完全静止
|
|
182
|
+
* 这种情况应该判定为照片,因为照片可以有偶然的反光
|
|
183
|
+
* 活体应该有【持续的或周期性的】动作
|
|
184
|
+
*
|
|
185
|
+
* 返回值:true = 最近3-5帧内有明显变化
|
|
134
186
|
*/
|
|
135
|
-
private
|
|
187
|
+
private detectRecentMovement;
|
|
136
188
|
/**
|
|
137
|
-
*
|
|
189
|
+
* 【核心】照片几何特征检测(逆向检测)
|
|
190
|
+
*
|
|
191
|
+
* 重要说明:
|
|
192
|
+
* - MediaPipe的Z坐标是从2D图像【推断】的,不是真实深度
|
|
193
|
+
* - 对照片也可能推断出"假"的3D结构
|
|
194
|
+
* - 因此【2D几何约束】比【Z坐标分析】更可靠
|
|
195
|
+
*
|
|
196
|
+
* 可靠的检测(基于2D几何,物理定律):
|
|
197
|
+
* 1. 单应性变换约束 - 平面必须满足
|
|
198
|
+
* 2. 特征点相对位置变化 - 照片偏转时遵循透视规律
|
|
199
|
+
*
|
|
200
|
+
* 参考性检测(基于推断的Z坐标,可能被欺骗):
|
|
201
|
+
* 1. 深度一致性 - 辅助参考
|
|
202
|
+
* 2. 跨帧深度模式 - 辅助参考
|
|
138
203
|
*/
|
|
139
|
-
private
|
|
204
|
+
private detectPhotoGeometry;
|
|
140
205
|
/**
|
|
141
|
-
*
|
|
206
|
+
* 【新增核心检测】交叉比率不变性检测
|
|
207
|
+
*
|
|
208
|
+
* 原理(射影几何的基本定理):
|
|
209
|
+
* - 平面上共线4点的【交叉比率】在透视变换下保持不变
|
|
210
|
+
* - 真实3D人脸旋转时,面部各点不共面,交叉比率会变化
|
|
211
|
+
* - 照片无论怎么偏转,共线点的交叉比率保持不变
|
|
212
|
+
*
|
|
213
|
+
* 这是纯2D几何检测,非常可靠!
|
|
142
214
|
*/
|
|
143
|
-
private calculateMaxKeypointDistance;
|
|
144
215
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
216
|
+
* 【交叉比率不变性检测】
|
|
217
|
+
*
|
|
218
|
+
* 原理(射影几何的基本定理):
|
|
219
|
+
* - 平面上共线4点的【交叉比率】在透视变换下保持不变
|
|
220
|
+
* - 真实3D人脸旋转时,面部各点不共面,交叉比率会变化
|
|
221
|
+
* - 照片无论怎么偏转,共线点的交叉比率保持不变
|
|
222
|
+
*
|
|
223
|
+
* 【注意】交叉比率本身是比率,不依赖绝对坐标
|
|
224
|
+
* 使用归一化坐标只是为了一致性
|
|
147
225
|
*/
|
|
148
|
-
private
|
|
226
|
+
private detectCrossRatioInvariance;
|
|
149
227
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
228
|
+
* 【关键】检测单应性变换约束
|
|
229
|
+
*
|
|
230
|
+
* 原理:
|
|
231
|
+
* - 平面物体(照片)在不同视角下的投影满足 H * p1 = p2(H是3x3单应性矩阵)
|
|
232
|
+
* - 3D物体不满足这个约束,会有残差误差
|
|
233
|
+
*
|
|
234
|
+
* 方法:用4对点计算H,然后检验其他点是否符合H变换
|
|
152
235
|
*/
|
|
153
|
-
private calculateMouthAspectRatio;
|
|
154
236
|
/**
|
|
155
|
-
*
|
|
237
|
+
* 【单应性约束检测】判断多帧特征点是否满足平面约束
|
|
238
|
+
*
|
|
239
|
+
* 【重要修复】使用归一化坐标进行比较
|
|
240
|
+
* 这是纯 2D 几何检测,最可靠!
|
|
156
241
|
*/
|
|
157
|
-
private
|
|
242
|
+
private detectHomographyConstraint;
|
|
158
243
|
/**
|
|
159
|
-
*
|
|
244
|
+
* 估计仿射变换矩阵 (简化的单应性)
|
|
245
|
+
* 输入:源点和目标点对
|
|
246
|
+
* 输出:[a, b, c, d, e, f] 表示变换 x' = ax + by + c, y' = dx + ey + f
|
|
160
247
|
*/
|
|
161
|
-
private
|
|
248
|
+
private estimateAffineTransform;
|
|
162
249
|
/**
|
|
163
|
-
*
|
|
250
|
+
* 应用仿射变换
|
|
164
251
|
*/
|
|
165
|
-
private
|
|
252
|
+
private applyAffineTransform;
|
|
166
253
|
/**
|
|
167
|
-
*
|
|
254
|
+
* 【关键】检测深度一致性
|
|
255
|
+
*
|
|
256
|
+
* 原理:
|
|
257
|
+
* - 真实人脸:鼻子Z坐标明显大于眼睛和脸颊(凸出)
|
|
258
|
+
* - 照片:所有点Z坐标接近相同(平面)
|
|
168
259
|
*/
|
|
169
|
-
private
|
|
260
|
+
private detectDepthConsistency;
|
|
170
261
|
/**
|
|
171
|
-
*
|
|
262
|
+
* 【关键】检测跨帧深度模式
|
|
263
|
+
*
|
|
264
|
+
* 原理:
|
|
265
|
+
* - 照片旋转时:所有点的深度变化遵循平面投影规律(线性关系)
|
|
266
|
+
* - 真实人脸旋转时:不同部位的深度变化不成线性关系
|
|
172
267
|
*/
|
|
173
|
-
private
|
|
268
|
+
private detectCrossFrameDepthPattern;
|
|
174
269
|
/**
|
|
175
|
-
*
|
|
270
|
+
* 【关键】检测透视变换模式
|
|
271
|
+
*
|
|
272
|
+
* 原理:
|
|
273
|
+
* - 照片偏转时,特征点位置变化遵循严格的透视变换规律
|
|
274
|
+
* - 检测左右脸的相对变化是否符合透视投影
|
|
176
275
|
*/
|
|
177
|
-
private detectMotionType;
|
|
178
276
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
277
|
+
* 【透视变换模式检测】
|
|
278
|
+
*
|
|
279
|
+
* 【重要修复】使用归一化坐标进行比较
|
|
280
|
+
*
|
|
281
|
+
* 原理:照片左右偏转时,左右脸宽度比例会平滑变化
|
|
181
282
|
*/
|
|
182
|
-
private
|
|
283
|
+
private detectPerspectiveTransformPattern;
|
|
183
284
|
/**
|
|
184
|
-
*
|
|
185
|
-
*
|
|
285
|
+
* 综合判定 - 结合正向检测(生物特征)和逆向检测(照片几何)
|
|
286
|
+
*
|
|
287
|
+
* 双重策略:
|
|
288
|
+
* 1. 正向:检测生物微动特征(有 → 活体)
|
|
289
|
+
* 2. 逆向:检测照片几何约束(满足 → 照片)
|
|
290
|
+
*
|
|
291
|
+
* 逆向检测优先级更高,因为照片几何约束是物理定律,无法伪造
|
|
186
292
|
*/
|
|
187
|
-
private
|
|
293
|
+
private makeLivenessDecision;
|
|
188
294
|
/**
|
|
189
|
-
*
|
|
295
|
+
* 【防护机制】检查脸部形状稳定性
|
|
296
|
+
*
|
|
297
|
+
* 原理:
|
|
298
|
+
* - 真实脸部:眨眼、张嘴等会改变脸部几何形状(EAR/MAR 变化)
|
|
299
|
+
* - 照片:脸部形状完全固定,不会有任何变化
|
|
300
|
+
* - 倾角照片:虽然会产生透视变形,但仍然是平面的,Z坐标无深度
|
|
301
|
+
*
|
|
302
|
+
* 返回值 0-1:值越接近1说明脸部形状越稳定(越可能是照片)
|
|
190
303
|
*/
|
|
191
|
-
private createEmptyResult;
|
|
192
304
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
305
|
+
* 检查脸部形状稳定性
|
|
306
|
+
*
|
|
307
|
+
* 【重要修复】使用归一化坐标进行比较
|
|
308
|
+
* 这样即使人脸在画面中移动或缩放,比较仍然有效
|
|
196
309
|
*/
|
|
197
|
-
private
|
|
310
|
+
private checkFaceShapeStability;
|
|
311
|
+
private extractKeypoints;
|
|
312
|
+
private calculateEyeAspectRatio;
|
|
313
|
+
private calculateMouthAspectRatio;
|
|
314
|
+
private pointDist;
|
|
315
|
+
private calculateStdDev;
|
|
198
316
|
/**
|
|
199
|
-
*
|
|
317
|
+
* 【关键方法】将关键点坐标归一化到人脸局部坐标系
|
|
318
|
+
*
|
|
319
|
+
* 问题:
|
|
320
|
+
* - MediaPipe 返回的 x,y 坐标是相对于【图像左上角】的像素坐标
|
|
321
|
+
* - 如果人脸在画面中移动,同一个关键点的绝对坐标会完全不同
|
|
322
|
+
* - 多帧之间直接比较绝对坐标是错误的!
|
|
323
|
+
*
|
|
324
|
+
* 解决:
|
|
325
|
+
* - 将坐标转换为相对于人脸边界框的归一化坐标
|
|
326
|
+
* - 归一化坐标 = (点坐标 - 人脸左上角) / 人脸尺寸
|
|
327
|
+
* - 这样无论人脸在画面中的位置,归一化坐标都一致
|
|
328
|
+
*
|
|
329
|
+
* @param landmarks 原始关键点数组
|
|
330
|
+
* @param faceBox 人脸边界框 [x, y, width, height]
|
|
331
|
+
* @returns 归一化后的关键点数组
|
|
200
332
|
*/
|
|
333
|
+
private normalizeLandmarks;
|
|
334
|
+
private createEmptyResult;
|
|
201
335
|
getStatistics(): any;
|
|
202
336
|
}
|
|
203
337
|
//# sourceMappingURL=motion-liveness-detector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"motion-liveness-detector.d.ts","sourceRoot":"","sources":["../../src/motion-liveness-detector.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"motion-liveness-detector.d.ts","sourceRoot":"","sources":["../../src/motion-liveness-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 光学畸变检测器 - 检测投影仪和其他光学系统的特有伪影
|
|
3
|
+
*
|
|
4
|
+
* 核心原理:
|
|
5
|
+
* - 投影仪通过光学透镜将图像投射到屏幕上
|
|
6
|
+
* - 光学系统导致多种失真:梯形失真、桶形/枕形失真、模糊
|
|
7
|
+
* - 真实人脸直接摄像,无这些光学失真
|
|
8
|
+
*
|
|
9
|
+
* 检测特征:
|
|
10
|
+
* 1. 梯形失真(Keystone)- 图像上下边宽度不同
|
|
11
|
+
* 2. 桶形/枕形失真 - 直线边缘弯曲
|
|
12
|
+
* 3. 光学模糊 - 边界清晰度在视场中不均匀
|
|
13
|
+
* 4. 色差(Chromatic Aberration)- RGB通道空间分离
|
|
14
|
+
* 5. 暗角(Vignetting)- 四角暗化
|
|
15
|
+
*/
|
|
16
|
+
import { VideoFrameCollector } from "./video-frame-collector";
|
|
17
|
+
export interface OpticalDistortionDetectorConfig {
|
|
18
|
+
bufferSize: number;
|
|
19
|
+
keystoneThreshold: number;
|
|
20
|
+
barrelDistortionThreshold: number;
|
|
21
|
+
chromaticAberrationThreshold: number;
|
|
22
|
+
vignetteThreshold: number;
|
|
23
|
+
samplingStride: number;
|
|
24
|
+
featureWeights: {
|
|
25
|
+
keystone: number;
|
|
26
|
+
barrelDistortion: number;
|
|
27
|
+
chromaticAberration: number;
|
|
28
|
+
vignette: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface OpticalDistortionDetectionResult {
|
|
32
|
+
isScreenCapture: boolean;
|
|
33
|
+
confidence: number;
|
|
34
|
+
distortionFeatures: {
|
|
35
|
+
keystoneDetected: boolean;
|
|
36
|
+
keystoneLevel: number;
|
|
37
|
+
barrelDistortionDetected: boolean;
|
|
38
|
+
barrelDistortionLevel: number;
|
|
39
|
+
chromaticAberrationDetected: boolean;
|
|
40
|
+
chromaticAberrationLevel: number;
|
|
41
|
+
vignetteDetected: boolean;
|
|
42
|
+
vignetteLevel: number;
|
|
43
|
+
};
|
|
44
|
+
overallOpticalDistortionScore: number;
|
|
45
|
+
estimatedProjectorType?: 'dlp' | 'lcd' | 'lcos' | 'unknown';
|
|
46
|
+
details?: any;
|
|
47
|
+
}
|
|
48
|
+
export declare class OpticalDistortionDetector {
|
|
49
|
+
private config;
|
|
50
|
+
private frameCollector;
|
|
51
|
+
constructor(frameCollector: VideoFrameCollector, config: OpticalDistortionDetectorConfig);
|
|
52
|
+
/**
|
|
53
|
+
* 获取当前缓冲区中的帧数
|
|
54
|
+
*/
|
|
55
|
+
getBufferedFrameCount(): number;
|
|
56
|
+
/**
|
|
57
|
+
* 执行光学畸变检测分析
|
|
58
|
+
*/
|
|
59
|
+
analyze(): OpticalDistortionDetectionResult;
|
|
60
|
+
/**
|
|
61
|
+
* 注意:重置由 FrameCollector 管理
|
|
62
|
+
* 此检测器不持有任何帧缓冲
|
|
63
|
+
*/
|
|
64
|
+
reset(): void;
|
|
65
|
+
/**
|
|
66
|
+
* 检测梯形失真(Keystone)
|
|
67
|
+
*
|
|
68
|
+
* 原理:
|
|
69
|
+
* - 梯形失真导致图像上下边宽度不同
|
|
70
|
+
* - 计算上下边的宽度比
|
|
71
|
+
*/
|
|
72
|
+
private detectKeystone;
|
|
73
|
+
/**
|
|
74
|
+
* 检测桶形/枕形失真
|
|
75
|
+
*
|
|
76
|
+
* 原理:
|
|
77
|
+
* - 提取图像边界
|
|
78
|
+
* - 拟合边界为曲线,计算曲率
|
|
79
|
+
* - 高曲率表示失真
|
|
80
|
+
*/
|
|
81
|
+
private detectBarrelDistortion;
|
|
82
|
+
/**
|
|
83
|
+
* 检测色差(RGB通道分离)
|
|
84
|
+
*/
|
|
85
|
+
private detectChromaticAberration;
|
|
86
|
+
/**
|
|
87
|
+
* 检测暗角(四角暗化)
|
|
88
|
+
*
|
|
89
|
+
* 原理:
|
|
90
|
+
* - 计算四个角区域的平均亮度
|
|
91
|
+
* - 与中心区域对比
|
|
92
|
+
* - 大幅下降表示暗角
|
|
93
|
+
*/
|
|
94
|
+
private detectVignette;
|
|
95
|
+
/**
|
|
96
|
+
* 找水平边界的宽度
|
|
97
|
+
*/
|
|
98
|
+
private findHorizontalEdgeWidth;
|
|
99
|
+
/**
|
|
100
|
+
* 测量边界的垂直直线度(曲率)
|
|
101
|
+
*/
|
|
102
|
+
private measureBoundaryDeviation;
|
|
103
|
+
/**
|
|
104
|
+
* 找在特定y处的垂直边界
|
|
105
|
+
*/
|
|
106
|
+
private findVerticalEdgeAtY;
|
|
107
|
+
/**
|
|
108
|
+
* 计算矩形区域的平均亮度
|
|
109
|
+
*/
|
|
110
|
+
private getAverageBrightness;
|
|
111
|
+
/**
|
|
112
|
+
* 推断投影仪类型
|
|
113
|
+
*/
|
|
114
|
+
private inferProjectorType;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=optical-distortion-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optical-distortion-detector.d.ts","sourceRoot":"","sources":["../../src/optical-distortion-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,MAAM,WAAW,+BAA+B;IAE9C,UAAU,EAAE,MAAM,CAAA;IAGlB,iBAAiB,EAAE,MAAM,CAAA;IAGzB,yBAAyB,EAAE,MAAM,CAAA;IAGjC,4BAA4B,EAAE,MAAM,CAAA;IAGpC,iBAAiB,EAAE,MAAM,CAAA;IAGzB,cAAc,EAAE,MAAM,CAAA;IAGtB,cAAc,EAAE;QACd,QAAQ,EAAE,MAAM,CAAA;QAChB,gBAAgB,EAAE,MAAM,CAAA;QACxB,mBAAmB,EAAE,MAAM,CAAA;QAC3B,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,gCAAgC;IAC/C,eAAe,EAAE,OAAO,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAGlB,kBAAkB,EAAE;QAClB,gBAAgB,EAAE,OAAO,CAAA;QACzB,aAAa,EAAE,MAAM,CAAA;QAErB,wBAAwB,EAAE,OAAO,CAAA;QACjC,qBAAqB,EAAE,MAAM,CAAA;QAE7B,2BAA2B,EAAE,OAAO,CAAA;QACpC,wBAAwB,EAAE,MAAM,CAAA;QAEhC,gBAAgB,EAAE,OAAO,CAAA;QACzB,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;IAGD,6BAA6B,EAAE,MAAM,CAAA;IAGrC,sBAAsB,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;IAE3D,OAAO,CAAC,EAAE,GAAG,CAAA;CACd;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,cAAc,CAAqB;gBAE/B,cAAc,EAAE,mBAAmB,EAAE,MAAM,EAAE,+BAA+B;IAUxF;;OAEG;IACH,qBAAqB,IAAI,MAAM;IAI/B;;OAEG;IACH,OAAO,IAAI,gCAAgC;IA6F3C;;;OAGG;IACH,KAAK,IAAI,IAAI;IAKb;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IA8BtB;;;;;;;OAOG;IACH,OAAO,CAAC,sBAAsB;IA0B9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAajC;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IA0DtB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA8B/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiC3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAgC3B"}
|