|
@@ -274,6 +274,13 @@ border-left:3px solid #e94560;padding:8px 10px;margin-bottom:8px;cursor:pointer}
|
|
|
<div id="poseActionList" style="display:grid;grid-template-columns:1fr 1fr;gap:8px 16px;font-size:13px"></div>
|
|
<div id="poseActionList" style="display:grid;grid-template-columns:1fr 1fr;gap:8px 16px;font-size:13px"></div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <div class="card">
|
|
|
|
|
+ <h3>屏蔽区域</h3>
|
|
|
|
|
+ <div class="form-group">
|
|
|
|
|
+ <label>每路排除误识别区域, 格式: x1,y1,x2,y2 (多个用;分隔, 不同路用行分隔)</label>
|
|
|
|
|
+ <div id="excludeZoneList"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</section>
|
|
</section>
|
|
|
|
|
|
|
@@ -1142,11 +1149,44 @@ async function loadPoseConfig() {
|
|
|
enabled.push('跌倒');
|
|
enabled.push('跌倒');
|
|
|
document.querySelectorAll('.pose-act-ck').forEach(c =>
|
|
document.querySelectorAll('.pose-act-ck').forEach(c =>
|
|
|
c.checked = enabled.includes(c.value));
|
|
c.checked = enabled.includes(c.value));
|
|
|
|
|
+ // 屏蔽区域
|
|
|
|
|
+ const ez = pd.pose_exclude_zones || {};
|
|
|
|
|
+ const zlist = document.getElementById('excludeZoneList');
|
|
|
|
|
+ if (zlist) {
|
|
|
|
|
+ const rows = Object.keys(ez).map(cid => {
|
|
|
|
|
+ const zones = ez[cid] || [];
|
|
|
|
|
+ const txt = zones.map(z => z.join(',')).join(';');
|
|
|
|
|
+ return `<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
|
|
|
|
+ <span style="width:50px;font-size:12px;color:#888">CH${cid}</span>
|
|
|
|
|
+ <input type="text" class="exclude-zone" data-ch="${cid}" value="${txt}" placeholder="x1,y1,x2,y2;x1,y1,x2,y2" style="flex:1;padding:6px;background:#0e1426;border:1px solid #0f3460;color:#eee;font-size:13px">
|
|
|
|
|
+ </div>`;
|
|
|
|
|
+ }).join('');
|
|
|
|
|
+ // 补充未配置的通道(最多8路)
|
|
|
|
|
+ const chs = (window.CHANNELS || []).map(c => String(c.id));
|
|
|
|
|
+ const extra = chs.filter(cid => !ez[cid]).map(cid =>
|
|
|
|
|
+ `<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">
|
|
|
|
|
+ <span style="width:50px;font-size:12px;color:#888">CH${cid}</span>
|
|
|
|
|
+ <input type="text" class="exclude-zone" data-ch="${cid}" value="" placeholder="x1,y1,x2,y2;x1,y1,x2,y2" style="flex:1;padding:6px;background:#0e1426;border:1px solid #0f3460;color:#eee;font-size:13px">
|
|
|
|
|
+ </div>`).join('');
|
|
|
|
|
+ zlist.innerHTML = rows + extra;
|
|
|
|
|
+ }
|
|
|
} catch (e) {}
|
|
} catch (e) {}
|
|
|
}
|
|
}
|
|
|
async function savePoseConfig() {
|
|
async function savePoseConfig() {
|
|
|
const checks = {};
|
|
const checks = {};
|
|
|
document.querySelectorAll('.pose-act-ck').forEach(c => checks[c.value] = c.checked);
|
|
document.querySelectorAll('.pose-act-ck').forEach(c => checks[c.value] = c.checked);
|
|
|
|
|
+ // 收集屏蔽区域
|
|
|
|
|
+ const ez = {};
|
|
|
|
|
+ document.querySelectorAll('.exclude-zone').forEach(inp => {
|
|
|
|
|
+ const txt = inp.value.trim();
|
|
|
|
|
+ if (!txt) return;
|
|
|
|
|
+ const zones = [];
|
|
|
|
|
+ txt.split(';').forEach(part => {
|
|
|
|
|
+ const n = part.split(',').map(x => parseInt(x.trim())).filter(x => !isNaN(x));
|
|
|
|
|
+ if (n.length === 4 && n[2] > n[0] && n[3] > n[1]) zones.push(n);
|
|
|
|
|
+ });
|
|
|
|
|
+ if (zones.length) ez[inp.dataset.ch] = zones;
|
|
|
|
|
+ });
|
|
|
const body = {
|
|
const body = {
|
|
|
pose_enabled: document.getElementById('cfgPoseEnabled').checked,
|
|
pose_enabled: document.getElementById('cfgPoseEnabled').checked,
|
|
|
fall_thresh: parseFloat(document.getElementById('cfgFallThresh').value),
|
|
fall_thresh: parseFloat(document.getElementById('cfgFallThresh').value),
|
|
@@ -1155,7 +1195,8 @@ async function savePoseConfig() {
|
|
|
pose_crouch: !!checks['异常蹲坐'],
|
|
pose_crouch: !!checks['异常蹲坐'],
|
|
|
pose_recline: !!checks['半躺'],
|
|
pose_recline: !!checks['半躺'],
|
|
|
pose_hand_to_mouth: !!checks['手近嘴部'],
|
|
pose_hand_to_mouth: !!checks['手近嘴部'],
|
|
|
- pose_min_area: parseInt(document.getElementById('cfgMinArea').value) || 3000
|
|
|
|
|
|
|
+ pose_min_area: parseInt(document.getElementById('cfgMinArea').value) || 3000,
|
|
|
|
|
+ pose_exclude_zones: ez
|
|
|
};
|
|
};
|
|
|
try {
|
|
try {
|
|
|
const r = await fetch('/api/pose/config', {method:'POST',
|
|
const r = await fetch('/api/pose/config', {method:'POST',
|