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

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 CHANGED
@@ -1,445 +1,609 @@
1
- > **Languages:** [English](#) · [中文](./README.zh-Hans.md)
1
+ <div align="center">
2
2
 
3
- # Face Detection Engine
3
+ > **语言 / Languages:** [中文](#) · [English](./README.en.md)
4
4
 
5
- A pure frontend, real-time face liveness detection engine built on **[Human.js](https://github.com/vladmandic/human)** and **[OpenCV.js](https://github.com/TechStark/opencv-js)**. This TypeScript-based npm package provides real-time face detection, dual liveness verification (silent + action-based), automatic best frame selection, and anti-spoofing capabilities - all running 100% in the browser with zero backend dependency.
5
+ # 人脸活体检测引擎
6
6
 
7
- ## Features
7
+ <p>
8
+ <strong>基于 TensorFlow + OpenCV 的纯前端实时人脸活体检测解决方案</strong>
9
+ </p>
8
10
 
9
- - 💯 **Pure Frontend Implementation** - Zero backend dependency, all processing runs locally in the browser
10
- - 🔬 **Hybrid TensorFlow + OpenCV Solution** - Combines TensorFlow.js for AI detection with OpenCV.js for image processing
11
- - 🧠 **Dual Detection Modes** - Both silent liveness detection and action-based detection (blink, mouth open, nod) with automatic best frame selection
12
- - **Pure JavaScript & Event-Driven** - 100% TypeScript, reactive event architecture, seamless integration with any frontend framework (Vue, React, Angular, Svelte, or vanilla JS)
13
- - 🎯 **Comprehensive Face Analysis** - Real-time anti-spoofing, quality assessment, frontality detection, and blur detection
11
+ <p>
12
+ <img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-5.0+-3178c6?logo=typescript">
13
+ <img alt="NPM Package" src="https://img.shields.io/npm/v/@sssxyd/face-liveness-detector?label=npm&color=cb3837">
14
+ <img alt="License" src="https://img.shields.io/badge/license-MIT-green">
15
+ </p>
14
16
 
15
- ## 🚀 Try Online Demo
17
+ </div>
16
18
 
17
- **[👉 Live Demo: https://face.lowtechsoft.com/](https://face.lowtechsoft.com/)**
19
+ ---
18
20
 
19
- Scan the QR code with your phone to test the detection engine right now:
21
+ ## 功能特性
20
22
 
21
- [![Face Liveness Detection Demo QR Code](https://raw.githubusercontent.com/sssxyd/face-liveness-detector/main/demos/vue-demo/vue-demo.png)](https://face.lowtechsoft.com/)
22
- ## Installation
23
+ <table>
24
+ <tr>
25
+ <td>💯 <strong>纯前端实现</strong><br/>零后端依赖,所有处理在浏览器中本地运行</td>
26
+ <td>🔬 <strong>混合 AI 方案</strong><br/>TensorFlow + OpenCV 深度融合</td>
27
+ </tr>
28
+ <tr>
29
+ <td>🧠 <strong>双重活体验证</strong><br/>静默检测 + 动作识别(眨眼、张嘴、点头)</td>
30
+ <td>⚡ <strong>事件驱动架构</strong><br/>100% TypeScript,与任何框架无缝集成</td>
31
+ </tr>
32
+ <tr>
33
+ <td>🎯 <strong>全维度分析</strong><br/>质量、正对度、运动分数、屏幕检测</td>
34
+ <td>🛡️ <strong>多维反欺骗</strong><br/>照片、屏幕视频、莫尔纹、RGB发光检测</td>
35
+ </tr>
36
+ </table>
37
+
38
+ ---
39
+
40
+ ## 🚀 在线演示
41
+
42
+ <div align="center">
43
+
44
+ **[👉 实时体验演示](https://face.lowtechsoft.com/) | 用手机扫码快速测试**
45
+
46
+ [![人脸活体检测演示二维码](https://raw.githubusercontent.com/sssxyd/face-liveness-detector/main/demos/vue-demo/vue-demo.png)](https://face.lowtechsoft.com/)
47
+
48
+ </div>
49
+
50
+ ---
51
+
52
+ ## 🧬 核心算法设计
53
+
54
+ | 检测模块 | 技术方案 | 说明文档 |
55
+ |---------|--------|--------|
56
+ | **人脸识别** | Human.js BlazeFace + FaceMesh | 468个面部特征点 + 表情识别 |
57
+ | **动作检测** | 多维度运动分析 | [运动检测算法](./docs/MOTION_DETECTION_ALGORITHM.md) - 光流、关键点方差、面部区域变化 |
58
+ | **屏幕检测** | 三维特征融合 | [屏幕捕捉检测](./docs/SCREEN_CAPTURE_DETECTION_ALGORITHM.md) - 莫尔纹、RGB发光、色彩特征 |
59
+
60
+ ---
61
+
62
+ ## 📦 安装指南
63
+
64
+ ### 快速安装(3 个包)
23
65
 
24
66
  ```bash
25
67
  npm install @sssxyd/face-liveness-detector @vladmandic/human @techstark/opencv-js
26
68
  ```
27
69
 
28
- Or with yarn:
70
+ <details>
71
+ <summary><strong>其他包管理器</strong></summary>
72
+
29
73
  ```bash
74
+ # Yarn
30
75
  yarn add @sssxyd/face-liveness-detector @vladmandic/human @techstark/opencv-js
31
- ```
32
76
 
33
- Or with pnpm:
34
- ```bash
77
+ # pnpm
35
78
  pnpm add @sssxyd/face-liveness-detector @vladmandic/human @techstark/opencv-js
36
79
  ```
37
80
 
38
- > **Note**: `@vladmandic/human` and `@techstark/opencv-js` are peer dependencies and must be installed separately to avoid bundling large libraries. This keeps your final bundle size smaller if you're already using these libraries elsewhere in your project.
81
+ </details>
82
+
83
+ > 📝 **为什么需要三个包?**
84
+ > `@vladmandic/human` 和 `@techstark/opencv-js` 是对等依赖(peer dependencies),需要单独安装以避免捆绑大型库,减小最终的打包体积。
85
+
86
+ ---
87
+
88
+ ## ⚠️ 必要配置步骤
39
89
 
40
- ## Quick Start - Using Local Resources
90
+ ### 1️⃣ 修复 OpenCV.js ESM 兼容性问题
41
91
 
42
- > ⚠️ **CRITICAL**: `@techstark/opencv-js` contains an ESM incompatible UMD-format OpenCV.js library that **will cause load failures**. You MUST apply the patch script.
43
- > - **Issue**: https://github.com/TechStark/opencv-js/issues/44
44
- > - **Patch Script**: [patch-opencv.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/patch-opencv.js)
45
- > - **Setup**: Add to your `package.json` scripts as a `postinstall` hook to auto-apply after dependencies install
92
+ `@techstark/opencv-js` 包含不兼容的 UMD 格式,**必须应用补丁脚本**。
46
93
 
47
- > ⚠️ **CRITICAL**: `@vladmandic/human` requires downloading large model files and TensorFlow WASM backend files. The component **will fail to load without these resources**. Download them to your project directory and configure the paths.
48
- > - **Models Download Script**: [copy-models.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/copy-models.js)
49
- > - **WASM Download Script**: [download-wasm.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/download-wasm.js)
50
- > - **Setup**: Run both scripts as `postinstall` hooks, then configure paths in your engine config
94
+ **参考:**
95
+ - 问题详情:[TechStark/opencv-js#44](https://github.com/TechStark/opencv-js/issues/44)
96
+ - 补丁脚本:[patch-opencv.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/patch-opencv.js)
97
+
98
+ **设置方法(推荐):** 添加到 `package.json` 的 `postinstall` 钩子
99
+
100
+ ```json
101
+ {
102
+ "scripts": {
103
+ "postinstall": "node patch-opencv.cjs"
104
+ }
105
+ }
106
+ ```
51
107
 
108
+ ### 2️⃣ 下载 Human.js 模型文件
109
+
110
+ `@vladmandic/human` 需要模型文件和 TensorFlow WASM 后端,**否则无法加载**。
111
+
112
+ **下载脚本:**
113
+ - 模型复制:[copy-models.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/copy-models.js)
114
+ - WASM 下载:[download-wasm.js](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/scripts/download-wasm.js)
115
+
116
+ **设置方法(推荐):** 配置为 `postinstall` 钩子
117
+
118
+ ```json
119
+ {
120
+ "scripts": {
121
+ "postinstall": "node scripts/copy-models.js && node scripts/download-wasm.js"
122
+ }
123
+ }
124
+ ```
125
+
126
+ ---
127
+
128
+ ## 🎯 快速开始
129
+
130
+ ### 基础示例
52
131
 
53
132
  ```typescript
54
133
  import FaceDetectionEngine, { LivenessAction } from '@sssxyd/face-liveness-detector'
55
134
 
56
- // Initialize the engine with custom configuration
135
+ // 初始化引擎
57
136
  const engine = new FaceDetectionEngine({
58
- // Configure resource paths
137
+ // 资源路径配置
59
138
  human_model_path: '/models',
60
139
  tensorflow_wasm_path: '/wasm',
140
+ tensorflow_backend: 'auto',
61
141
 
62
- // Detection settings
63
- video_width: 640,
64
- video_height: 640,
65
-
66
- // Quality settings
67
- min_image_quality: 0.5,
68
- min_face_frontal: 0.9,
69
-
70
- // Liveness settings - choose your preferred actions
71
- liveness_action_count: 1, // 0 for silent detection only, 1-3 for action-based
72
- liveness_action_list: [LivenessAction.BLINK, LivenessAction.MOUTH_OPEN, LivenessAction.NOD]
142
+ // 检测设置(建议 ≥720p,否则屏幕检测准确率下降)
143
+ detect_video_ideal_width: 1920,
144
+ detect_video_ideal_height: 1080,
145
+ detect_video_mirror: true,
146
+ detect_video_load_timeout: 5000,
147
+ detect_frame_delay: 100,
148
+
149
+ // 采集质量要求
150
+ collect_min_collect_count: 3, // 最少采集 3 张人脸
151
+ collect_min_face_ratio: 0.5, // 人脸占比 50%+
152
+ collect_max_face_ratio: 0.9, // 人脸占比 90% 以下
153
+ collect_min_face_frontal: 0.9, // 人脸正对度 90%
154
+ collect_min_image_quality: 0.5, // 图像质量 50%+
155
+
156
+ // 活体检测设置
157
+ action_liveness_action_count: 1, // 需要 1 个动作
158
+ action_liveness_action_list: [LivenessAction.BLINK, LivenessAction.MOUTH_OPEN, LivenessAction.NOD],
159
+ action_liveness_action_randomize: true,
160
+ action_liveness_verify_timeout: 60000,
161
+
162
+ // 防欺骗设置
163
+ motion_liveness_min_motion_score: 0.15,
164
+ motion_liveness_strict_photo_detection: false,
165
+ screen_capture_confidence_threshold: 0.7,
73
166
  })
74
167
 
75
- // Listen for events
168
+ // 监听核心事件
76
169
  engine.on('detector-loaded', (data) => {
77
- console.log('✅ Engine is ready')
78
- console.log(`OpenCV: ${data.opencv_version}`)
79
- console.log(`Human.js: ${data.human_version}`)
170
+ if (data.success) {
171
+ console.log('✅ 引擎就绪', {
172
+ opencv: data.opencv_version,
173
+ human: data.human_version
174
+ })
175
+ }
80
176
  })
81
177
 
82
178
  engine.on('detector-info', (data) => {
83
- // Real-time detection information
179
+ // 每帧实时数据
84
180
  console.log({
85
- quality: (data.quality * 100).toFixed(1) + '%',
86
- frontal: (data.frontal * 100).toFixed(1) + '%',
87
- liveness: (data.live * 100).toFixed(1) + '%',
88
- realness: (data.real * 100).toFixed(1) + '%'
181
+ status: data.code,
182
+ quality: (data.imageQuality * 100).toFixed(1) + '%',
183
+ frontal: (data.faceFrontal * 100).toFixed(1) + '%',
184
+ motion: (data.motionScore * 100).toFixed(1) + '%',
185
+ screen: (data.screenConfidence * 100).toFixed(1) + '%'
89
186
  })
90
187
  })
91
188
 
92
189
  engine.on('detector-action', (data) => {
93
- // Action liveness prompts
94
- if (data.status === 'started') {
95
- console.log(`Please perform: ${data.action}`)
96
- } else if (data.status === 'completed') {
97
- console.log(`✅ Action recognized: ${data.action}`)
98
- }
190
+ // 动作提示
191
+ console.log(`请执行动作: ${data.action} (${data.status})`)
99
192
  })
100
193
 
101
194
  engine.on('detector-finish', (data) => {
195
+ // 检测完成
102
196
  if (data.success) {
103
- console.log('✅ Liveness verification passed!')
104
- console.log({
105
- silentDetections: data.silentPassedCount,
106
- actionsCompleted: data.actionPassedCount,
107
- imageQuality: (data.bestQualityScore * 100).toFixed(1) + '%',
108
- totalTime: (data.totalTime / 1000).toFixed(2) + 's',
109
- bestFrame: data.bestFrameImage, // Base64 encoded
110
- bestFace: data.bestFaceImage // Base64 encoded
197
+ console.log('✅ 活体验证通过!', {
198
+ 静默通过: data.silentPassedCount,
199
+ 动作完成: data.actionPassedCount,
200
+ 最佳质量: (data.bestQualityScore * 100).toFixed(1) + '%',
201
+ 总耗时: (data.totalTime / 1000).toFixed(2) + 's'
111
202
  })
112
203
  } else {
113
- console.log('❌ Liveness verification failed')
204
+ console.log('❌ 活体验证失败')
114
205
  }
115
206
  })
116
207
 
117
208
  engine.on('detector-error', (error) => {
118
- console.error(`Error [${error.code}]: ${error.message}`)
209
+ console.error(`❌ 错误 [${error.code}]: ${error.message}`)
119
210
  })
120
211
 
121
- engine.on('detector-debug', (debug) => {
122
- console.log(`[${debug.stage}] ${debug.message}`)
123
- })
124
-
125
- // Initialize and start detection
126
- async function runDetection() {
212
+ // 启动检测
213
+ async function startLivenessDetection() {
127
214
  try {
128
- // Initialize libraries (models, TensorFlow WASM, etc.)
215
+ // 初始化库
129
216
  await engine.initialize()
130
217
 
131
- // Get video element
132
- const videoElement = document.getElementById('video') as HTMLVideoElement
218
+ // 获取视频元素并开始检测
219
+ const videoEl = document.getElementById('video') as HTMLVideoElement
220
+ await engine.startDetection(videoEl)
133
221
 
134
- // Start detection on the video stream
135
- await engine.startDetection(videoElement)
136
-
137
- // Detection runs until completion or error
138
- // Stop manually if needed:
139
- // engine.stopDetection(true) // true to display best image
222
+ // 检测自动运行到完成或手动停止
223
+ // engine.stopDetection(true) // 停止并显示最佳图像
140
224
  } catch (error) {
141
- console.error('Failed to run detection:', error)
225
+ console.error('检测启动失败:', error)
142
226
  }
143
227
  }
144
228
 
145
- // Call when ready
146
- runDetection()
147
- ```
229
+ // 就绪时启动
230
+ startLivenessDetection()
231
+ ```
232
+
233
+ ---
234
+
235
+ ## ⚙️ 详细配置参考
236
+
237
+ ### 资源路径配置
238
+
239
+ | 选项 | 类型 | 说明 | 默认值 |
240
+ |-----|------|------|--------|
241
+ | `human_model_path` | `string` | Human.js 模型文件目录 | `undefined` |
242
+ | `tensorflow_wasm_path` | `string` | TensorFlow WASM 文件目录 | `undefined` |
243
+ | `tensorflow_backend` | `'auto' \| 'webgl' \| 'wasm'` | TensorFlow 后端引擎 | `'auto'` |
148
244
 
149
- ## Configuration
245
+ ### 视频检测设置
150
246
 
151
- ### FaceDetectionEngineConfig
247
+ | 选项 | 类型 | 说明 | 默认值 |
248
+ |-----|------|------|--------|
249
+ | `detect_video_ideal_width` | `number` | 视频宽度(像素) | `1920` |
250
+ | `detect_video_ideal_height` | `number` | 视频高度(像素) | `1080` |
251
+ | `detect_video_mirror` | `boolean` | 水平翻转视频 | `true` |
252
+ | `detect_video_load_timeout` | `number` | 加载超时(ms) | `5000` |
253
+ | `detect_frame_delay` | `number` | 帧间延迟(ms) | `100` |
254
+ | `detect_error_retry_delay` | `number` | 错误重试延迟(ms) | `200` |
152
255
 
153
- #### Resource Paths
256
+ ### 人脸采集质量要求
154
257
 
155
- | Property | Type | Description | Default |
156
- |----------|------|-------------|---------|
157
- | `human_model_path` | `string` | Path to Human.js model files | `undefined` |
158
- | `tensorflow_wasm_path` | `string` | Path to TensorFlow WASM files | `undefined` |
159
- | `tensorflow_backend` | `'auto' \| 'webgl' \| 'wasm'` | TensorFlow backend selection | `'auto'` |
258
+ | 选项 | 类型 | 说明 | 默认值 |
259
+ |-----|------|------|--------|
260
+ | `collect_min_collect_count` | `number` | 最少采集数量 | `3` |
261
+ | `collect_min_face_ratio` | `number` | 最小人脸占比 (0-1) | `0.5` |
262
+ | `collect_max_face_ratio` | `number` | 最大人脸占比 (0-1) | `0.9` |
263
+ | `collect_min_face_frontal` | `number` | 最小正对度 (0-1) | `0.9` |
264
+ | `collect_min_image_quality` | `number` | 最小图像质量 (0-1) | `0.5` |
160
265
 
161
- #### Video Detection Settings
266
+ ### 人脸正对度参数
162
267
 
163
- | Property | Type | Description | Default |
164
- |----------|------|-------------|---------|
165
- | `video_width` | `number` | Video stream width in pixels | `640` |
166
- | `video_height` | `number` | Video stream height in pixels | `640` |
167
- | `video_mirror` | `boolean` | Mirror video horizontally | `true` |
168
- | `video_load_timeout` | `number` | Video stream loading timeout in ms | `5000` |
169
- | `detection_frame_delay` | `number` | Delay between detection frames in ms | `100` |
170
- | `error_retry_delay` | `number` | Error retry delay in ms | `200` |
268
+ | 选项 | 类型 | 说明 | 默认值 |
269
+ |-----|------|------|--------|
270
+ | `yaw_threshold` | `number` | 偏航角阈值(度) | `3` |
271
+ | `pitch_threshold` | `number` | 俯仰角阈值(度) | `4` |
272
+ | `roll_threshold` | `number` | 翻滚角阈值(度) | `2` |
171
273
 
172
- #### Detection Quality Settings
274
+ ### 图像质量参数
173
275
 
174
- | Property | Type | Description | Default |
175
- |----------|------|-------------|---------|
176
- | `silent_detect_count` | `number` | Number of silent detections to collect | `3` |
177
- | `min_face_ratio` | `number` | Minimum face size ratio (0-1) | `0.5` |
178
- | `max_face_ratio` | `number` | Maximum face size ratio (0-1) | `0.9` |
179
- | `min_face_frontal` | `number` | Minimum face frontality score (0-1) | `0.9` |
180
- | `min_image_quality` | `number` | Minimum image quality score (0-1) | `0.5` |
181
- | `min_live_score` | `number` | Minimum liveness score (0-1) | `0.5` |
182
- | `min_real_score` | `number` | Minimum anti-spoofing score (0-1) | `0.85` |
183
- | `suspected_frauds_count` | `number` | Number of frauds to detect before fail | `3` |
276
+ | 选项 | 类型 | 说明 | 默认值 |
277
+ |-----|------|------|--------|
278
+ | `require_full_face_in_bounds` | `boolean` | 人脸完全在边界内 | `false` |
279
+ | `min_laplacian_variance` | `number` | 最小模糊检测值 | `40` |
280
+ | `min_gradient_sharpness` | `number` | 最小清晰度 | `0.15` |
281
+ | `min_blur_score` | `number` | 最小模糊分数 | `0.6` |
184
282
 
185
- #### Face Frontality Features (`face_frontal_features`)
283
+ ### 活体检测设置
186
284
 
187
- | Property | Type | Description | Default |
188
- |----------|------|-------------|---------|
189
- | `yaw_threshold` | `number` | Yaw angle threshold in degrees | `3` |
190
- | `pitch_threshold` | `number` | Pitch angle threshold in degrees | `4` |
191
- | `roll_threshold` | `number` | Roll angle threshold in degrees | `2` |
285
+ | 选项 | 类型 | 说明 | 默认值 |
286
+ |-----|------|------|--------|
287
+ | `action_liveness_action_list` | `LivenessAction[]` | 动作列表 | `[BLINK, MOUTH_OPEN, NOD]` |
288
+ | `action_liveness_action_count` | `number` | 需要完成的动作数 | `1` |
289
+ | `action_liveness_action_randomize` | `boolean` | 随机化动作顺序 | `true` |
290
+ | `action_liveness_verify_timeout` | `number` | 超时时间(ms) | `60000` |
291
+ | `action_liveness_min_mouth_open_percent` | `number` | 最小张嘴比例 (0-1) | `0.2` |
192
292
 
193
- #### Image Quality Features (`image_quality_features`)
293
+ ### 动作活体检测(防照片攻击)
194
294
 
195
- | Property | Type | Description | Default |
196
- |----------|------|-------------|---------|
197
- | `require_full_face_in_bounds` | `boolean` | Require face completely within bounds | `false` |
198
- | `use_opencv_enhancement` | `boolean` | Use OpenCV enhancement for quality detection | `true` |
199
- | `min_laplacian_variance` | `number` | Minimum Laplacian variance for blur detection | `50` |
200
- | `min_gradient_sharpness` | `number` | Minimum gradient sharpness for blur detection | `0.15` |
201
- | `min_blur_score` | `number` | Minimum blur score | `0.6` |
295
+ | 选项 | 类型 | 说明 | 默认值 |
296
+ |-----|------|------|--------|
297
+ | `motion_liveness_min_motion_score` | `number` | 最小运动分数 (0-1) | `0.15` |
298
+ | `motion_liveness_min_keypoint_variance` | `number` | 最小关键点方差 (0-1) | `0.02` |
299
+ | `motion_liveness_frame_buffer_size` | `number` | 帧缓冲区大小 | `5` |
300
+ | `motion_liveness_eye_aspect_ratio_threshold` | `number` | 眨眼阈值 | `0.15` |
301
+ | `motion_liveness_motion_consistency_threshold` | `number` | 一致性阈值 (0-1) | `0.3` |
302
+ | `motion_liveness_min_optical_flow_threshold` | `number` | 最小光流幅度 (0-1) | `0.02` |
303
+ | `motion_liveness_strict_photo_detection` | `boolean` | 严格照片检测模式 | `false` |
202
304
 
203
- #### Liveness Detection Settings
305
+ ### 屏幕采集检测
204
306
 
205
- | Property | Type | Description | Default |
206
- |----------|------|-------------|---------|
207
- | `liveness_action_list` | `LivenessAction[]` | List of liveness actions to detect | `[BLINK, MOUTH_OPEN, NOD]` |
208
- | `liveness_action_count` | `number` | Number of liveness actions to perform | `1` |
209
- | `liveness_action_randomize` | `boolean` | Randomize liveness actions order | `true` |
210
- | `liveness_verify_timeout` | `number` | Timeout for liveness verification in ms | `60000` |
211
- | `min_mouth_open_percent` | `number` | Minimum mouth open percentage (0-1) | `0.2` |
307
+ | 选项 | 类型 | 说明 | 默认值 |
308
+ |-----|------|------|--------|
309
+ | `screen_capture_confidence_threshold` | `number` | 置信度阈值 (0-1) | `0.7` |
310
+ | `screen_capture_detection_strategy` | `string` | 检测策略 | `'adaptive'` |
311
+ | `screen_moire_pattern_threshold` | `number` | 莫尔纹阈值 (0-1) | `0.65` |
312
+ | `screen_moire_pattern_enable_dct` | `boolean` | 启用 DCT 分析 | `true` |
313
+ | `screen_moire_pattern_enable_edge_detection` | `boolean` | 启用边缘检测 | `true` |
212
314
 
315
+ ### 屏幕色彩特征
213
316
 
214
- ## API Reference
317
+ | 选项 | 类型 | 说明 | 默认值 |
318
+ |-----|------|------|--------|
319
+ | `screen_color_saturation_threshold` | `number` | 饱和度阈值 (%) | `40` |
320
+ | `screen_color_rgb_correlation_threshold` | `number` | RGB相关性阈值 (0-1) | `0.75` |
321
+ | `screen_color_pixel_entropy_threshold` | `number` | 熵值阈值 (0-8) | `6.5` |
322
+ | `screen_color_gradient_smoothness_threshold` | `number` | 平滑性阈值 (0-1) | `0.7` |
323
+ | `screen_color_confidence_threshold` | `number` | 置信度阈值 (0-1) | `0.65` |
215
324
 
216
- ### Methods
325
+ ### 屏幕 RGB 发光检测
326
+
327
+ | 选项 | 类型 | 说明 | 默认值 |
328
+ |-----|------|------|--------|
329
+ | `screen_rgb_low_freq_start_percent` | `number` | 低频段开始 (0-1) | `0.15` |
330
+ | `screen_rgb_low_freq_end_percent` | `number` | 低频段结束 (0-1) | `0.35` |
331
+ | `screen_rgb_energy_score_weight` | `number` | 能量权重 | `0.40` |
332
+ | `screen_rgb_asymmetry_score_weight` | `number` | 不同步权重 | `0.40` |
333
+ | `screen_rgb_difference_factor_weight` | `number` | 差异权重 | `0.20` |
334
+ | `screen_rgb_confidence_threshold` | `number` | 置信度阈值 (0-1) | `0.65` |
335
+
336
+ ---
337
+
338
+ ## 🛠️ API 方法参考
339
+
340
+ ### 核心方法
217
341
 
218
342
  #### `initialize(): Promise<void>`
219
- Load and initialize detection libraries. Must be called before using detection.
343
+ 加载并初始化检测库。**必须在使用其他功能前调用。**
220
344
 
221
345
  ```typescript
222
346
  await engine.initialize()
223
347
  ```
224
348
 
225
349
  #### `startDetection(videoElement): Promise<void>`
226
- Start face detection on a video element.
350
+ 在视频元素上开始人脸检测。
227
351
 
228
352
  ```typescript
229
- const videoElement = document.getElementById('video') as HTMLVideoElement
230
- await engine.startDetection(videoElement)
353
+ const videoEl = document.getElementById('video') as HTMLVideoElement
354
+ await engine.startDetection(videoEl)
231
355
  ```
232
356
 
233
357
  #### `stopDetection(success?: boolean): void`
234
- Stop the detection process.
358
+ 停止检测过程。
235
359
 
236
360
  ```typescript
237
- engine.stopDetection(true) // true to display best image
361
+ engine.stopDetection(true) // true: 显示最佳检测图像
238
362
  ```
239
363
 
240
364
  #### `updateConfig(config): void`
241
- Update configuration during runtime.
365
+ 运行时动态更新配置。
242
366
 
243
367
  ```typescript
244
368
  engine.updateConfig({
245
- min_face_ratio: 0.6,
246
- liveness_action_count: 2
369
+ collect_min_face_ratio: 0.6,
370
+ action_liveness_action_count: 0
247
371
  })
248
372
  ```
249
373
 
250
- #### `getConfig(): FaceDetectionEngineConfig`
251
- Get current configuration.
374
+ #### `getOptions(): FaceDetectionEngineOptions`
375
+ 获取当前配置对象。
252
376
 
253
377
  ```typescript
254
- const config = engine.getConfig()
378
+ const config = engine.getOptions()
255
379
  ```
256
380
 
257
- #### `getStatus(): Object`
258
- Get engine status.
381
+ #### `getEngineState(): EngineState`
382
+ 获取引擎当前状态。
259
383
 
260
384
  ```typescript
261
- const { isReady, isDetecting, isInitializing } = engine.getStatus()
262
- ```
263
-
264
- ### Events
385
+ const state = engine.getEngineState()
386
+ ```
387
+
388
+ ---
389
+
390
+ ## 📡 事件系统
391
+
392
+ 引擎采用 **TypeScript 事件发射器模式**,所有事件都是类型安全的。
393
+
394
+ ### 事件列表
395
+
396
+ <table>
397
+ <tr>
398
+ <td><strong>detector-loaded</strong></td>
399
+ <td>引擎初始化完成</td>
400
+ </tr>
401
+ <tr>
402
+ <td><strong>detector-info</strong></td>
403
+ <td>每帧实时检测数据</td>
404
+ </tr>
405
+ <tr>
406
+ <td><strong>detector-action</strong></td>
407
+ <td>动作活体提示与状态</td>
408
+ </tr>
409
+ <tr>
410
+ <td><strong>detector-finish</strong></td>
411
+ <td>检测完成(成功/失败)</td>
412
+ </tr>
413
+ <tr>
414
+ <td><strong>detector-error</strong></td>
415
+ <td>错误发生时触发</td>
416
+ </tr>
417
+ <tr>
418
+ <td><strong>detector-debug</strong></td>
419
+ <td>调试信息(开发用)</td>
420
+ </tr>
421
+ </table>
422
+
423
+ ---
424
+
425
+ ### 📋 detector-loaded
426
+
427
+ **引擎初始化完成时触发**
265
428
 
266
- The engine uses a TypeScript event emitter pattern. All events are type-safe:
267
-
268
- #### `detector-loaded`
269
- Fired when the engine finishes initialization.
270
-
271
- **Data:**
272
429
  ```typescript
273
430
  interface DetectorLoadedEventData {
274
- success: boolean // Whether initialization succeeded
275
- error?: string // Error message if any
276
- opencv_version?: string // OpenCV.js version
277
- human_version?: string // Human.js version
431
+ success: boolean // 初始化是否成功
432
+ error?: string // 错误信息(失败时)
433
+ opencv_version?: string // OpenCV.js 版本号
434
+ human_version?: string // Human.js 版本号
278
435
  }
279
436
  ```
280
437
 
281
- **Example:**
438
+ **示例:**
282
439
  ```typescript
283
440
  engine.on('detector-loaded', (data) => {
284
441
  if (data.success) {
285
- console.log('✅ Engine ready')
286
- console.log(`OpenCV: ${data.opencv_version}`)
287
- console.log(`Human.js: ${data.human_version}`)
442
+ console.log('✅ 引擎就绪')
443
+ console.log(`OpenCV ${data.opencv_version} | Human.js ${data.human_version}`)
288
444
  } else {
289
- console.error('Engine failed:', data.error)
445
+ console.error(' 初始化失败:', data.error)
290
446
  }
291
447
  })
292
448
  ```
293
449
 
294
- #### `detector-info`
295
- Real-time detection information for each frame.
450
+ ---
451
+
452
+ ### 📊 detector-info
453
+
454
+ **每帧返回实时检测数据(高频事件)**
296
455
 
297
- **Data:**
298
456
  ```typescript
299
457
  interface DetectorInfoEventData {
300
- passed: boolean // Whether silent liveness check passed
301
- code: DetectionCode // Detection status code
302
- size: number // Face size ratio (0-1)
303
- frontal: number // Face frontality score (0-1)
304
- quality: number // Image quality score (0-1)
305
- real: number // Anti-spoofing score (0-1)
306
- live: number // Liveness score (0-1)
458
+ passed: boolean // 是否通过静默检测
459
+ code: DetectionCode // 检测状态码
460
+ message: string // 状态消息
461
+ faceCount: number // 检测到的人脸数
462
+ faceRatio: number // 人脸占比 (0-1)
463
+ faceFrontal: number // 人脸正对度 (0-1)
464
+ imageQuality: number // 图像质量分数 (0-1)
465
+ motionScore: number // 运动分数 (0-1)
466
+ keypointVariance: number // 关键点方差 (0-1)
467
+ motionType: string // 检测到的运动类型
468
+ screenConfidence: number // 屏幕采集置信度 (0-1)
307
469
  }
308
470
  ```
309
471
 
310
- **Detection Codes:**
472
+ **检测状态码:**
311
473
  ```typescript
312
474
  enum DetectionCode {
313
- VIDEO_NO_FACE = 'VIDEO_NO_FACE', // No face detected
314
- MULTIPLE_FACE = 'MULTIPLE_FACE', // Multiple faces detected
315
- FACE_TOO_SMALL = 'FACE_TOO_SMALL', // Face too small
316
- FACE_TOO_LARGE = 'FACE_TOO_LARGE', // Face too large
317
- FACE_NOT_FRONTAL = 'FACE_NOT_FRONTAL', // Face not frontal enough
318
- FACE_NOT_REAL = 'FACE_NOT_REAL', // Suspected spoofing
319
- FACE_NOT_LIVE = 'FACE_NOT_LIVE', // Low liveness score
320
- FACE_LOW_QUALITY = 'FACE_LOW_QUALITY', // Image quality too low
321
- FACE_CHECK_PASS = 'FACE_CHECK_PASS' // All checks passed
475
+ VIDEO_NO_FACE = 'VIDEO_NO_FACE', // 未检测到人脸
476
+ MULTIPLE_FACE = 'MULTIPLE_FACE', // 检测到多张人脸
477
+ FACE_TOO_SMALL = 'FACE_TOO_SMALL', // 人脸太小
478
+ FACE_TOO_LARGE = 'FACE_TOO_LARGE', // 人脸太大
479
+ FACE_NOT_FRONTAL = 'FACE_NOT_FRONTAL', // 人脸不够正面
480
+ FACE_NOT_REAL = 'FACE_NOT_REAL', // 疑似欺骗
481
+ FACE_NOT_LIVE = 'FACE_NOT_LIVE', // 活体分数过低
482
+ FACE_LOW_QUALITY = 'FACE_LOW_QUALITY', // 图像质量过低
483
+ FACE_CHECK_PASS = 'FACE_CHECK_PASS' // 所有检查通过
322
484
  }
323
485
  ```
324
486
 
325
- **Example:**
487
+ **示例:**
326
488
  ```typescript
327
489
  engine.on('detector-info', (data) => {
328
490
  console.log({
329
- passed: data.passed,
330
- status: data.code,
331
- quality: (data.quality * 100).toFixed(1) + '%',
332
- frontal: (data.frontal * 100).toFixed(1) + '%',
333
- liveness: (data.live * 100).toFixed(1) + '%',
334
- realness: (data.real * 100).toFixed(1) + '%'
491
+ 检测状态: data.code,
492
+ 静默通过: data.passed ? '✅' : '❌',
493
+ 图像质量: `${(data.imageQuality * 100).toFixed(1)}%`,
494
+ 人脸正对度: `${(data.faceFrontal * 100).toFixed(1)}%`,
495
+ 运动分数: `${(data.motionScore * 100).toFixed(1)}%`,
496
+ 屏幕采集: `${(data.screenConfidence * 100).toFixed(1)}%`
335
497
  })
336
498
  })
337
499
  ```
338
500
 
339
- #### `detector-action`
340
- Action liveness prompts and status updates.
501
+ ---
502
+
503
+ ### 👤 detector-action
504
+
505
+ **动作活体提示与识别状态**
341
506
 
342
- **Data:**
343
507
  ```typescript
344
508
  interface DetectorActionEventData {
345
- action: LivenessAction // The action to perform
346
- status: LivenessActionStatus // Action status
509
+ action: LivenessAction // 要执行的动作
510
+ status: LivenessActionStatus // 动作状态
347
511
  }
348
- ```
349
512
 
350
- **Action Types:**
351
- ```typescript
352
513
  enum LivenessAction {
353
- BLINK = 'blink',
354
- MOUTH_OPEN = 'mouth_open',
355
- NOD = 'nod'
514
+ BLINK = 'blink', // 眨眼
515
+ MOUTH_OPEN = 'mouth_open', // 张嘴
516
+ NOD = 'nod' // 点头
356
517
  }
357
- ```
358
518
 
359
- **Action Status:**
360
- ```typescript
361
519
  enum LivenessActionStatus {
362
- STARTED = 'started', // Action prompt started
363
- COMPLETED = 'completed', // Action recognized
364
- TIMEOUT = 'timeout' // Action recognition timeout
520
+ STARTED = 'started', // 提示已开始
521
+ COMPLETED = 'completed', // 成功识别
522
+ TIMEOUT = 'timeout' // 识别超时
365
523
  }
366
524
  ```
367
525
 
368
- **Example:**
526
+ **示例:**
369
527
  ```typescript
370
528
  engine.on('detector-action', (data) => {
529
+ const actionLabels = {
530
+ 'blink': '眨眼',
531
+ 'mouth_open': '张嘴',
532
+ 'nod': '点头'
533
+ }
534
+
371
535
  switch (data.status) {
372
536
  case 'started':
373
- console.log(`👤 Please perform: ${data.action}`)
374
- // Update UI to show action prompt
537
+ console.log(`👤 请执行: ${actionLabels[data.action]}`)
538
+ // 显示 UI 提示
375
539
  break
376
540
  case 'completed':
377
- console.log(`✅ Action recognized: ${data.action}`)
378
- // Update progress indicator
541
+ console.log(`✅ 已识别: ${actionLabels[data.action]}`)
542
+ // 更新进度条
379
543
  break
380
544
  case 'timeout':
381
- console.log(`⏱️ Action timeout: ${data.action}`)
545
+ console.log(`⏱️ 超时: ${actionLabels[data.action]}`)
546
+ // 显示重试提示
382
547
  break
383
548
  }
384
549
  })
385
550
  ```
386
551
 
387
- #### `detector-finish`
388
- Fired when liveness detection completes (successfully or failed).
552
+ ---
553
+
554
+ ### ✅ detector-finish
555
+
556
+ **检测流程完成(成功或失败)**
389
557
 
390
- **Data:**
391
558
  ```typescript
392
559
  interface DetectorFinishEventData {
393
- success: boolean // Whether liveness verification passed
394
- silentPassedCount: number // Number of silent detections passed
395
- actionPassedCount: number // Number of actions completed
396
- totalTime: number // Total detection time in ms
397
- bestQualityScore: number // Best image quality score (0-1)
398
- bestFrameImage: string | null // Base64 encoded best frame image
399
- bestFaceImage: string | null // Base64 encoded best face image
560
+ success: boolean // 是否通过验证
561
+ silentPassedCount: number // 静默检测通过数
562
+ actionPassedCount: number // 动作完成数
563
+ totalTime: number // 总耗时(毫秒)
564
+ bestQualityScore: number // 最佳图像质量 (0-1)
565
+ bestFrameImage: string | null // Base64 帧图像
566
+ bestFaceImage: string | null // Base64 人脸图像
400
567
  }
401
568
  ```
402
569
 
403
- **Example:**
570
+ **示例:**
404
571
  ```typescript
405
572
  engine.on('detector-finish', (data) => {
406
573
  if (data.success) {
407
- console.log(' Liveness verification passed!')
408
- console.log({
409
- silentDetections: data.silentPassedCount,
410
- actionsCompleted: data.actionPassedCount,
411
- quality: (data.bestQualityScore * 100).toFixed(1) + '%',
412
- time: (data.totalTime / 1000).toFixed(2) + 's'
574
+ console.log('🎉 活体验证成功!', {
575
+ 静默通过: `${data.silentPassedCount} 次`,
576
+ 动作完成: `${data.actionPassedCount} 次`,
577
+ 最佳质量: `${(data.bestQualityScore * 100).toFixed(1)}%`,
578
+ 总耗时: `${(data.totalTime / 1000).toFixed(2)}s`
413
579
  })
414
580
 
415
- // Send results to server
581
+ // 上传结果到服务器
416
582
  if (data.bestFrameImage) {
417
- uploadVerificationResult({
583
+ uploadToServer({
418
584
  image: data.bestFrameImage,
419
585
  quality: data.bestQualityScore,
420
586
  timestamp: new Date()
421
587
  })
422
588
  }
423
589
  } else {
424
- console.log('❌ Liveness verification failed')
425
- // Prompt user to try again
590
+ console.log('❌ 验证失败,请重试')
426
591
  }
427
592
  })
428
593
  ```
429
594
 
430
- #### `detector-error`
431
- Fired when an error occurs during detection.
595
+ ---
596
+
597
+ ### ⚠️ detector-error
598
+
599
+ **检测过程中发生错误**
432
600
 
433
- **Data:**
434
601
  ```typescript
435
602
  interface DetectorErrorEventData {
436
- code: ErrorCode // Error code
437
- message: string // Error message
603
+ code: ErrorCode // 错误代码
604
+ message: string // 错误信息
438
605
  }
439
- ```
440
606
 
441
- **Error Codes:**
442
- ```typescript
443
607
  enum ErrorCode {
444
608
  DETECTOR_NOT_INITIALIZED = 'DETECTOR_NOT_INITIALIZED',
445
609
  CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED',
@@ -448,124 +612,118 @@ enum ErrorCode {
448
612
  }
449
613
  ```
450
614
 
451
- **Example:**
615
+ **示例:**
452
616
  ```typescript
453
617
  engine.on('detector-error', (error) => {
454
- console.error(`❌ Error [${error.code}]: ${error.message}`)
455
-
456
- switch (error.code) {
457
- case 'CAMERA_ACCESS_DENIED':
458
- showErrorMessage('Please grant camera permissions')
459
- break
460
- case 'STREAM_ACQUISITION_FAILED':
461
- showErrorMessage('Failed to access camera')
462
- break
463
- case 'SUSPECTED_FRAUDS_DETECTED':
464
- showErrorMessage('Spoofing detected - please try again')
465
- break
466
- default:
467
- showErrorMessage('Detection failed: ' + error.message)
618
+ const errorMessages: Record<string, string> = {
619
+ 'DETECTOR_NOT_INITIALIZED': '引擎未初始化',
620
+ 'CAMERA_ACCESS_DENIED': '摄像头权限被拒绝',
621
+ 'STREAM_ACQUISITION_FAILED': '无法获取摄像头数据流',
622
+ 'SUSPECTED_FRAUDS_DETECTED': '检测到欺骗行为'
468
623
  }
624
+
625
+ console.error(`❌ 错误 [${error.code}]: ${errorMessages[error.code] || error.message}`)
626
+ showUserErrorPrompt(errorMessages[error.code])
469
627
  })
470
628
  ```
471
629
 
472
- #### `detector-debug`
473
- Debug information for development and troubleshooting.
630
+ ---
631
+
632
+ ### 🐛 detector-debug
633
+
634
+ **开发和故障排除的调试信息**
474
635
 
475
- **Data:**
476
636
  ```typescript
477
637
  interface DetectorDebugEventData {
478
- level: 'info' | 'warn' | 'error' // Debug level
479
- stage: string // Current processing stage
480
- message: string // Debug message
481
- details?: Record<string, any> // Additional details
482
- timestamp: number // Unix timestamp
638
+ level: 'info' | 'warn' | 'error' // 日志级别
639
+ stage: string // 处理阶段
640
+ message: string // 调试信息
641
+ details?: Record<string, any> // 额外详情
642
+ timestamp: number // Unix 时间戳
483
643
  }
484
644
  ```
485
645
 
486
- **Example:**
646
+ **示例:**
487
647
  ```typescript
488
648
  engine.on('detector-debug', (debug) => {
489
649
  const time = new Date(debug.timestamp).toLocaleTimeString()
490
- console.log(`[${time}] [${debug.stage}] ${debug.message}`)
650
+ const prefix = `[${time}] [${debug.stage}]`
491
651
 
492
- if (debug.details) {
493
- console.log('Details:', debug.details)
494
- }
495
-
496
- // Log errors for troubleshooting
497
652
  if (debug.level === 'error') {
498
- logErrorToServer({
499
- stage: debug.stage,
500
- message: debug.message,
501
- details: debug.details
502
- })
653
+ console.error(`${prefix} ❌ ${debug.message}`, debug.details)
654
+ } else {
655
+ console.log(`${prefix} ℹ️ ${debug.message}`)
503
656
  }
504
657
  })
505
658
  ```
506
659
 
507
- ## Enumerations
660
+ ---
661
+
662
+ ## 📖 类型定义
508
663
 
509
664
  ### LivenessAction
510
665
  ```typescript
511
666
  enum LivenessAction {
512
- BLINK = 'blink',
513
- MOUTH_OPEN = 'mouth_open',
514
- NOD = 'nod'
667
+ BLINK = 'blink', // 眨眼
668
+ MOUTH_OPEN = 'mouth_open', // 张嘴
669
+ NOD = 'nod' // 点头
515
670
  }
516
671
  ```
517
672
 
518
673
  ### LivenessActionStatus
519
674
  ```typescript
520
675
  enum LivenessActionStatus {
521
- STARTED = 'started', // Action prompt has started
522
- COMPLETED = 'completed', // Action successfully recognized
523
- TIMEOUT = 'timeout' // Action recognition timeout
676
+ STARTED = 'started', // 动作提示已开始
677
+ COMPLETED = 'completed', // 动作成功识别
678
+ TIMEOUT = 'timeout' // 动作识别超时
524
679
  }
525
680
  ```
526
681
 
527
682
  ### DetectionCode
528
683
  ```typescript
529
684
  enum DetectionCode {
530
- VIDEO_NO_FACE = 'VIDEO_NO_FACE', // No face detected in the video
531
- MULTIPLE_FACE = 'MULTIPLE_FACE', // Multiple faces detected
532
- FACE_TOO_SMALL = 'FACE_TOO_SMALL', // Face size below minimum threshold
533
- FACE_TOO_LARGE = 'FACE_TOO_LARGE', // Face size above maximum threshold
534
- FACE_NOT_FRONTAL = 'FACE_NOT_FRONTAL', // Face angle not frontal enough
535
- FACE_NOT_REAL = 'FACE_NOT_REAL', // Suspected spoofing detected
536
- FACE_NOT_LIVE = 'FACE_NOT_LIVE', // Liveness score below threshold
537
- FACE_LOW_QUALITY = 'FACE_LOW_QUALITY', // Image quality below minimum
538
- FACE_CHECK_PASS = 'FACE_CHECK_PASS' // All detection checks passed
685
+ VIDEO_NO_FACE = 'VIDEO_NO_FACE', // 视频中未检测到人脸
686
+ MULTIPLE_FACE = 'MULTIPLE_FACE', // 检测到多张人脸
687
+ FACE_TOO_SMALL = 'FACE_TOO_SMALL', // 人脸尺寸小于最小阈值
688
+ FACE_TOO_LARGE = 'FACE_TOO_LARGE', // 人脸尺寸大于最大阈值
689
+ FACE_NOT_FRONTAL = 'FACE_NOT_FRONTAL', // 人脸角度不够正面
690
+ FACE_NOT_REAL = 'FACE_NOT_REAL', // 检测到疑似欺骗
691
+ FACE_NOT_LIVE = 'FACE_NOT_LIVE', // 活体分数低于阈值
692
+ FACE_LOW_QUALITY = 'FACE_LOW_QUALITY', // 图像质量低于最小值
693
+ FACE_CHECK_PASS = 'FACE_CHECK_PASS' // 所有检测检查通过
539
694
  }
540
695
  ```
541
696
 
542
697
  ### ErrorCode
543
698
  ```typescript
544
699
  enum ErrorCode {
545
- DETECTOR_NOT_INITIALIZED = 'DETECTOR_NOT_INITIALIZED', // Engine not initialized
546
- CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED', // Camera permission denied
547
- STREAM_ACQUISITION_FAILED = 'STREAM_ACQUISITION_FAILED', // Failed to get video stream
548
- SUSPECTED_FRAUDS_DETECTED = 'SUSPECTED_FRAUDS_DETECTED' // Spoofing/fraud suspected
700
+ DETECTOR_NOT_INITIALIZED = 'DETECTOR_NOT_INITIALIZED', // 引擎未初始化
701
+ CAMERA_ACCESS_DENIED = 'CAMERA_ACCESS_DENIED', // 摄像头权限被拒
702
+ STREAM_ACQUISITION_FAILED = 'STREAM_ACQUISITION_FAILED', // 获取视频流失败
703
+ SUSPECTED_FRAUDS_DETECTED = 'SUSPECTED_FRAUDS_DETECTED' // 检测到欺骗/欺诈
549
704
  }
550
705
  ```
551
706
 
552
- ## Advanced Usage
707
+ ---
553
708
 
554
- For comprehensive examples and advanced usage patterns, please refer to the official demo project:
709
+ ## 🎓 高级用法与示例
555
710
 
556
- **👉 [Vue Demo Project](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/)**
711
+ ### 完整的 Vue 3 演示项目
557
712
 
558
- The demo includes:
559
- - Complete Vue 3 integration with TypeScript
560
- - Real-time detection visualization
561
- - Configuration panel for experimenting with different settings
562
- - Event handling examples for all engine events
563
- - Debug panel showing detailed detection information
564
- - Responsive UI design for mobile and desktop
565
- - Error handling and user feedback patterns
566
- - Result export and image capture examples
713
+ 有关全面的示例和高级使用模式,请参考官方演示项目:
567
714
 
568
- To run the demo locally:
715
+ **[Vue 演示项目](https://github.com/sssxyd/face-liveness-detector/tree/main/demos/vue-demo/)** 包括:
716
+
717
+ - ✅ 完整的 Vue 3 + TypeScript 集成
718
+ - ✅ 实时检测结果可视化
719
+ - ✅ 动态配置面板
720
+ - ✅ 所有引擎事件的完整处理
721
+ - ✅ 实时调试面板
722
+ - ✅ 响应式移动端 + 桌面端 UI
723
+ - ✅ 错误处理和用户反馈
724
+ - ✅ 结果导出和图像捕获
725
+
726
+ **快速启动演示:**
569
727
 
570
728
  ```bash
571
729
  cd demos/vue-demo
@@ -573,123 +731,116 @@ npm install
573
731
  npm run dev
574
732
  ```
575
733
 
576
- Then open your browser to the displayed local URL to see the detection engine in action.
734
+ 然后在浏览器中打开显示的本地 URL
735
+
736
+ ---
577
737
 
578
- ## Downloading and Hosting Model Files
738
+ ## 📥 本地部署模型文件
579
739
 
580
- To avoid CDN dependencies and improve performance, you can download model files locally:
740
+ ### 为什么需要本地部署?
581
741
 
582
- ### Available Download Scripts
742
+ - 🚀 **提升性能** - 避免 CDN 延迟
743
+ - 🔒 **隐私保护** - 完全离线运行
744
+ - 🌐 **网络独立** - 不依赖外部连接
583
745
 
584
- Two scripts are provided in the root directory:
746
+ ### 可用脚本
585
747
 
586
- #### 1. Copy Human.js Models
748
+ 项目根目录提供两个下载脚本:
749
+
750
+ #### 1️⃣ 复制 Human.js 模型
587
751
 
588
752
  ```bash
589
- node copy-human-models.js
753
+ node copy-models.js
590
754
  ```
591
755
 
592
- **What it does:**
593
- - Copies face detection models from `node_modules/@vladmandic/human/models`
594
- - Saves to `public/models/` directory
595
- - Downloads both `.json` and `.bin` model files
596
- - Shows file size and progress
756
+ **功能:**
757
+ - `node_modules/@vladmandic/human/models` 复制模型
758
+ - 保存到 `public/models/` 目录
759
+ - 包含 `.json` `.bin` 模型文件
760
+ - 自动显示文件大小和进度
597
761
 
598
- #### 2. Download TensorFlow.js WASM Files
762
+ #### 2️⃣ 下载 TensorFlow WASM 文件
599
763
 
600
764
  ```bash
601
- node download-tensorflow-wasm.js
765
+ node download-wasm.js
602
766
  ```
603
767
 
604
- **What it does:**
605
- - Downloads TensorFlow.js WASM backend files
606
- - Saves to `public/wasm/` directory
607
- - Downloads 4 critical files:
768
+ **功能:**
769
+ - 自动下载 TensorFlow.js WASM 后端
770
+ - 保存到 `public/wasm/` 目录
771
+ - 下载 4 个关键文件:
608
772
  - `tf-backend-wasm.min.js`
609
773
  - `tfjs-backend-wasm.wasm`
610
774
  - `tfjs-backend-wasm-simd.wasm`
611
775
  - `tfjs-backend-wasm-threaded-simd.wasm`
612
- - **Supports multiple CDN sources** with automatic fallback:
613
- 1. unpkg.com (primary)
614
- 2. cdn.jsdelivr.net (backup)
615
- 3. esm.sh (fallback)
616
- 4. cdn.esm.sh (last resort)
776
+ - **智能多 CDN 源** 自动回退:
777
+ 1. unpkg.com(推荐)
778
+ 2. cdn.jsdelivr.net
779
+ 3. esm.sh
780
+ 4. cdn.esm.sh
617
781
 
618
- ### Configuration to Use Local Files
782
+ ### 配置项目使用本地文件
619
783
 
620
- Once downloaded, configure the engine to use these local files:
784
+ 下载完成后,在引擎初始化时指定本地路径:
621
785
 
622
786
  ```typescript
623
787
  const engine = new FaceDetectionEngine({
624
- // Use local files instead of CDN
788
+ // 使用本地文件而不是 CDN
625
789
  human_model_path: '/models',
626
790
  tensorflow_wasm_path: '/wasm',
627
791
 
628
- // ... rest of configuration
792
+ // 其他配置...
629
793
  })
630
794
  ```
631
795
 
632
- ## Browser Requirements
796
+ ### 自动化设置(推荐)
797
+
798
+ 在 `package.json` 中配置 `postinstall` 钩子实现自动下载:
799
+
800
+ ```json
801
+ {
802
+ "scripts": {
803
+ "postinstall": "node scripts/copy-models.js && node scripts/download-wasm.js"
804
+ }
805
+ }
806
+ ```
807
+
808
+ ---
809
+
810
+ ## 🌐 浏览器兼容性
633
811
 
634
- - Modern browsers with WebRTC support (Chrome, Firefox, Edge, Safari 11+)
635
- - HTTPS required for getUserMedia
636
- - WebGL or WASM backend support
812
+ | 浏览器 | 版本 | 支持 | 备注 |
813
+ |--------|------|------|------|
814
+ | Chrome | 60+ | ✅ | 完全支持 |
815
+ | Firefox | 55+ | ✅ | 完全支持 |
816
+ | Safari | 11+ | ✅ | 完全支持 |
817
+ | Edge | 79+ | ✅ | 完全支持 |
637
818
 
638
- ## Performance Tips
819
+ **系统要求:**
639
820
 
640
- 1. **Adjust detection frame delay** - Higher delay = lower CPU usage but slower detection
641
- ```typescript
642
- engine.updateConfig({ detection_frame_delay: 200 })
643
- ```
821
+ - 📱 支持 **WebRTC** 的现代浏览器
822
+ - 🔒 **HTTPS 环境**(开发可用 localhost)
823
+ - ⚙️ **WebGL** 或 **WASM** 后端支持
824
+ - 📹 **用户授权** - 需要摄像头权限
644
825
 
645
- 2. **Reduce canvas size** - Smaller canvases process faster
646
- ```typescript
647
- engine.updateConfig({
648
- video_width: 480,
649
- video_height: 480
650
- })
651
- ```
826
+ ---
652
827
 
653
- 3. **Optimize light conditions** - Better lighting = better detection
654
- - Avoid backlighting
655
- - Ensure face is well-lit
828
+ ## 📄 许可证
656
829
 
657
- 4. **Monitor debug output** - Use debug events to identify bottlenecks
658
- ```typescript
659
- engine.on('detector-debug', (debug) => {
660
- if (debug.stage === 'detection') {
661
- console.time(debug.message)
662
- }
663
- })
664
- ```
830
+ [MIT License](./LICENSE) - 自由使用和修改
665
831
 
666
- ## Troubleshooting
832
+ ## 🤝 贡献
667
833
 
668
- ### "Camera access denied"
669
- - Ensure HTTPS is used (or localhost for development)
670
- - Check browser permissions
671
- - User must grant camera access
834
+ 欢迎提交 Issue Pull Request!
672
835
 
673
- ### "Video loading timeout"
674
- - Check internet connection
675
- - Verify model files are accessible
676
- - Increase `video_load_timeout`
836
+ ---
677
837
 
678
- ### Poor detection accuracy
679
- - Ensure good lighting
680
- - Keep face centered in frame
681
- - Face should be 50-90% of frame
682
- - Face should be frontal (not tilted)
838
+ <div align="center">
683
839
 
684
- ### High CPU usage
685
- - Increase `detection_frame_delay`
686
- - Reduce `video_width` and `video_height`
687
- - Disable `show_action_prompt` if not needed
840
+ **[⬆ 返回顶部](#人脸活体检测引擎)**
688
841
 
689
- ## License
842
+ Made with ❤️ by [sssxyd](https://github.com/sssxyd)
690
843
 
691
- MIT
844
+ </div>
692
845
 
693
- ## Support
694
846
 
695
- For issues and questions, please visit: https://github.com/sssxyd/face-liveness-detector/issues