@sssxyd/face-liveness-detector 0.2.27 → 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +132 -136
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +132 -136
- package/dist/index.js.map +1 -1
- package/dist/types/exports.d.ts +1 -1
- package/dist/types/exports.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/library-loader.d.ts +8 -10
- package/dist/types/library-loader.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -289,7 +289,6 @@ if (cvModuleImport && cvModuleImport.default) {
|
|
|
289
289
|
}
|
|
290
290
|
let webglAvailableCache = null;
|
|
291
291
|
let opencvInitPromise = null;
|
|
292
|
-
let opencvInitialized = false; // 标记是否已初始化完成
|
|
293
292
|
function _isWebGLAvailable() {
|
|
294
293
|
if (webglAvailableCache !== null) {
|
|
295
294
|
return webglAvailableCache;
|
|
@@ -324,11 +323,6 @@ function _detectOptimalBackend() {
|
|
|
324
323
|
* @param timeout - Maximum wait time in milliseconds (default: 30000)
|
|
325
324
|
*/
|
|
326
325
|
async function preloadOpenCV(timeout = 30000) {
|
|
327
|
-
// 如果已经初始化完成,直接返回
|
|
328
|
-
if (opencvInitialized) {
|
|
329
|
-
console.log('[OpenCV] Already initialized, skipping preload');
|
|
330
|
-
return;
|
|
331
|
-
}
|
|
332
326
|
// 如果已经在初始化中,返回现有的 Promise
|
|
333
327
|
if (opencvInitPromise) {
|
|
334
328
|
console.log('[OpenCV] Already initializing, reusing existing promise');
|
|
@@ -338,15 +332,13 @@ async function preloadOpenCV(timeout = 30000) {
|
|
|
338
332
|
// 复用 loadOpenCV 的初始化逻辑
|
|
339
333
|
opencvInitPromise = _initializeOpenCV(timeout);
|
|
340
334
|
try {
|
|
341
|
-
|
|
342
|
-
console.log('[OpenCV] Preload completed successfully
|
|
343
|
-
initTime: `${initTime.toFixed(2)}ms`,
|
|
344
|
-
version: getOpenCVVersion()
|
|
345
|
-
});
|
|
335
|
+
await opencvInitPromise;
|
|
336
|
+
console.log('[OpenCV] Preload completed successfully');
|
|
346
337
|
}
|
|
347
338
|
catch (error) {
|
|
348
339
|
console.error('[OpenCV] Preload failed:', error);
|
|
349
|
-
|
|
340
|
+
// 失败后清除 Promise,允许重试
|
|
341
|
+
opencvInitPromise = null;
|
|
350
342
|
throw error;
|
|
351
343
|
}
|
|
352
344
|
}
|
|
@@ -356,16 +348,16 @@ async function preloadOpenCV(timeout = 30000) {
|
|
|
356
348
|
*/
|
|
357
349
|
async function _initializeOpenCV(timeout) {
|
|
358
350
|
const initStartTime = performance.now();
|
|
359
|
-
console.log('Waiting for OpenCV WASM initialization...');
|
|
351
|
+
console.log('[FaceDetectionEngine] Waiting for OpenCV WASM initialization...');
|
|
360
352
|
// 快速路径:检查是否已经初始化
|
|
361
353
|
if (cvModule.Mat) {
|
|
362
354
|
const initTime = performance.now() - initStartTime;
|
|
363
|
-
console.log(`OpenCV.js already initialized, took ${initTime.toFixed(2)}ms`);
|
|
364
|
-
return
|
|
355
|
+
console.log(`[FaceDetectionEngine] OpenCV.js already initialized, took ${initTime.toFixed(2)}ms`);
|
|
356
|
+
return true;
|
|
365
357
|
}
|
|
366
358
|
if (typeof globalThis !== 'undefined' && globalThis.cv && globalThis.cv.Mat) {
|
|
367
359
|
const initTime = performance.now() - initStartTime;
|
|
368
|
-
console.log(`OpenCV.js already initialized (from global), took ${initTime.toFixed(2)}ms`);
|
|
360
|
+
console.log(`[FaceDetectionEngine] OpenCV.js already initialized (from global), took ${initTime.toFixed(2)}ms`);
|
|
369
361
|
cvModule = globalThis.cv;
|
|
370
362
|
return cvModule;
|
|
371
363
|
}
|
|
@@ -373,84 +365,69 @@ async function _initializeOpenCV(timeout) {
|
|
|
373
365
|
if (typeof globalThis !== 'undefined' && !globalThis.cv) {
|
|
374
366
|
if (cvModule && Object.isExtensible(cvModule)) {
|
|
375
367
|
globalThis.cv = cvModule;
|
|
376
|
-
console.log('cvModule assigned to globalThis.cv');
|
|
368
|
+
console.log('[FaceDetectionEngine] cvModule assigned to globalThis.cv');
|
|
377
369
|
}
|
|
378
370
|
else {
|
|
379
|
-
console.log('cvModule is not extensible or globalThis already has cv');
|
|
371
|
+
console.log('[FaceDetectionEngine] cvModule is not extensible or globalThis already has cv');
|
|
380
372
|
}
|
|
381
373
|
}
|
|
382
374
|
return new Promise((resolve, reject) => {
|
|
383
|
-
// 轮询检查OpenCV初始化状态的标记
|
|
384
375
|
let pollInterval = null;
|
|
385
|
-
// 防止多次调用 resolve/reject
|
|
386
|
-
let finished = false;
|
|
387
376
|
const timeoutId = setTimeout(() => {
|
|
388
|
-
console.error('OpenCV.js initialization timeout after ' + timeout + 'ms');
|
|
389
|
-
finished = true;
|
|
377
|
+
console.error('[FaceDetectionEngine] OpenCV.js initialization timeout after ' + timeout + 'ms');
|
|
390
378
|
if (pollInterval) {
|
|
391
379
|
clearInterval(pollInterval);
|
|
392
380
|
}
|
|
393
381
|
reject(new Error('OpenCV.js initialization timeout'));
|
|
394
382
|
}, timeout);
|
|
383
|
+
let resolved = false;
|
|
395
384
|
const resolveOnce = (source) => {
|
|
396
|
-
if (
|
|
397
|
-
console.log('[resolveOnce] Already finished, ignoring call from:', source);
|
|
385
|
+
if (resolved)
|
|
398
386
|
return;
|
|
399
|
-
|
|
400
|
-
finished = true;
|
|
401
|
-
console.log('[resolveOnce] Marking as finished');
|
|
402
|
-
// 立即停止所有定时器和轮询
|
|
387
|
+
resolved = true;
|
|
403
388
|
clearTimeout(timeoutId);
|
|
404
|
-
if (pollInterval
|
|
389
|
+
if (pollInterval) {
|
|
405
390
|
clearInterval(pollInterval);
|
|
406
|
-
pollInterval = null;
|
|
407
|
-
console.log('[resolveOnce] Poll interval cleared');
|
|
408
391
|
}
|
|
409
392
|
const initTime = performance.now() - initStartTime;
|
|
410
|
-
console.log(`OpenCV.js initialized (${source}), took ${initTime.toFixed(2)}ms`);
|
|
411
|
-
|
|
412
|
-
opencvInitialized = true;
|
|
413
|
-
// 返回简单的标记,实际的 cv 对象已经在 globalThis.cv 上了
|
|
414
|
-
resolve(initTime);
|
|
393
|
+
console.log(`[FaceDetectionEngine] OpenCV.js initialized (${source}), took ${initTime.toFixed(2)}ms`);
|
|
394
|
+
resolve(true);
|
|
415
395
|
};
|
|
416
396
|
// 尝试设置回调(只有在 cvModule 可扩展时才尝试)
|
|
417
397
|
const canSetCallback = cvModule && Object.isExtensible(cvModule);
|
|
418
398
|
if (canSetCallback) {
|
|
419
399
|
try {
|
|
420
400
|
const originalOnRuntimeInitialized = cvModule.onRuntimeInitialized(cvModule).onRuntimeInitialized = () => {
|
|
421
|
-
console.log('[
|
|
401
|
+
console.log('[FaceDetectionEngine] onRuntimeInitialized callback triggered');
|
|
422
402
|
// 调用原始回调(如果存在)
|
|
423
403
|
if (originalOnRuntimeInitialized && typeof originalOnRuntimeInitialized === 'function') {
|
|
424
404
|
try {
|
|
425
405
|
originalOnRuntimeInitialized();
|
|
426
406
|
}
|
|
427
407
|
catch (e) {
|
|
428
|
-
console.warn('[
|
|
408
|
+
console.warn('[FaceDetectionEngine] Original onRuntimeInitialized callback failed:', e);
|
|
429
409
|
}
|
|
430
410
|
}
|
|
431
411
|
resolveOnce('callback');
|
|
432
412
|
};
|
|
433
|
-
console.log('[
|
|
413
|
+
console.log('[FaceDetectionEngine] onRuntimeInitialized callback set successfully');
|
|
434
414
|
}
|
|
435
415
|
catch (e) {
|
|
436
|
-
console.warn('[
|
|
416
|
+
console.warn('[FaceDetectionEngine] Failed to set onRuntimeInitialized callback, will use polling:', e);
|
|
437
417
|
}
|
|
438
418
|
}
|
|
439
419
|
else {
|
|
440
|
-
console.log('[
|
|
420
|
+
console.log('[FaceDetectionEngine] cvModule is not extensible, using polling mode');
|
|
441
421
|
}
|
|
442
422
|
// 启动轮询作为备用方案或主要方案
|
|
443
423
|
pollInterval = setInterval(() => {
|
|
444
|
-
console.log('[polling] Checking for Mat class...');
|
|
445
424
|
// 优先检查 cvModule 中是否有 Mat
|
|
446
425
|
if (cvModule.Mat) {
|
|
447
|
-
console.log('[polling] Found Mat in cvModule');
|
|
448
426
|
resolveOnce('cvModule polling');
|
|
449
427
|
return;
|
|
450
428
|
}
|
|
451
429
|
// 其次检查 globalThis.cv 中是否有 Mat
|
|
452
430
|
if (typeof globalThis !== 'undefined' && globalThis.cv && globalThis.cv.Mat) {
|
|
453
|
-
console.log('[polling] Found Mat in globalThis.cv');
|
|
454
431
|
cvModule = globalThis.cv;
|
|
455
432
|
resolveOnce('globalThis.cv polling');
|
|
456
433
|
return;
|
|
@@ -464,35 +441,59 @@ async function _initializeOpenCV(timeout) {
|
|
|
464
441
|
* @returns Promise that resolves with cv module
|
|
465
442
|
*/
|
|
466
443
|
async function loadOpenCV(timeout = 30000) {
|
|
444
|
+
let cv;
|
|
445
|
+
console.log('[FaceDetectionEngine] Loading OpenCV.js...');
|
|
467
446
|
try {
|
|
468
|
-
//
|
|
469
|
-
if (
|
|
470
|
-
console.log('[
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
447
|
+
// 如果已经在初始化中,复用现有的 Promise
|
|
448
|
+
if (opencvInitPromise) {
|
|
449
|
+
console.log('[FaceDetectionEngine] OpenCV initialization in progress, waiting...');
|
|
450
|
+
try {
|
|
451
|
+
await opencvInitPromise;
|
|
452
|
+
cv = getCvSync();
|
|
453
|
+
if (cv && cv.Mat) {
|
|
454
|
+
console.log('[FaceDetectionEngine] OpenCV.js loaded successfully');
|
|
455
|
+
return { cv };
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
// 失败后清除 Promise,允许重试
|
|
460
|
+
opencvInitPromise = null;
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
478
463
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
464
|
+
else {
|
|
465
|
+
cv = getCvSync();
|
|
466
|
+
if (cv && cv.Mat) {
|
|
467
|
+
console.log('[FaceDetectionEngine] OpenCV.js already initialized');
|
|
468
|
+
return { cv };
|
|
469
|
+
}
|
|
470
|
+
// 开始新的初始化
|
|
471
|
+
console.log('[FaceDetectionEngine] Starting OpenCV initialization...');
|
|
472
|
+
opencvInitPromise = _initializeOpenCV(timeout);
|
|
473
|
+
try {
|
|
474
|
+
await opencvInitPromise;
|
|
475
|
+
cv = getCvSync();
|
|
476
|
+
if (cv && cv.Mat) {
|
|
477
|
+
console.log('[FaceDetectionEngine] OpenCV.js loaded successfully');
|
|
478
|
+
return { cv };
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
// 失败后清除 Promise,允许重试
|
|
483
|
+
opencvInitPromise = null;
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
486
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
487
|
+
// 如果到这里还没有返回,说明加载失败
|
|
488
|
+
console.error('[FaceDetectionEngine] OpenCV module is invalid:', {
|
|
489
|
+
hasMat: cv && cv.Mat,
|
|
490
|
+
type: typeof cv,
|
|
491
|
+
keys: cv ? Object.keys(cv).slice(0, 10) : 'N/A'
|
|
490
492
|
});
|
|
491
|
-
|
|
493
|
+
throw new Error('OpenCV.js loaded but module is invalid (no Mat class found)');
|
|
492
494
|
}
|
|
493
495
|
catch (error) {
|
|
494
|
-
console.error('[
|
|
495
|
-
opencvInitPromise = null; // 失败时清除 Promise,允许重试
|
|
496
|
+
console.error('[FaceDetectionEngine] Failed to load OpenCV.js:', error);
|
|
496
497
|
throw error;
|
|
497
498
|
}
|
|
498
499
|
}
|
|
@@ -511,35 +512,6 @@ function getCvSync() {
|
|
|
511
512
|
}
|
|
512
513
|
return null;
|
|
513
514
|
}
|
|
514
|
-
/**
|
|
515
|
-
* Extract OpenCV version from getBuildInformation
|
|
516
|
-
* @returns version string like "4.12.0"
|
|
517
|
-
*/
|
|
518
|
-
function getOpenCVVersion() {
|
|
519
|
-
try {
|
|
520
|
-
const cv = getCvSync();
|
|
521
|
-
if (!cv || !cv.getBuildInformation) {
|
|
522
|
-
return 'unknown';
|
|
523
|
-
}
|
|
524
|
-
const buildInfo = cv.getBuildInformation();
|
|
525
|
-
// 查找 "Version control:" 或 "OpenCV" 开头的行
|
|
526
|
-
// 格式: "Version control: 4.12.0"
|
|
527
|
-
const versionMatch = buildInfo.match(/Version\s+control:\s+(\d+\.\d+\.\d+)/i);
|
|
528
|
-
if (versionMatch && versionMatch[1]) {
|
|
529
|
-
return versionMatch[1];
|
|
530
|
-
}
|
|
531
|
-
// 备用方案:查找 "OpenCV X.X.X" 格式
|
|
532
|
-
const opencvMatch = buildInfo.match(/OpenCV\s+(\d+\.\d+\.\d+)/i);
|
|
533
|
-
if (opencvMatch && opencvMatch[1]) {
|
|
534
|
-
return opencvMatch[1];
|
|
535
|
-
}
|
|
536
|
-
return 'unknown';
|
|
537
|
-
}
|
|
538
|
-
catch (error) {
|
|
539
|
-
console.error('[getOpenCVVersion] Failed to get version:', error);
|
|
540
|
-
return 'unknown';
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
515
|
/**
|
|
544
516
|
* Load Human.js
|
|
545
517
|
* @param modelPath - Path to model files (optional)
|
|
@@ -547,8 +519,6 @@ function getOpenCVVersion() {
|
|
|
547
519
|
* @returns Promise that resolves with Human instance
|
|
548
520
|
*/
|
|
549
521
|
async function loadHuman(modelPath, wasmPath) {
|
|
550
|
-
console.log('[loadHuman] START - creating config');
|
|
551
|
-
const initStartTime = performance.now();
|
|
552
522
|
const config = {
|
|
553
523
|
backend: _detectOptimalBackend(),
|
|
554
524
|
face: {
|
|
@@ -571,20 +541,24 @@ async function loadHuman(modelPath, wasmPath) {
|
|
|
571
541
|
if (wasmPath) {
|
|
572
542
|
config.wasmPath = wasmPath;
|
|
573
543
|
}
|
|
574
|
-
console.log('[
|
|
544
|
+
console.log('[FaceDetectionEngine] Human.js config:', {
|
|
575
545
|
backend: config.backend,
|
|
576
546
|
modelBasePath: config.modelBasePath || '(using default)',
|
|
577
547
|
wasmPath: config.wasmPath || '(using default)'
|
|
578
548
|
});
|
|
579
|
-
|
|
549
|
+
const initStartTime = performance.now();
|
|
550
|
+
console.log('[FaceDetectionEngine] Creating Human instance...');
|
|
580
551
|
const human = new Human(config);
|
|
581
|
-
|
|
552
|
+
const instanceCreateTime = performance.now() - initStartTime;
|
|
553
|
+
console.log(`[FaceDetectionEngine] Human instance created, took ${instanceCreateTime.toFixed(2)}ms`);
|
|
554
|
+
console.log('[FaceDetectionEngine] Loading Human.js models...');
|
|
555
|
+
const modelLoadStartTime = performance.now();
|
|
582
556
|
try {
|
|
583
|
-
console.log('[loadHuman] Calling human.load()...');
|
|
584
557
|
await human.load();
|
|
585
|
-
|
|
558
|
+
const loadTime = performance.now() - modelLoadStartTime;
|
|
586
559
|
const totalTime = performance.now() - initStartTime;
|
|
587
|
-
console.log('[
|
|
560
|
+
console.log('[FaceDetectionEngine] Human.js loaded successfully', {
|
|
561
|
+
modelLoadTime: `${loadTime.toFixed(2)}ms`,
|
|
588
562
|
totalInitTime: `${totalTime.toFixed(2)}ms`,
|
|
589
563
|
version: human.version
|
|
590
564
|
});
|
|
@@ -592,33 +566,37 @@ async function loadHuman(modelPath, wasmPath) {
|
|
|
592
566
|
}
|
|
593
567
|
catch (error) {
|
|
594
568
|
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
|
|
595
|
-
console.error('[
|
|
596
|
-
console.error('[loadHuman] Error stack:', error instanceof Error ? error.stack : 'N/A');
|
|
569
|
+
console.error('[FaceDetectionEngine] Human.js load failed:', errorMsg);
|
|
597
570
|
throw error;
|
|
598
571
|
}
|
|
599
572
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
573
|
+
/**
|
|
574
|
+
* Extract OpenCV version from getBuildInformation
|
|
575
|
+
* @returns version string like "4.12.0"
|
|
576
|
+
*/
|
|
577
|
+
function getOpenCVVersion() {
|
|
603
578
|
try {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
579
|
+
const cv = getCvSync();
|
|
580
|
+
if (!cv || !cv.getBuildInformation) {
|
|
581
|
+
return 'unknown';
|
|
582
|
+
}
|
|
583
|
+
const buildInfo = cv.getBuildInformation();
|
|
584
|
+
// 查找 "Version control:" 或 "OpenCV" 开头的行
|
|
585
|
+
// 格式: "Version control: 4.12.0"
|
|
586
|
+
const versionMatch = buildInfo.match(/Version\s+control:\s+(\d+\.\d+\.\d+)/i);
|
|
587
|
+
if (versionMatch && versionMatch[1]) {
|
|
588
|
+
return versionMatch[1];
|
|
589
|
+
}
|
|
590
|
+
// 备用方案:查找 "OpenCV X.X.X" 格式
|
|
591
|
+
const opencvMatch = buildInfo.match(/OpenCV\s+(\d+\.\d+\.\d+)/i);
|
|
592
|
+
if (opencvMatch && opencvMatch[1]) {
|
|
593
|
+
return opencvMatch[1];
|
|
594
|
+
}
|
|
595
|
+
return 'unknown';
|
|
617
596
|
}
|
|
618
597
|
catch (error) {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
throw error;
|
|
598
|
+
console.error('[getOpenCVVersion] Failed to get version:', error);
|
|
599
|
+
return 'unknown';
|
|
622
600
|
}
|
|
623
601
|
}
|
|
624
602
|
|
|
@@ -1599,13 +1577,12 @@ class FaceDetectionEngine extends SimpleEventEmitter {
|
|
|
1599
1577
|
this.isInitializing = true;
|
|
1600
1578
|
this.emitDebug('initialization', 'Starting to load detection libraries...');
|
|
1601
1579
|
try {
|
|
1602
|
-
// Load
|
|
1603
|
-
this.emitDebug('initialization', 'Loading
|
|
1604
|
-
const
|
|
1605
|
-
const { cv, human } = await loadLibraries(this.config.human_model_path, this.config.tensorflow_wasm_path, 30000);
|
|
1580
|
+
// Load OpenCV
|
|
1581
|
+
this.emitDebug('initialization', 'Loading OpenCV...');
|
|
1582
|
+
const { cv } = await loadOpenCV(60000); // 1 minute timeout
|
|
1606
1583
|
if (!cv || !cv.Mat) {
|
|
1607
1584
|
console.log('[FaceDetectionEngine] Failed to load OpenCV.js: module is null or invalid');
|
|
1608
|
-
this.emit('detector-
|
|
1585
|
+
this.emit('detector-error', {
|
|
1609
1586
|
success: false,
|
|
1610
1587
|
error: 'Failed to load OpenCV.js: module is null or invalid'
|
|
1611
1588
|
});
|
|
@@ -1615,9 +1592,23 @@ class FaceDetectionEngine extends SimpleEventEmitter {
|
|
|
1615
1592
|
});
|
|
1616
1593
|
return;
|
|
1617
1594
|
}
|
|
1618
|
-
|
|
1595
|
+
const cv_version = getOpenCVVersion();
|
|
1596
|
+
this.emitDebug('initialization', 'OpenCV loaded successfully', {
|
|
1597
|
+
version: cv_version
|
|
1598
|
+
});
|
|
1599
|
+
console.log('[FaceDetectionEngine] OpenCV loaded successfully', {
|
|
1600
|
+
version: cv_version
|
|
1601
|
+
});
|
|
1602
|
+
// Load Human.js
|
|
1603
|
+
console.log('[FaceDetectionEngine] Loading Human.js models...');
|
|
1604
|
+
this.emitDebug('initialization', 'Loading Human.js...');
|
|
1605
|
+
const humanStartTime = performance.now();
|
|
1606
|
+
this.human = await loadHuman(this.config.human_model_path, this.config.tensorflow_wasm_path);
|
|
1607
|
+
const humanLoadTime = performance.now() - humanStartTime;
|
|
1608
|
+
if (!this.human) {
|
|
1619
1609
|
const errorMsg = 'Failed to load Human.js: instance is null';
|
|
1620
1610
|
console.log('[FaceDetectionEngine] ' + errorMsg);
|
|
1611
|
+
this.emitDebug('initialization', errorMsg, { loadTime: humanLoadTime }, 'error');
|
|
1621
1612
|
this.emit('detector-loaded', {
|
|
1622
1613
|
success: false,
|
|
1623
1614
|
error: errorMsg
|
|
@@ -1628,16 +1619,21 @@ class FaceDetectionEngine extends SimpleEventEmitter {
|
|
|
1628
1619
|
});
|
|
1629
1620
|
return;
|
|
1630
1621
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1622
|
+
this.emitDebug('initialization', 'Human.js loaded successfully', {
|
|
1623
|
+
loadTime: `${humanLoadTime.toFixed(2)}ms`,
|
|
1624
|
+
version: this.human.version
|
|
1625
|
+
});
|
|
1626
|
+
console.log('[FaceDetectionEngine] Human.js loaded successfully', {
|
|
1627
|
+
loadTime: `${humanLoadTime.toFixed(2)}ms`,
|
|
1628
|
+
version: this.human.version
|
|
1629
|
+
});
|
|
1633
1630
|
this.isReady = true;
|
|
1634
1631
|
const loadedData = {
|
|
1635
1632
|
success: true,
|
|
1636
|
-
opencv_version:
|
|
1633
|
+
opencv_version: cv_version,
|
|
1637
1634
|
human_version: this.human.version
|
|
1638
1635
|
};
|
|
1639
1636
|
console.log('[FaceDetectionEngine] Engine initialized and ready', {
|
|
1640
|
-
initCostTime: (performance.now() - startLoadTime).toFixed(2),
|
|
1641
1637
|
opencv_version: loadedData.opencv_version,
|
|
1642
1638
|
human_version: loadedData.human_version
|
|
1643
1639
|
});
|