Skip to content

Commit 4e6f66a

Browse files
fix: localize region alarm rules and update tutorials
1 parent 9aab225 commit 4e6f66a

10 files changed

Lines changed: 491 additions & 150 deletions

File tree

266 KB
Loading
-22.2 KB
Binary file not shown.

docs/en/tutorials/04-pipeline-orchestration/pipeline-orchestration.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ relationship, so the guide starts from a known minimum business chain.
139139
| Model | Installed `PedestrianDetection` atomic model |
140140
| Rules | Track people, keep the pedestrian class, decide whether a target enters the main area |
141141
| Output | Region-intrusion event with the person target and snapshot |
142-
| Positive sample | A clearly visible person enters the area and satisfies the duration |
142+
| Positive sample | A clearly visible person enters the area and satisfies the minimum stay duration |
143143
| Negative sample | A person passes only outside the area |
144144
| Acceptance | Positive has a box and event; negative has no intrusion event; the task still works after restart |
145145

@@ -181,10 +181,12 @@ Complete these six numbered steps:
181181
Keep the pedestrian label and start with the current Min Pedestrian Size of `60`.
182182

183183
5. **Region Alarm**
184-
Select the main area as input. This node evaluates whether pedestrians enter the area drawn during
185-
scenario task assignment.
184+
Select **Exception Alarm** for **Output Purpose**, **Target Region Stay** for **Region Rule Type**,
185+
**Primary Region** for **Decision Region**, and **Target is inside the region** for
186+
**Stay Start Condition**. This node evaluates whether pedestrians enter the area drawn during scenario
187+
task assignment and produces a candidate alarm after the minimum stay duration is satisfied.
186188

187-
![Using the main area in Region Alarm](images/img_42.webp)
189+
![Selecting Exception Alarm, Target Region Stay, and Primary Region in Region Alarm](images/img_42.png)
188190

189191
6. **Event Report**
190192
Select a triggered event with target tracking. Video clips increase storage and transfer load, so enable
@@ -211,7 +213,7 @@ Under **Parameter Settings**, start from an explainable baseline:
211213
| --- | ---: | --- |
212214
| Pedestrian Detection Method | Bottom | Use the person's foot position for a ground-plane area |
213215
| Min Pedestrian Size | 60 | Remove very small pedestrian targets |
214-
| Detection Time | 0 seconds | Prove the chain first; increase later to suppress brief entry |
216+
| Minimum Stay Duration | 0 seconds | Prove the chain first; increase later to suppress brief entry |
215217
| Alarm Interval (sec) | 3 | Convenient for a short test; increase for the production response process |
216218
| Alarm Count | 1 | Verify a single trigger first |
217219
| Stationary Target Deduplication | Off | Observe raw behavior before deciding whether to enable it |
@@ -271,7 +273,7 @@ Final pass criteria:
271273

272274
1. Confirm that Category Filter does not remove every target.
273275
2. Confirm that the target enters the area using the selected box position.
274-
3. Restore detection duration and alarm suppression to a testable baseline.
276+
3. Restore minimum stay duration and alarm suppression to a testable baseline.
275277
4. Confirm that Event Report exists after the rules and is configured for a triggered event.
276278
5. Check Event Center filters and storage space.
277279

256 KB
Loading

docs/tutorials/04-pipeline-orchestration/pipeline-orchestration.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ next:
138138
| 模型 | 已安装的 `PedestrianDetection` 行人检测原子模型 |
139139
| 规则 | 追踪行人、保留行人类别、判断是否进入主区域 |
140140
| 输出 | 带行人目标的区域入侵事件和抓拍图 |
141-
| 正样本 | 人员清晰进入区域并满足检测持续时间 |
141+
| 正样本 | 人员清晰进入区域并满足最短停留时间 |
142142
| 负样本 | 人员只在区域外经过 |
143143
| 验收方法 | 正样本有框且有事件;负样本不产生区域入侵事件;重启任务后仍可运行 |
144144

@@ -179,9 +179,11 @@ next:
179179
保留行人标签,最小行人尺寸从当前默认 `60` 开始。过小目标漏报或噪声问题出现后再调。
180180

181181
5. **区域告警判断**
182-
输入区域类型选择主区域。该节点依据场景任务分配页绘制的区域判断行人是否进入。
182+
输出目的选择 **异常告警**,区域规则类型选择 **目标区域停留**,判断区域选择
183+
**主区域**,停留开始条件选择 **目标位于区域内**。该节点依据场景任务分配页绘制的
184+
区域判断行人是否进入,并按最短停留时间产生候选告警。
183185

