fix(h5): relax capture angles and annotate acne marks

This commit is contained in:
xsl
2026-10-15 19:55:21 +08:00
parent 757b96dfad
commit 482fb4280d
9 changed files with 53 additions and 36 deletions
+2 -1
View File
@@ -1326,7 +1326,8 @@
{ key: 'closed_comedones', color: '#E8A13D' }, // 闭口粉刺
{ key: 'acne', color: '#D30C0C' }, // 痤疮
{ key: 'acne_pustule', color: '#D30C0C' }, // 脓包
{ key: 'acne_nodule', color: '#8E0000' } // 结节
{ key: 'acne_nodule', color: '#8E0000' }, // 结节
{ key: 'acne_mark', color: '#8750C8' } // 痘印:紫色,与红色炎性痘痘区分
] }
};
+1 -1
View File
@@ -6,7 +6,7 @@
'use strict';
// Real-phone feedback: ease alignment and normal hand/head movement while
// retaining two checked frames, one face, framing and final JPEG validation.
var config = Object.freeze({ version: '2026-10-12-fourth-v2', score: 0.4,
var config = Object.freeze({ version: '2026-10-15-angle-relaxed-20-v3', score: 0.4,
near: 0.30, far: 0.68, center: 0.16, edge: 0.01,
dark: 65, bright: 235, holdMs: 450, minFrames: 2, maxGapMs: 2000,
yawDrift: 8, pitchDrift: 8, centerDrift: 0.055, sizeDrift: 0.065 });
+18 -17
View File
@@ -64,12 +64,13 @@
// ---- check 阈值(角度制) ----
// Real-phone feedback: relaxed alignment, without accepting frontal photos
// as side views. These empirical angles are not upstream quality scores.
var FRONT_YAW_MAX = 15;
var FRONT_PITCH_MAX = 18;
var SIDE_YAW_MIN = 30;
var SIDE_YAW_MAX = 70;
var SIDE_PITCH_MAX = 20;
var ROLL_MAX = 15;
// 2026-10-15: expand accepted angles by 20%; lower side minimum by 20%.
var FRONT_YAW_MAX = 18;
var FRONT_PITCH_MAX = 21.6;
var SIDE_YAW_MIN = 24;
var SIDE_YAW_MAX = 84;
var SIDE_PITCH_MAX = 24;
var ROLL_MAX = 18;
var HINT_KEEP = '保持不动';
var HINT_TURN_LEFT = '请向左转头'; // 用户向自己的左侧转
@@ -158,10 +159,10 @@
/**
* check(points, target, mirrored) -> { ok, hint }
* target: 'front' | 'left' | 'right'
* 'front' : |yaw|<=15 且 |pitch|<=18、|roll|<=15;角度不合格只提示回正,
* 'front' : |yaw|<=18 且 |pitch|<=21.6、|roll|<=18;角度不合格只提示回正,
* 不在正脸拍摄完成前播侧脸转头指令。
* 'left' : 画面中看到左脸 = 被摄者头向右转(语义 yaw ∈ [-70°,-30°]),|pitch|<=20
* 'right' : 画面中看到右脸 = 被摄者头向左转(语义 yaw ∈ [30°,70°]),|pitch|<=20
* 'left' : 画面中看到左脸 = 被摄者头向右转(语义 yaw ∈ [-84°,-24°]),|pitch|<=24
* 'right' : 画面中看到右脸 = 被摄者头向左转(语义 yaw ∈ [24°,84°]),|pitch|<=24
* ok=true 时 hint='保持不动';输入非法(含 estimate 返回 null 的退化特征点)时 ok=false、hint='请正对屏幕'。
*/
function check(points, target, mirrored) {
@@ -295,13 +296,13 @@ if (typeof module !== 'undefined' && typeof require !== 'undefined' && require.m
ok(bc.ok === true, '反向侧脸 target=left ok');
ok(HeadPose.check(back, 'right', false).ok === false, '反向侧脸 target=right 拒绝');
// 7) 侧脸做 front check → 拒绝并引导转回(被摄者左转 → 请向右转头;反向 → 请向左转头)
// 7) 正面步骤只提示回正,不能提前引导拍下一张侧脸。
var sc = HeadPose.check(makeSide(), 'front', false);
ok(sc.ok === false && sc.hint === '请向右转头', '左转侧脸 front 拒绝,hint=请向右转头');
ok(sc.ok === false && sc.hint === '请正对屏幕', '左转侧脸 front 拒绝,hint=请正对屏幕');
var scb = makeSide();
scb[30] = { x: 182.3, y: 140 };
scb[33] = { x: 182.3, y: 161.5 };
ok(HeadPose.check(scb, 'front', false).hint === '请向左转头', '右转侧脸 front 拒绝,hint=请向左转头');
ok(HeadPose.check(scb, 'front', false).hint === '请正对屏幕', '右转侧脸 front 拒绝,hint=请正对屏幕');
// 8) roll:右眼(45 点)下移 10px → roll≈5.7°
var tilted = makeFrontal();
@@ -314,10 +315,10 @@ if (typeof module !== 'undefined' && typeof require !== 'undefined' && require.m
var de = HeadPose.estimate(down, false);
var dc = HeadPose.check(down, 'front', false);
ok(de.pitch < -30, '低头 pitch<0 (got ' + de.pitch.toFixed(2) + ')');
ok(dc.ok === false && dc.hint === '请略微抬头', '低头 front 拒绝,hint=请略微抬头');
ok(dc.ok === false && dc.hint === '请正对屏幕', '低头 front 拒绝,hint=请正对屏幕');
var up = makeFrontal();
up[33] = { x: 200, y: 200 };
ok(HeadPose.check(up, 'front', false).hint === '请略微低头', '抬头过多 front 拒绝,hint=请略微低头');
ok(HeadPose.check(up, 'front', false).hint === '请正对屏幕', '抬头过多 front 拒绝,hint=请正对屏幕');
// 10) 非法输入:check 不抛异常,返回兜底引导
var bad = HeadPose.check(null, 'front', false);
@@ -336,8 +337,8 @@ if (typeof module !== 'undefined' && typeof require !== 'undefined' && require.m
ok(HeadPose.estimate(tiny, false) === null, 'faceHeight 过小 → estimate 返回 null');
ok(HeadPose.check(tiny, 'front', false).hint === '请正对屏幕', 'faceHeight 过小 check 兜底');
// 13) Phone feedback: restore the 15° frontal margin, still reject 16°+.
ok(HeadPose.config.FRONT_YAW_MAX === 15, 'config.FRONT_YAW_MAX = 15');
// 13) Phone feedback: expand the frontal margin to 18 degrees.
ok(HeadPose.config.FRONT_YAW_MAX === 18, 'config.FRONT_YAW_MAX = 18');
var slight = makeFrontal();
slight[30] = { x: 205.6, y: 140 }; // 偏移 5.6 → yaw≈14.9°(YAW_COEFF=3.8 标定)
slight[33] = { x: 205.6, y: 161.5 };
@@ -351,7 +352,7 @@ if (typeof module !== 'undefined' && typeof require !== 'undefined' && require.m
var se2 = HeadPose.estimate(slight2, false);
ok(se2.yaw > 15 && se2.yaw < 17.5, '偏头 yaw∈(15,17.5) (got ' + se2.yaw.toFixed(2) + ')');
var sc3 = HeadPose.check(slight2, 'front', false);
ok(sc3.ok === false && sc3.hint === '请向右转头', 'yaw≈16.2° front 拒绝,hint=请向右转头');
ok(sc3.ok === true, 'yaw≈16.2° front 通过(放宽20%)');
if (failures > 0) {
console.error('\n' + failures + ' 项自测失败');