184-
![区域告警判断节点使用主区域](images/img_42.webp)
186+
![区域告警判断节点选择异常告警、目标区域停留和主区域](images/img_42.png)
185187

186188
6. **事件上报**
187189
选择带目标跟踪的触发类事件。是否附带视频片段会影响存储和传输,应按项目要求设置;
@@ -208,7 +210,7 @@ next:
208210
| --- | ---: | --- |
209211
| pedestrian 检测方式 | 底部 | 以行人脚部位置判断是否进入地面区域 |
210212
| 最小行人尺寸 | 60 | 过滤过小行人目标 |
211-
| 检测时间 | 0 秒 | 首轮先验证链路;需要抑制瞬时进入时再增加 |
213+
| 最短停留时间 | 0 秒 | 首轮先验证链路;需要抑制瞬时进入时再增加 |
212214
| 告警时间间隔(秒) | 3 | 便于短视频验证;生产环境按处置流程增大 |
213215
| 告警次数 | 1 | 首轮只验证一次触发 |
214216
| 静止目标去重 | 关闭 | 先观察原始行为,再决定是否启用 |
@@ -267,7 +269,7 @@ next:
267269

268270
1. 确认类别过滤没有删除全部目标。
269271
2. 确认目标实际进入检测区域,且检测方式选择的位置正确。
270-
3. 将检测时间和告警抑制恢复为可验证基线
272+
3. 将最短停留时间和告警抑制恢复为可验证基线
271273
4. 检查事件上报节点存在、位于规则之后,并已配置触发类事件。
272274
5. 检查事件中心筛选条件和存储空间。
273275

src/web/scripts/area_rule_compatibility_check.mjs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,25 @@ import {
33
AREA_RULE_UI_TYPES,
44
applyAreaRuleUiType,
55
buildAreaRuleSummary,
6+
getAreaRuleFieldText,
7+
getAreaRuleOptionLabel,
68
inferAreaRuleUiType,
79
mergeParamsPreservingUnknown
810
} from '../src/views/gam/countManagement/arrangeDetail/flow/areaRuleCompatibility.js'
11+
import zhCN from '../src/i18n/locales/zh-CN.js'
12+
import enUS from '../src/i18n/locales/en-US.js'
13+
14+
const createTranslator = (messages) => (key, params = {}) => {
15+
const value = key.split('.').reduce((current, segment) => current?.[segment], messages)
16+
assert.equal(typeof value, 'string', `missing translation: ${key}`)
17+
return Object.entries(params).reduce(
18+
(text, [name, replacement]) => text.replaceAll(`{${name}}`, String(replacement)),
19+
value
20+
)
21+
}
22+
23+
const zhT = createTranslator(zhCN)
24+
const enT = createTranslator(enUS)
925

1026
const legacy = [
1127
{ key: 'areaAlarmType', value: '6' },
@@ -14,7 +30,7 @@ const legacy = [
1430
]
1531
assert.equal(inferAreaRuleUiType(legacy), AREA_RULE_UI_TYPES.LEGACY_TARGET_LIMIT)
1632
assert.match(
17-
buildAreaRuleSummary(legacy, AREA_RULE_UI_TYPES.LEGACY_TARGET_LIMIT),
33+
buildAreaRuleSummary(legacy, AREA_RULE_UI_TYPES.LEGACY_TARGET_LIMIT, zhT),
1834
/ < 2/
1935
)
2036

@@ -31,7 +47,8 @@ compareCases.forEach(([compare, symbol]) => {
3147
{ key: 'param.areaLimitTargetCount', value: '3' },
3248
{ key: 'param.areaLimitTargetType', value: compare }
3349
],
34-
AREA_RULE_UI_TYPES.TARGET_LIMIT
50+
AREA_RULE_UI_TYPES.TARGET_LIMIT,
51+
zhT
3552
)
3653
assert.match(summary, new RegExp(`有效目标数 ${symbol} 3`))
3754
})
@@ -66,4 +83,50 @@ const unknown = [{ key: 'areaAlarmType', value: '99' }]
6683
assert.equal(inferAreaRuleUiType(unknown), AREA_RULE_UI_TYPES.UNKNOWN)
6784
assert.deepEqual(applyAreaRuleUiType(unknown, AREA_RULE_UI_TYPES.UNKNOWN), unknown)
6885

86+
assert.equal(
87+
getAreaRuleFieldText('inputAreaType', enT).name,
88+
'Decision Region'
89+
)
90+
assert.equal(
91+
getAreaRuleOptionLabel('param.areaLimitTargetType', '0', '', enT),
92+
'Less than'
93+
)
94+
95+
const englishSummaryCases = [
96+
[
97+
AREA_RULE_UI_TYPES.TARGET_LIMIT,
98+
[
99+
{ key: 'param.areaLimitTargetCount', value: '3' },
100+
{ key: 'param.areaLimitTargetType', value: '0' }
101+
]
102+
],
103+
[AREA_RULE_UI_TYPES.AREA_COUNT, []],
104+
[AREA_RULE_UI_TYPES.PASS_FLOW, []],
105+
[AREA_RULE_UI_TYPES.TRIPWIRE, [{ key: 'param.trippingWireType', value: '1' }]],
106+
[
107+
AREA_RULE_UI_TYPES.DIRECTION,
108+
[
109+
{ key: 'param.retroDirect', value: '0' },
110+
{ key: 'param.retroDistance', value: '0.05' }
111+
]
112+
],
113+
[
114+
AREA_RULE_UI_TYPES.DURATION,
115+
[
116+
{ key: 'durationBreakAreaType', value: '0' },
117+
{ key: 'param.areaDuration', value: '10' },
118+
{ key: 'param.areaDurationTimeType', value: '1000' }
119+
]
120+
],
121+
[AREA_RULE_UI_TYPES.PRESENCE, []],
122+
[AREA_RULE_UI_TYPES.LEGACY_TARGET_LIMIT, legacy],
123+
[AREA_RULE_UI_TYPES.UNKNOWN, unknown]
124+
]
125+
126+
englishSummaryCases.forEach(([type, params]) => {
127+
const summary = buildAreaRuleSummary(params, type, enT)
128+
assert.ok(summary.length > 0, `empty English summary for ${type}`)
129+
assert.doesNotMatch(summary, /\p{Script=Han}/u, `Chinese leaked into ${type}: ${summary}`)
130+
})
131+
69132
console.log('area rule compatibility checks passed')

src/web/src/i18n/locales/en-US.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,151 @@ export default {
16531653
}
16541654
},
16551655
flow: {
1656+
areaRule: {
1657+
title: 'Region Rule Configuration',
1658+
purposeLabel: 'Output Purpose',
1659+
purposes: {
1660+
alarm: 'Exception Alarm',
1661+
statistics: 'Statistics Report',
1662+
compatibility: 'Compatibility Configuration'
1663+
},
1664+
typeLabel: 'Region Rule Type',
1665+
summaryLabel: 'Rule Description',
1666+
downstreamNote: 'Whether an alarm record is ultimately created still depends on rate limits, deduplication, and review rules in the downstream “Event Report” node.',
1667+
legacyNote: 'This is a legacy multi-node configuration. Editing preserves the original type 6 and parameter keys without automatic migration.',
1668+
types: {
1669+
targetLimit: 'Region Target Count Condition',
1670+
areaCount: 'Region Target Count Statistics',
1671+
passFlow: 'Entry/Exit Flow Statistics',
1672+
tripwire: 'Target Line Crossing',
1673+
direction: 'Vertical Direction Anomaly',
1674+
duration: 'Target Region Stay',
1675+
presence: 'Target Present in Region',
1676+
legacyTargetLimit: 'Region Target Count Condition (Legacy Multi-node)',
1677+
unknown: 'Unrecognized Legacy Region Rule'
1678+
},
1679+
fields: {
1680+
decisionRegion: {
1681+
name: 'Decision Region',
1682+
description: 'Choose the primary or associated region for rule evaluation.'
1683+
},
1684+
targetCountThreshold: {
1685+
name: 'Target Count Threshold',
1686+
description: 'Compared with the actual valid target count in the region.'
1687+
},
1688+
triggerCondition: {
1689+
name: 'Trigger Condition',
1690+
description: 'Choose the comparison between the actual target count and the threshold.'
1691+
},
1692+
conditionDuration: {
1693+
name: 'Condition Duration',
1694+
description: 'How long the count condition must remain true; 0 evaluates the current frame.'
1695+
},
1696+
durationUnit: {
1697+
name: 'Duration Unit',
1698+
description: 'Time unit used by the condition duration.'
1699+
},
1700+
reportingPeriod: {
1701+
name: 'Statistics Reporting Period',
1702+
description: 'Periodically produces region count or entry/exit flow statistics.'
1703+
},
1704+
reportingPeriodUnit: {
1705+
name: 'Reporting Period Unit',
1706+
description: 'Time unit used by the statistics reporting period.'
1707+
},
1708+
crossingDirection: {
1709+
name: 'Crossing Direction',
1710+
description: 'Matches when a target crosses in the direction marked on the tripwire.'
1711+
},
1712+
requiredLineCount: {
1713+
name: 'Required Tripwire Count',
1714+
description: 'Number of tripwires the same tracked target must cross.'
1715+
},
1716+
stayStartCondition: {
1717+
name: 'Stay Start Condition',
1718+
description: 'Choose whether the target only needs to be inside the region or must first be observed entering from outside.'
1719+
},
1720+
minimumStayDuration: {
1721+
name: 'Minimum Stay Duration',
1722+
description: 'How long the same tracked target must continuously remain in the region.'
1723+
},
1724+
stayDurationUnit: {
1725+
name: 'Stay Duration Unit',
1726+
description: 'Time unit used by the minimum stay duration.'
1727+
},
1728+
prohibitedDirection: {
1729+
name: 'Prohibited Movement Direction',
1730+
description: 'The current implementation evaluates vertical movement and requires stable target tracking.'
1731+
},
1732+
minimumAbnormalDisplacement: {
1733+
name: 'Minimum Abnormal Displacement',
1734+
description: 'A ratio of frame height; 0.05 means 5% of the frame height.'
1735+
},
1736+
legacyTargetCountThreshold: {
1737+
name: 'Target Count Threshold',
1738+
description: 'Target count threshold used by the legacy multi-node configuration.'
1739+
},
1740+
legacyTriggerCondition: {
1741+
name: 'Trigger Condition',
1742+
description: 'Count comparison used by the legacy multi-node configuration.'
1743+
},
1744+
legacyConditionDuration: {
1745+
name: 'Condition Duration',
1746+
description: 'Condition duration used by the legacy multi-node configuration.'
1747+
},
1748+
legacyDurationUnit: {
1749+
name: 'Duration Unit',
1750+
description: 'Time unit used by the legacy multi-node configuration.'
1751+
},
1752+
periodicDataChangeMarker: {
1753+
name: 'Periodic Data Change Marker',
1754+
description: 'Marks whether the target count changed in a periodic report; it does not bypass the reporting period.'
1755+
}
1756+
},
1757+
options: {
1758+
compare: {
1759+
lessThan: 'Less than',
1760+
greaterThan: 'Greater than',
1761+
notGreaterThan: 'Not greater than',
1762+
notLessThan: 'Not less than',
1763+
equalTo: 'Equal to'
1764+
},
1765+
unit: {
1766+
milliseconds: 'ms',
1767+
seconds: 's',
1768+
minutes: 'min',
1769+
hours: 'h'
1770+
},
1771+
tripwire: {
1772+
count1: 'Cross 1 tripwire',
1773+
count2: 'Cross 2 tripwires'
1774+
},
1775+
stayStart: {
1776+
inside: 'Target is inside the region',
1777+
entered: 'Target enters from outside the region',
1778+
insideFallback: 'inside the region'
1779+
},
1780+
direction: {
1781+
bottomToTop: 'from bottom to top of the frame',
1782+
topToBottom: 'from top to bottom of the frame',
1783+
specified: 'in the specified direction'
1784+
}
1785+
},
1786+
summary: {
1787+
currentFrame: 'evaluated on the current frame',
1788+
satisfiedFor: 'satisfied for {value} {unit}',
1789+
targetExpression: 'Valid target count {symbol} {count}',
1790+
targetExpressionFallback: 'The valid target count satisfies the selected threshold relation',
1791+
targetLimit: 'Compares the valid target count in the region with the target count threshold and supports <, >, ≤, ≥, and =. Current configuration: {expression}; a candidate alarm is produced when the condition is {duration}.',
1792+
areaCount: 'Periodically reports the current valid target count in the region, including zero. This is statistical data, not an exception alarm.',
1793+
passFlow: 'Periodically reports tripwire entries, exits, and cumulative flow. This rule requires stable target tracking.',
1794+
tripwire: 'A candidate alarm is produced when the same tracked target crosses the configured number ({count}) of tripwires in the marked direction.',
1795+
direction: 'A candidate alarm is produced when the same target moves {direction} by more than {distance}% of the frame height.',
1796+
duration: 'A candidate alarm is produced when the same target satisfies “{condition}” and the stay condition is {duration}.',
1797+
presence: 'A candidate alarm is produced when any valid upstream target is inside the decision region. Target classes are determined by the upstream model and category filter.',
1798+
unknown: 'This configuration contains a legacy rule value that the current interface cannot recognize. Use compatibility mode for read-only inspection to avoid overwriting it.'
1799+
}
1800+
},
16561801
actionNames: {
16571802
'目标检测算法': 'Target Detection',
16581803
'目标分类算法': 'Target Classification',

0 commit comments

Comments
 (0)