@windsland52/maafw-live 0.0.0-stage → 0.3.0
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/LICENSE +21 -0
- package/README.md +278 -2
- package/bin/maafw-live.mjs +25 -0
- package/docs/daemon-protocol.md +116 -0
- package/docs/keyframe-evidence-contract-v0.md +61 -0
- package/docs/keyframe-retention-contract-v0.md +236 -0
- package/lib/client/daemon.js +234 -0
- package/lib/client/daemon.js.map +1 -0
- package/lib/commands/annotate.js +172 -0
- package/lib/commands/annotate.js.map +1 -0
- package/lib/commands/calibrate.js +61 -0
- package/lib/commands/calibrate.js.map +1 -0
- package/lib/commands/color.js +73 -0
- package/lib/commands/color.js.map +1 -0
- package/lib/commands/crop.js +228 -0
- package/lib/commands/crop.js.map +1 -0
- package/lib/commands/env.js +215 -0
- package/lib/commands/env.js.map +1 -0
- package/lib/commands/index.js +64 -0
- package/lib/commands/index.js.map +1 -0
- package/lib/commands/input.js +219 -0
- package/lib/commands/input.js.map +1 -0
- package/lib/commands/kf.js +131 -0
- package/lib/commands/kf.js.map +1 -0
- package/lib/commands/reco.js +211 -0
- package/lib/commands/reco.js.map +1 -0
- package/lib/commands/repl.js +698 -0
- package/lib/commands/repl.js.map +1 -0
- package/lib/commands/runtime.js +514 -0
- package/lib/commands/runtime.js.map +1 -0
- package/lib/commands/skill.js +169 -0
- package/lib/commands/skill.js.map +1 -0
- package/lib/commands/timing.js +229 -0
- package/lib/commands/timing.js.map +1 -0
- package/lib/commands/version.js +66 -0
- package/lib/commands/version.js.map +1 -0
- package/lib/daemon/framed.mjs +2850 -0
- package/lib/daemon/reco_child.mjs +146 -0
- package/lib/exec.js +96 -0
- package/lib/exec.js.map +1 -0
- package/lib/flags.js +42 -0
- package/lib/flags.js.map +1 -0
- package/lib/image.js +90 -0
- package/lib/image.js.map +1 -0
- package/lib/index.js +139 -0
- package/lib/index.js.map +1 -0
- package/lib/interface/index.js +12 -0
- package/lib/interface/index.js.map +1 -0
- package/lib/interface/jsonc.js +95 -0
- package/lib/interface/jsonc.js.map +1 -0
- package/lib/interface/load.js +307 -0
- package/lib/interface/load.js.map +1 -0
- package/lib/interface/override.js +103 -0
- package/lib/interface/override.js.map +1 -0
- package/lib/interface/plan.js +188 -0
- package/lib/interface/plan.js.map +1 -0
- package/lib/pkg.js +18 -0
- package/lib/pkg.js.map +1 -0
- package/lib/protocol.js +90 -0
- package/lib/protocol.js.map +1 -0
- package/lib/runtime/actions.js +110 -0
- package/lib/runtime/actions.js.map +1 -0
- package/lib/runtime/keyframes.js +73 -0
- package/lib/runtime/keyframes.js.map +1 -0
- package/lib/runtime/session.js +86 -0
- package/lib/runtime/session.js.map +1 -0
- package/lib/types/client/daemon.d.ts +86 -0
- package/lib/types/commands/annotate.d.ts +3 -0
- package/lib/types/commands/calibrate.d.ts +7 -0
- package/lib/types/commands/color.d.ts +9 -0
- package/lib/types/commands/crop.d.ts +3 -0
- package/lib/types/commands/env.d.ts +2 -0
- package/lib/types/commands/index.d.ts +13 -0
- package/lib/types/commands/input.d.ts +17 -0
- package/lib/types/commands/kf.d.ts +10 -0
- package/lib/types/commands/reco.d.ts +23 -0
- package/lib/types/commands/repl.d.ts +2 -0
- package/lib/types/commands/runtime.d.ts +48 -0
- package/lib/types/commands/skill.d.ts +17 -0
- package/lib/types/commands/timing.d.ts +64 -0
- package/lib/types/commands/version.d.ts +3 -0
- package/lib/types/exec.d.ts +31 -0
- package/lib/types/flags.d.ts +58 -0
- package/lib/types/image.d.ts +27 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/interface/index.d.ts +11 -0
- package/lib/types/interface/jsonc.d.ts +9 -0
- package/lib/types/interface/load.d.ts +113 -0
- package/lib/types/interface/override.d.ts +33 -0
- package/lib/types/interface/plan.d.ts +47 -0
- package/lib/types/pkg.d.ts +6 -0
- package/lib/types/protocol.d.ts +108 -0
- package/lib/types/runtime/actions.d.ts +166 -0
- package/lib/types/runtime/keyframes.d.ts +43 -0
- package/lib/types/runtime/session.d.ts +53 -0
- package/lib/types/update-check.d.ts +20 -0
- package/lib/types/usage.d.ts +3 -0
- package/lib/update-check.js +97 -0
- package/lib/update-check.js.map +1 -0
- package/lib/usage.js +50 -0
- package/lib/usage.js.map +1 -0
- package/package.json +81 -4
- package/skills/README.md +51 -0
- package/skills/maafw-live/SKILL.md +263 -0
- package/skills/maafw-live/references/examples.md +238 -0
- package/skills/maafw-live/references/pitfalls.md +118 -0
- package/skills/maafw-live/references/workflows.md +159 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* annotate(轻量 SoM):候选区域 + 编号回画。
|
|
3
|
+
*
|
|
4
|
+
* 模型消费方式:看回画图选编号 → 查候选表 ctrl 坐标 → click / reco / crop。
|
|
5
|
+
* 候选源:OCR 框(语义最强)、变化 diff 区域、连通域、边缘密度;半透明/粒子/渐变场景
|
|
6
|
+
* 候选质量降级——那时走点选路径(crop --point),两条路径互为降级。
|
|
7
|
+
*
|
|
8
|
+
* 源帧两条路:会话内 L1 小图(缺省,一次性命令自动截一帧)或**关键帧库留存帧**(`--from-kf`,
|
|
9
|
+
* 控制器分辨率、离线、不需要设备)。库帧路径下 diff 源不可用(没有会话事件),工具如实报出,
|
|
10
|
+
* 不拿别的区域顶替——所以它适合"事后在旧帧上重跑候选",不适合替代实时变化检测。
|
|
11
|
+
*/
|
|
12
|
+
import { defaultFramesDir, resolveFrame } from '../runtime/keyframes.js';
|
|
13
|
+
import { EXIT, fail } from '../protocol.js';
|
|
14
|
+
import { annotate, seedObservation, withDaemon } from '../runtime/actions.js';
|
|
15
|
+
import { describeSession, ensureSession, offlineResource } from '../runtime/session.js';
|
|
16
|
+
import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
|
|
17
|
+
export const annotateCommand = {
|
|
18
|
+
name: 'annotate',
|
|
19
|
+
summary: '轻量 SoM:OCR/diff/连通域/边缘密度候选区域 + 编号回画(源可为会话内帧或关键帧库留存帧)',
|
|
20
|
+
usage: 'maafw-live annotate [--seq n] [--out <png>] [--resource-dir <dir>] [--project <dir>|--kind ...]\n' +
|
|
21
|
+
' maafw-live annotate --from-kf <kf:库UUID:序号> [--frames-dir <dir>] [--out <png>] [--resource-dir <dir>|--project <dir>]\n' +
|
|
22
|
+
' OCR 候选需要资源目录(OCR 模型);一次性命令自动截一帧;其余候选源无依赖\n' +
|
|
23
|
+
' --from-kf 在库里留存帧上离线跑(不需要设备;该路径没有会话事件,diff 源不可用)\n' +
|
|
24
|
+
' --som-limit n 放开候选上限(缺省 30;网格/表格类界面必给)\n' +
|
|
25
|
+
' --som-max-area-ratio r 巨框剔除阈值(缺省 0.12,按画面面积比;OCR 框不参与)\n' +
|
|
26
|
+
' 回画优先落在 L0 全分辨率原图上;回执带 availability(截断/剔除/分带),别把"30 条"读成"画面就这些"',
|
|
27
|
+
options: {
|
|
28
|
+
...CONNECT_OPTIONS,
|
|
29
|
+
seq: { type: 'string' },
|
|
30
|
+
out: { type: 'string' },
|
|
31
|
+
'resource-dir': { type: 'string' },
|
|
32
|
+
'from-kf': { type: 'string' },
|
|
33
|
+
'frames-dir': { type: 'string' },
|
|
34
|
+
'som-limit': { type: 'string' },
|
|
35
|
+
'som-max-area-ratio': { type: 'string' },
|
|
36
|
+
roi: { type: 'string' },
|
|
37
|
+
},
|
|
38
|
+
async run(ctx) {
|
|
39
|
+
const o = sessionOptions(ctx.values);
|
|
40
|
+
const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
|
|
41
|
+
if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
|
|
42
|
+
return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
|
|
43
|
+
}
|
|
44
|
+
const out = typeof ctx.values.out === 'string' ? ctx.values.out : undefined;
|
|
45
|
+
const roi = typeof ctx.values.roi === 'string'
|
|
46
|
+
? ctx.values.roi.split(',').map((x) => Number(String(x).trim()))
|
|
47
|
+
: undefined;
|
|
48
|
+
if (roi && (roi.length !== 4 || roi.some((n) => !Number.isFinite(n)))) {
|
|
49
|
+
return fail('BAD_ARGUMENTS', '--roi 需要 4 个数字:x,y,w,h(控制器分辨率坐标)', undefined, EXIT.USAGE);
|
|
50
|
+
}
|
|
51
|
+
/* 上限/阈值必须**显式拒绝**非法值,不能靠 daemon 的 `> 0` 守卫悄悄换回默认——
|
|
52
|
+
* `--som-limit 0` 被静默当成 30 时,调用方以为"不限量",拿到的是截断表。 */
|
|
53
|
+
const somLimitRaw = ctx.values['som-limit'];
|
|
54
|
+
const somLimit = typeof somLimitRaw === 'string' ? Number(somLimitRaw) : undefined;
|
|
55
|
+
if (somLimitRaw !== undefined && (!Number.isFinite(somLimit) || somLimit <= 0)) {
|
|
56
|
+
return fail('BAD_ARGUMENTS', '--som-limit 必须是正整数(收到 ' + JSON.stringify(somLimitRaw) + ')'
|
|
57
|
+
+ ';0 不等于"不限量"', undefined, EXIT.USAGE);
|
|
58
|
+
}
|
|
59
|
+
const ratioRaw = ctx.values['som-max-area-ratio'];
|
|
60
|
+
const ratio = typeof ratioRaw === 'string' ? Number(ratioRaw) : undefined;
|
|
61
|
+
if (ratioRaw !== undefined && (!Number.isFinite(ratio) || ratio <= 0 || ratio >= 1)) {
|
|
62
|
+
return fail('BAD_ARGUMENTS', '--som-max-area-ratio 要在 (0,1) 之间(画面面积比,收到 ' + JSON.stringify(ratioRaw) + ')'
|
|
63
|
+
+ ';0 不等于"关闭剔除"', undefined, EXIT.USAGE);
|
|
64
|
+
}
|
|
65
|
+
const fromKf = typeof ctx.values['from-kf'] === 'string' ? ctx.values['from-kf'] : undefined;
|
|
66
|
+
if (fromKf !== undefined && seq !== undefined) {
|
|
67
|
+
return fail('BAD_ARGUMENTS', '--from-kf 与 --seq 互斥:前者在库内留存帧上跑,后者在本会话缓冲帧上跑', '取库里有哪些帧:maafw-live kf list', EXIT.USAGE);
|
|
68
|
+
}
|
|
69
|
+
/* 库帧来源:先走离线读侧解析(契约 §4.1),daemon 只接身份与路径 */
|
|
70
|
+
let kfSource;
|
|
71
|
+
if (fromKf !== undefined) {
|
|
72
|
+
const dir = typeof ctx.values['frames-dir'] === 'string' ? ctx.values['frames-dir'] : defaultFramesDir();
|
|
73
|
+
const r = resolveFrame(dir, fromKf);
|
|
74
|
+
if (r.status !== 'available' || !r.path || !r.record) {
|
|
75
|
+
const code = r.status === 'corrupt' ? 'KF_CORRUPT' : (r.status === 'unsupported' ? 'KF_UNSUPPORTED' : 'KF_MISSING');
|
|
76
|
+
return fail(code, '库帧不可用(' + r.status + '):' + String(r.reason ?? '') + '(库 ' + dir + ')', 'kf list 看库内有哪些帧;missing 表示本机不可复核,不代表历史从未观测', EXIT.FINDINGS);
|
|
77
|
+
}
|
|
78
|
+
const rec = r.record;
|
|
79
|
+
kfSource = {
|
|
80
|
+
id: rec.id, path: r.path, sha256: rec.sha256, ctrlW: rec.ctrlW, ctrlH: rec.ctrlH,
|
|
81
|
+
captureSeq: rec.captureSeq, capturedAt: rec.capturedAt,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const offline = kfSource !== undefined;
|
|
85
|
+
try {
|
|
86
|
+
return await withDaemon(async (client) => {
|
|
87
|
+
const s = offline ? { connected: false } : await ensureSession(client, o);
|
|
88
|
+
let resourceDir = (typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined)
|
|
89
|
+
?? s.plan?.resource?.paths[0];
|
|
90
|
+
if (!resourceDir && offline && o.project) {
|
|
91
|
+
/* 离线:项目只作资源的来源(OCR 模型),不扫设备不连接 */
|
|
92
|
+
const off = offlineResource(o.project, o.controller, o.resource);
|
|
93
|
+
if (off.error) {
|
|
94
|
+
return fail('PLAN_FAILED', '离线解析项目资源失败:' + off.error, '也可以直接给 --resource-dir <dir>', EXIT.FINDINGS);
|
|
95
|
+
}
|
|
96
|
+
resourceDir = off.paths[0];
|
|
97
|
+
}
|
|
98
|
+
/* 一次性命令缓冲为空:先截一帧(用完即删,不留临时文件)。库帧路径不截帧——源已固定。 */
|
|
99
|
+
if (!offline && seq === undefined) {
|
|
100
|
+
await seedObservation(client, 'annotate');
|
|
101
|
+
}
|
|
102
|
+
const r = await annotate(client, {
|
|
103
|
+
...(offline ? { kfSource } : {}),
|
|
104
|
+
...(!offline && seq !== undefined ? { seq } : {}),
|
|
105
|
+
...(out ? { out } : {}),
|
|
106
|
+
...(resourceDir ? { resourceDir } : {}),
|
|
107
|
+
...(roi ? { roi } : {}),
|
|
108
|
+
...(somLimit !== undefined ? { somLimit } : {}),
|
|
109
|
+
...(ratio !== undefined ? { somMaxAreaRatio: ratio } : {}),
|
|
110
|
+
});
|
|
111
|
+
if (r.ok === false) {
|
|
112
|
+
return fail('ANNOTATE', String(r.error ?? '候选生成失败'), offline
|
|
113
|
+
? '库帧候选失败通常是文件被改动或库记录不一致;kf resolve 可复核'
|
|
114
|
+
: '需要观测:REPL 里先 screencap / stream start;一次性命令会自动截一帧', EXIT.FINDINGS);
|
|
115
|
+
}
|
|
116
|
+
const cands = r.candidates ?? [];
|
|
117
|
+
const sources = r.sources;
|
|
118
|
+
const src = r.source;
|
|
119
|
+
const unavailable = r.sourcesUnavailable;
|
|
120
|
+
const ctrl = Array.isArray(r.ctrl) ? r.ctrl : null;
|
|
121
|
+
const avail = r.availability;
|
|
122
|
+
const srcLine = src?.kind === 'kf'
|
|
123
|
+
? '源帧 ' + String(src.id) + '(留存帧,捕获 seq=' + String(src.captureSeq) + ',' +
|
|
124
|
+
String(ctrl?.[0] ?? '?') + 'x' + String(ctrl?.[1] ?? '?') + ',离线)'
|
|
125
|
+
: '源帧 seq=' + String(r.seq) + '(小图 ' + JSON.stringify(r.small) + ' × ctrl ' + JSON.stringify(r.ctrl) + ')';
|
|
126
|
+
/* 可用性三列:**"看起来有结果"不等于"有结果"**。截断/剔除/分带一起读,
|
|
127
|
+
* 才分得清"这一带没东西"与"这一带的东西被上限或门槛拿掉了"。 */
|
|
128
|
+
const availLines = avail
|
|
129
|
+
? [
|
|
130
|
+
' 可用性:合并池 ' + String(avail.mergedTotal ?? '?') + ' → 进表 ' + String(r.count)
|
|
131
|
+
+ '(上限 ' + String(avail.limit ?? '?') + ',截断 ' + String(avail.truncated ?? 0) + ')'
|
|
132
|
+
+ ';剔除 太小 ' + String(avail.dropped?.tooSmall ?? 0) + ' / 巨框 ' + String(avail.dropped?.tooBig ?? 0)
|
|
133
|
+
+ '(阈值 ' + String(avail.maxAreaRatio ?? '?') + ')/ 重复 ' + String(avail.dropped?.duplicated ?? 0),
|
|
134
|
+
...(avail.byBand ? [' 分带(上/中/下):' + avail.byBand.map((b) => String(b.inTable) + '/' + String(b.inPool)).join(' ')] : []),
|
|
135
|
+
...(avail.outResolution ? [' 回画分辨率:' + String(avail.outResolution.w) + 'x' + String(avail.outResolution.h)
|
|
136
|
+
+ '(' + String(avail.outResolution.source) + ')'] : []),
|
|
137
|
+
...(avail.detectionResolution ? [' 检测面分辨率:' + String(avail.detectionResolution.w) + 'x'
|
|
138
|
+
+ String(avail.detectionResolution.h) + '(' + String(avail.detectionResolution.source)
|
|
139
|
+
+ ')——检测面越小,小目标越可能探不到'] : []),
|
|
140
|
+
]
|
|
141
|
+
: [];
|
|
142
|
+
return {
|
|
143
|
+
exitCode: EXIT.OK,
|
|
144
|
+
human: [
|
|
145
|
+
...describeSession(s),
|
|
146
|
+
...(offline ? ['离线候选:未连接设备(库帧是本机持久文件)'] : []),
|
|
147
|
+
'SoM 候选 ' + String(r.count) + ' 个(ocr ' + String(sources?.ocr ?? 0) + ' / diff ' + String(sources?.diff ?? 0) +
|
|
148
|
+
' / conn ' + String(sources?.conn ?? 0) + ' / edge ' + String(sources?.edge ?? 0) + ')→ ' + String(r.out),
|
|
149
|
+
' ' + srcLine,
|
|
150
|
+
...availLines,
|
|
151
|
+
...(unavailable ? Object.entries(unavailable).map(([k, v]) => ' ' + k + ' 源不可用:' + v) : []),
|
|
152
|
+
' 坐标为控制器分辨率(面积占比供排序:越小越像小按钮,越大越像面板/背景):',
|
|
153
|
+
...cands.map((c) => ' #' + c.id + ' [' + c.source + '] ctrl=' + c.ctrl.join(',')
|
|
154
|
+
+ (typeof c.areaRatio === 'number' ? ' 面积比=' + c.areaRatio : '')
|
|
155
|
+
+ (typeof c.score === 'number' ? ' score=' + c.score : '')
|
|
156
|
+
+ (c.text ? ' "' + c.text + '"' : '')),
|
|
157
|
+
...(r.warn ? [' 警告:' + String(r.warn)] : []),
|
|
158
|
+
'选号后:click / reco --node(roi 用 ctrl 坐标)/ crop --roi(可再 crop --from-kf 于同一帧)',
|
|
159
|
+
],
|
|
160
|
+
data: r,
|
|
161
|
+
warnings: r.warn ? [String(r.warn)] : [],
|
|
162
|
+
written: [String(r.out)],
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
return daemonFail(e);
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
export const ANNOTATE_COMMANDS = [annotateCommand];
|
|
172
|
+
//# sourceMappingURL=annotate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotate.js","sourceRoot":"","sources":["../../src/commands/annotate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 变化检测阈值校准:静止画面采帧,统计分块亮度差 / 全局位差率的噪声分布,
|
|
3
|
+
* 推荐 blockThresh / changeGlobal。校准期间画面必须静止(max≫p99 会警告重跑)。
|
|
4
|
+
*/
|
|
5
|
+
import { EXIT, fail } from '../protocol.js';
|
|
6
|
+
import { calibrate, withDaemon } from '../runtime/actions.js';
|
|
7
|
+
import { describeSession, ensureSession } from '../runtime/session.js';
|
|
8
|
+
import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
|
|
9
|
+
export const calibrateCommand = {
|
|
10
|
+
name: 'calibrate',
|
|
11
|
+
summary: '变化检测阈值校准:静止画面采帧定噪声地板,推荐 blockThresh / changeGlobal',
|
|
12
|
+
usage: 'maafw-live calibrate [--frames n] [--interval ms] --project <dir>|--kind ...\n' +
|
|
13
|
+
' 采集期间保持画面静止;结果给出可直接粘贴的 stream start 参数',
|
|
14
|
+
options: { ...CONNECT_OPTIONS, frames: { type: 'string' }, interval: { type: 'string' } },
|
|
15
|
+
async run(ctx) {
|
|
16
|
+
const o = sessionOptions(ctx.values);
|
|
17
|
+
if (!o.project && !o.kind) {
|
|
18
|
+
return fail('BAD_ARGUMENTS', '校准要设备:给 --project <dir>(推荐)或 --kind win32|adb|gamepad', undefined, EXIT.USAGE);
|
|
19
|
+
}
|
|
20
|
+
const frames = typeof ctx.values.frames === 'string' ? Number(ctx.values.frames) : undefined;
|
|
21
|
+
if (frames !== undefined && !Number.isFinite(frames)) {
|
|
22
|
+
return fail('BAD_ARGUMENTS', '--frames 必须是数字(6..60,默认 24)', undefined, EXIT.USAGE);
|
|
23
|
+
}
|
|
24
|
+
const interval = typeof ctx.values.interval === 'string' ? Number(ctx.values.interval) : undefined;
|
|
25
|
+
if (interval !== undefined && !Number.isFinite(interval)) {
|
|
26
|
+
return fail('BAD_ARGUMENTS', '--interval 必须是毫秒数(默认 300)', undefined, EXIT.USAGE);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return await withDaemon(async (client) => {
|
|
30
|
+
const s = await ensureSession(client, o);
|
|
31
|
+
const r = await calibrate(client, {
|
|
32
|
+
...(frames !== undefined ? { frames } : {}),
|
|
33
|
+
...(interval !== undefined ? { interval } : {}),
|
|
34
|
+
});
|
|
35
|
+
if (r.ok === false) {
|
|
36
|
+
return fail('CALIBRATE', String(r.error ?? '校准失败'), undefined, EXIT.FINDINGS);
|
|
37
|
+
}
|
|
38
|
+
const block = r.block;
|
|
39
|
+
const global = r.global;
|
|
40
|
+
return {
|
|
41
|
+
exitCode: r.warn ? EXIT.FINDINGS : EXIT.OK,
|
|
42
|
+
human: [
|
|
43
|
+
...describeSession(s),
|
|
44
|
+
'校准 ' + String(r.frames) + ' 帧(分块亮度差 / 全局位差率的噪声分布):',
|
|
45
|
+
' 分块差 p50=' + block.p50 + ' p99=' + block.p99 + ' max=' + block.max,
|
|
46
|
+
' 位差率 p50=' + global.p50 + ' p99=' + global.p99 + ' max=' + global.max,
|
|
47
|
+
' 推荐:' + String(r.apply),
|
|
48
|
+
...(r.warn ? [' 警告:' + String(r.warn)] : []),
|
|
49
|
+
],
|
|
50
|
+
data: r,
|
|
51
|
+
...(r.warn ? { warnings: [String(r.warn)] } : {}),
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
return daemonFail(e);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
export const CALIBRATE_COMMANDS = [calibrateCommand];
|
|
61
|
+
//# sourceMappingURL=calibrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calibrate.js","sourceRoot":"","sources":["../../src/commands/calibrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 探色命令:ROI 实测主色/均值(RGB/HSV/灰度)——模型只选色不报色值。
|
|
3
|
+
*
|
|
4
|
+
* 为什么不靠模型读像素:色值必须来自实测(降采样小图按该帧捕获尺寸换算后的 ROI),
|
|
5
|
+
* 模型选完色后用 reco ColorMatch 出框(走已修好的参数透传链),出框与否是事实不是判断。
|
|
6
|
+
*/
|
|
7
|
+
import { EXIT, fail } from '../protocol.js';
|
|
8
|
+
import { colorProbe, seedObservation, withDaemon } from '../runtime/actions.js';
|
|
9
|
+
import { describeSession, ensureSession } from '../runtime/session.js';
|
|
10
|
+
import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
|
|
11
|
+
export const colorCommand = {
|
|
12
|
+
name: 'color',
|
|
13
|
+
summary: '探色:ROI 实测均值/HSV/主色(控制器分辨率坐标;选中后用 reco ColorMatch 出框)',
|
|
14
|
+
usage: 'maafw-live color [--roi x,y,w,h] [--seq n] --project <dir>|--kind ...\n' +
|
|
15
|
+
' 一次性命令先自动截一帧再测;REPL 里测缓冲最新帧(先 screencap / stream)',
|
|
16
|
+
options: { ...CONNECT_OPTIONS, roi: { type: 'string' }, seq: { type: 'string' } },
|
|
17
|
+
async run(ctx) {
|
|
18
|
+
const o = sessionOptions(ctx.values);
|
|
19
|
+
if (!o.project && !o.kind) {
|
|
20
|
+
return fail('BAD_ARGUMENTS', '要设备才能探色:给 --project <dir>(推荐)或 --kind win32|adb|gamepad', '多步操作用 maafw-live repl(连接一次后连续观测)', EXIT.USAGE);
|
|
21
|
+
}
|
|
22
|
+
const roi = typeof ctx.values.roi === 'string'
|
|
23
|
+
? ctx.values.roi.split(',').map((x) => Number(String(x).trim()))
|
|
24
|
+
: undefined;
|
|
25
|
+
if (roi && (roi.length !== 4 || roi.some((n) => !Number.isFinite(n)))) {
|
|
26
|
+
return fail('BAD_ARGUMENTS', '--roi 需要 4 个数字:x,y,w,h(控制器分辨率坐标,与 pipeline 的 roi 同空间)', undefined, EXIT.USAGE);
|
|
27
|
+
}
|
|
28
|
+
const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
|
|
29
|
+
if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
|
|
30
|
+
return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
return await withDaemon(async (client) => {
|
|
34
|
+
const s = await ensureSession(client, o);
|
|
35
|
+
/* 一次性命令缓冲为空:先截一帧产生观测(screencap 现在进环,有捕获身份)。
|
|
36
|
+
* 截帧文件用完即删——它只是观测载体,既不落用户 cwd,也不留在临时目录。 */
|
|
37
|
+
if (seq === undefined) {
|
|
38
|
+
await seedObservation(client, 'color');
|
|
39
|
+
}
|
|
40
|
+
const r = await colorProbe(client, {
|
|
41
|
+
...(seq !== undefined ? { seq } : {}),
|
|
42
|
+
...(roi ? { roi } : {}),
|
|
43
|
+
});
|
|
44
|
+
if (r.ok === false) {
|
|
45
|
+
return fail('COLOR_PROBE', String(r.error ?? '探色失败'), 'REPL 里先 screencap 或 stream start;一次性命令会自动截一帧', EXIT.FINDINGS);
|
|
46
|
+
}
|
|
47
|
+
const mean = r.mean;
|
|
48
|
+
const hsv = r.hsv;
|
|
49
|
+
const dom = r.dominant;
|
|
50
|
+
return {
|
|
51
|
+
exitCode: EXIT.OK,
|
|
52
|
+
human: [
|
|
53
|
+
...describeSession(s),
|
|
54
|
+
'探色 seq=' + String(r.seq) + (roi ? ' roi=' + roi.join(',') : ' (整帧)'),
|
|
55
|
+
' 均值 RGB ' + mean.r + ',' + mean.g + ',' + mean.b + ' 灰度 ' + mean.gray +
|
|
56
|
+
' HSV ' + hsv.h + '°,' + hsv.s + '%,' + hsv.v + '%',
|
|
57
|
+
' 主色 RGB ' + dom.rgb.join(',') + '(覆盖 ' + Math.round(dom.ratio * 100) + '%)',
|
|
58
|
+
'出框验证:maafw-live reco --type ColorMatch --param \'{"color":[' + dom.rgb.join(',') + '],"threshold":0.05}\' …',
|
|
59
|
+
],
|
|
60
|
+
data: r,
|
|
61
|
+
suggestedCommands: [
|
|
62
|
+
'maafw-live reco --type ColorMatch --param \'{"color":[' + dom.rgb.join(',') + '],"threshold":0.05}\' --image <png> --resource-dir <dir>',
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
return daemonFail(e);
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
export const COLOR_COMMANDS = [colorCommand];
|
|
73
|
+
//# sourceMappingURL=color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/commands/color.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模板裁剪:低精度输入(宽松框或点+外扩)→ snap 收紧 → 从源帧原图裁剪 →
|
|
3
|
+
* 同帧自匹配逐边重试取得分最高边界。
|
|
4
|
+
*
|
|
5
|
+
* 关键约束:模板尺寸必须与识别空间一致——只从控制器分辨率的完整原图裁,
|
|
6
|
+
* 不从降采样小图裁。点→ROI 派生与裁剪共享同一条 snap 链(roadmap 条目4/5)。
|
|
7
|
+
*
|
|
8
|
+
* 源帧两条路:
|
|
9
|
+
* - L0 热缓存(缺省):进程态,seq 或最新;跨帧验证缺省开(新帧再匹配一次)。
|
|
10
|
+
* - 关键帧库留存帧(--from-kf):库内 L0 文件,跨会话可用、**不需要设备**——
|
|
11
|
+
* 不可复现状态的动线正是这条(捕获它的那次会话早已结束)。跨帧验证缺省关:
|
|
12
|
+
* 留存帧对应的状态通常已不在画面上,拿当前帧比只会得到假警告。
|
|
13
|
+
*
|
|
14
|
+
* 裁出的 PNG 是 L2 派生图(契约 §2),旁边写 `<out>.prov.json` 出处记录
|
|
15
|
+
* (契约 §5:L2 记录来源及裁剪 / 缩放变换)——出处与模板同生共死,可一起提交进仓库。
|
|
16
|
+
*/
|
|
17
|
+
import { defaultFramesDir, resolveFrame } from '../runtime/keyframes.js';
|
|
18
|
+
import { EXIT, fail } from '../protocol.js';
|
|
19
|
+
import { seedObservation, tplCrop, withDaemon } from '../runtime/actions.js';
|
|
20
|
+
import { describeSession, ensureSession, offlineResource } from '../runtime/session.js';
|
|
21
|
+
import { CONNECT_OPTIONS, daemonFail, sessionOptions } from './runtime.js';
|
|
22
|
+
function nums(raw, count, what) {
|
|
23
|
+
if (raw === undefined)
|
|
24
|
+
return undefined;
|
|
25
|
+
const v = raw.split(',').map((x) => Number(String(x).trim()));
|
|
26
|
+
if (v.length !== count || v.some((n) => !Number.isFinite(n))) {
|
|
27
|
+
throw new Error(what + ' 需要 ' + count + ' 个数字');
|
|
28
|
+
}
|
|
29
|
+
return v;
|
|
30
|
+
}
|
|
31
|
+
/** 库里解析出来的帧 → daemon 的裁剪源(身份与路径;daemon 会复核 sha256 与像素尺寸)。 */
|
|
32
|
+
function kfSourceOf(r) {
|
|
33
|
+
const rec = r.record;
|
|
34
|
+
return {
|
|
35
|
+
id: rec.id,
|
|
36
|
+
path: String(r.path),
|
|
37
|
+
sha256: rec.sha256,
|
|
38
|
+
ctrlW: rec.ctrlW,
|
|
39
|
+
ctrlH: rec.ctrlH,
|
|
40
|
+
captureSeq: rec.captureSeq,
|
|
41
|
+
capturedAt: rec.capturedAt,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export const cropCommand = {
|
|
45
|
+
name: 'crop',
|
|
46
|
+
summary: '模板裁剪:宽松框/点 → snap 收紧 → 原图裁剪 → 自匹配验证(源可为 L0 热缓存或关键帧库留存帧)',
|
|
47
|
+
usage: 'maafw-live crop --roi x,y,w,h | --point x,y [--pad n] [--seq n] [--out <png>] [--no-cross] --project <dir>|--kind ...\n' +
|
|
48
|
+
' maafw-live crop --from-kf <kf:库UUID:序号> --roi x,y,w,h [--frames-dir <dir>] [--resource-dir <dir> | --project <dir>] [--cross]\n' +
|
|
49
|
+
' 源帧缺省是 L0 最新原图(screencap/stream/输入都会产生);连接真机时自动做跨帧验证(新帧再匹配一次)\n' +
|
|
50
|
+
' --from-kf 改从关键帧库留存帧裁:离线可用(不需要设备),跨帧验证缺省关(留存帧对应的状态通常已不在画面上)\n' +
|
|
51
|
+
' 裁出的 PNG 是 L2 派生图,旁边写 <out>.prov.json 出处记录(来源 + 裁剪变换;--no-prov 可关)\n' +
|
|
52
|
+
' --keep-source 顺手把本次裁剪用的那一帧升格进关键帧库,出处随即带上可复核的 kf: 身份\n' +
|
|
53
|
+
' (契约的模型是 L0 缓存 → 选择性升格 → 从库帧裁;少了这步,出处只剩一个随进程消失的 seq)\n' +
|
|
54
|
+
' --prov-out <dir> 把出处写到该目录下(同名),用于模板要进资源包、而资源包只装框架要加载的东西:\n' +
|
|
55
|
+
' 约定不变量是"同一相对路径"(如 state-plan/provenance/ 与 image/ 同构)',
|
|
56
|
+
options: {
|
|
57
|
+
...CONNECT_OPTIONS,
|
|
58
|
+
roi: { type: 'string' },
|
|
59
|
+
point: { type: 'string' },
|
|
60
|
+
pad: { type: 'string' },
|
|
61
|
+
seq: { type: 'string' },
|
|
62
|
+
out: { type: 'string' },
|
|
63
|
+
'resource-dir': { type: 'string' },
|
|
64
|
+
'no-cross': { type: 'boolean' },
|
|
65
|
+
'from-kf': { type: 'string' },
|
|
66
|
+
'frames-dir': { type: 'string' },
|
|
67
|
+
cross: { type: 'boolean' },
|
|
68
|
+
'no-prov': { type: 'boolean' },
|
|
69
|
+
'prov-out': { type: 'string' },
|
|
70
|
+
'keep-source': { type: 'boolean' },
|
|
71
|
+
},
|
|
72
|
+
async run(ctx) {
|
|
73
|
+
const o = sessionOptions(ctx.values);
|
|
74
|
+
let roi;
|
|
75
|
+
let point;
|
|
76
|
+
try {
|
|
77
|
+
roi = nums(typeof ctx.values.roi === 'string' ? ctx.values.roi : undefined, 4, '--roi');
|
|
78
|
+
point = nums(typeof ctx.values.point === 'string' ? ctx.values.point : undefined, 2, '--point');
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
return fail('BAD_ARGUMENTS', e.message, undefined, EXIT.USAGE);
|
|
82
|
+
}
|
|
83
|
+
if (!roi && !point) {
|
|
84
|
+
return fail('BAD_ARGUMENTS', '给 --roi x,y,w,h(宽松框)或 --point x,y(自动外扩成宽松框)', undefined, EXIT.USAGE);
|
|
85
|
+
}
|
|
86
|
+
const seq = typeof ctx.values.seq === 'string' ? Number(ctx.values.seq) : undefined;
|
|
87
|
+
if (ctx.values.seq !== undefined && !Number.isFinite(seq)) {
|
|
88
|
+
return fail('BAD_ARGUMENTS', '--seq 必须是数字', undefined, EXIT.USAGE);
|
|
89
|
+
}
|
|
90
|
+
const pad = typeof ctx.values.pad === 'string' ? Number(ctx.values.pad) : undefined;
|
|
91
|
+
if (pad !== undefined && !Number.isFinite(pad)) {
|
|
92
|
+
return fail('BAD_ARGUMENTS', '--pad 必须是数字(点→ROI 外扩半径,默认 24)', undefined, EXIT.USAGE);
|
|
93
|
+
}
|
|
94
|
+
const out = typeof ctx.values.out === 'string' ? ctx.values.out : undefined;
|
|
95
|
+
const fromKf = typeof ctx.values['from-kf'] === 'string' ? ctx.values['from-kf'] : undefined;
|
|
96
|
+
if (fromKf !== undefined && seq !== undefined) {
|
|
97
|
+
return fail('BAD_ARGUMENTS', '--from-kf 与 --seq 互斥:前者从库内留存帧裁,后者从本会话 L0 热缓存裁', '取库里有哪些帧:maafw-live kf list', EXIT.USAGE);
|
|
98
|
+
}
|
|
99
|
+
if (fromKf !== undefined && ctx.values.cross === true && ctx.values['no-cross'] === true) {
|
|
100
|
+
return fail('BAD_ARGUMENTS', '--cross 与 --no-cross 互斥', undefined, EXIT.USAGE);
|
|
101
|
+
}
|
|
102
|
+
/* 库帧来源:先走离线读侧解析(契约 §4.1),daemon 只接身份与路径——
|
|
103
|
+
* 解析失败就在这一层如实报,不把不可复核的帧送进裁剪。 */
|
|
104
|
+
let kfSource;
|
|
105
|
+
if (fromKf !== undefined) {
|
|
106
|
+
const dir = typeof ctx.values['frames-dir'] === 'string' ? ctx.values['frames-dir'] : defaultFramesDir();
|
|
107
|
+
const r = resolveFrame(dir, fromKf);
|
|
108
|
+
if (r.status !== 'available' || !r.path || !r.record) {
|
|
109
|
+
const code = r.status === 'corrupt' ? 'KF_CORRUPT' : (r.status === 'unsupported' ? 'KF_UNSUPPORTED' : 'KF_MISSING');
|
|
110
|
+
return fail(code, '库帧不可用(' + r.status + '):' + String(r.reason ?? '') + '(库 ' + dir + ')', 'kf list 看库内有哪些帧;missing 表示本机不可复核,不代表历史从未观测', EXIT.FINDINGS);
|
|
111
|
+
}
|
|
112
|
+
kfSource = kfSourceOf(r);
|
|
113
|
+
}
|
|
114
|
+
const wantCross = ctx.values.cross === true;
|
|
115
|
+
/* 库帧路径默认离线:留存帧是本机持久文件,裁剪不需要设备。要跨帧验证才连。 */
|
|
116
|
+
const offline = kfSource !== undefined && !wantCross;
|
|
117
|
+
if (kfSource !== undefined && wantCross && !o.project && !o.kind) {
|
|
118
|
+
return fail('BAD_ARGUMENTS', '--cross 需要连接设备:给 --project <dir> 或 --kind', '不留 --cross 就是纯离线裁剪(留存帧的价值所在)', EXIT.USAGE);
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
return await withDaemon(async (client) => {
|
|
122
|
+
const s = offline ? { connected: false } : await ensureSession(client, o);
|
|
123
|
+
/* 自匹配要加载资源(模板走 override_image,不写项目目录);项目模式用规划出的资源 */
|
|
124
|
+
let resourceDir = (typeof ctx.values['resource-dir'] === 'string' ? ctx.values['resource-dir'] : undefined)
|
|
125
|
+
?? s.plan?.resource?.paths[0];
|
|
126
|
+
if (!resourceDir && offline && o.project) {
|
|
127
|
+
/* 离线:项目只是资源的来源,不是连接的对象——只读 interface.json,不扫设备 */
|
|
128
|
+
const off = offlineResource(o.project, o.controller, o.resource);
|
|
129
|
+
if (off.error) {
|
|
130
|
+
return fail('PLAN_FAILED', '离线解析项目资源失败:' + off.error, '也可以直接给 --resource-dir <dir>', EXIT.FINDINGS);
|
|
131
|
+
}
|
|
132
|
+
resourceDir = off.paths[0];
|
|
133
|
+
}
|
|
134
|
+
if (!resourceDir) {
|
|
135
|
+
return fail('BAD_ARGUMENTS', '自匹配需要资源目录:给 --resource-dir <dir> 或 --project <dir>', undefined, EXIT.USAGE);
|
|
136
|
+
}
|
|
137
|
+
/* L0 是进程态:一次性命令先截一帧产生观测(截帧文件用完即删,不落用户 cwd、也不留在临时目录)。
|
|
138
|
+
* 库帧路径不截帧——源已经固定,重截只会拿到另一个时刻。 */
|
|
139
|
+
if (kfSource === undefined && seq === undefined) {
|
|
140
|
+
await seedObservation(client, 'crop');
|
|
141
|
+
}
|
|
142
|
+
const r = await tplCrop(client, {
|
|
143
|
+
...(roi ? { roi } : {}),
|
|
144
|
+
...(point ? { point } : {}),
|
|
145
|
+
...(pad !== undefined ? { pad } : {}),
|
|
146
|
+
...(kfSource === undefined && seq !== undefined ? { seq } : {}),
|
|
147
|
+
...(kfSource ? { kfSource } : {}),
|
|
148
|
+
...(out ? { out } : {}),
|
|
149
|
+
resourceDir,
|
|
150
|
+
/* 跨帧验证缺省:热缓存路径交给 daemon 判(连接着就做);库帧路径显式关,--cross 才做 */
|
|
151
|
+
...(kfSource !== undefined && !wantCross ? { cross: false } : (wantCross ? { cross: true } : {})),
|
|
152
|
+
...(ctx.values['no-cross'] === true ? { cross: false } : {}),
|
|
153
|
+
...(ctx.values['no-prov'] === true ? { prov: false } : {}),
|
|
154
|
+
...(typeof ctx.values['prov-out'] === 'string' && ctx.values['prov-out']
|
|
155
|
+
? { provOut: ctx.values['prov-out'] }
|
|
156
|
+
: {}),
|
|
157
|
+
...(ctx.values['keep-source'] === true ? { keepSource: true } : {}),
|
|
158
|
+
});
|
|
159
|
+
if (r.ok === false) {
|
|
160
|
+
return fail('TPL_CROP', String(r.error ?? '裁剪失败'), kfSource ? '库帧裁剪失败通常是文件被改动或库记录不一致;kf resolve 可复核' : '源帧取 L0 最新原图:先 screencap / stream / 输入产生观测', EXIT.FINDINGS);
|
|
161
|
+
}
|
|
162
|
+
const box = r.box;
|
|
163
|
+
const src = r.source;
|
|
164
|
+
const cross = r.cross;
|
|
165
|
+
/* 贴合度信号:宽松框 → 最终框的几何对比(得分那一路分辨不出贴合度:三种窗口自匹配都是 1.0) */
|
|
166
|
+
const tg = r.tighten;
|
|
167
|
+
const space = r.spaceCheck;
|
|
168
|
+
const srcLine = src && src.kind === 'kf'
|
|
169
|
+
? '源帧 ' + String(src.id) + '(留存帧,捕获 seq=' + String(src.captureSeq) + ',' +
|
|
170
|
+
String(src.ctrlW) + 'x' + String(src.ctrlH) + ',sha ' + String(src.sha256).slice(0, 12) + ')'
|
|
171
|
+
: '源帧 seq=' + String(r.seq) + '(' + String(r.ctrlW) + 'x' + String(r.ctrlH) + ',L0 热缓存)';
|
|
172
|
+
const spaceLine = space && space.current
|
|
173
|
+
? ' 空间核对:源 ' + String(r.ctrlW) + 'x' + String(r.ctrlH) + (space.match ? ' = ' : ' ≠ ') +
|
|
174
|
+
'当前控制器 ' + space.current.w + 'x' + space.current.h
|
|
175
|
+
: ' 空间核对:未连接设备,未与当前控制器尺寸比对(模板空间 = 源帧捕获时尺寸 ' +
|
|
176
|
+
String(r.ctrlW) + 'x' + String(r.ctrlH) + ')';
|
|
177
|
+
const human = [
|
|
178
|
+
...describeSession(s),
|
|
179
|
+
...(offline ? ['离线裁剪:未连接设备(留存帧是本机持久文件,裁剪不需要设备)'] : []),
|
|
180
|
+
'模板 ' + String(r.w) + 'x' + String(r.h) + ' → ' + String(r.path),
|
|
181
|
+
' ' + srcLine,
|
|
182
|
+
' 宽松框 ' + JSON.stringify(r.loose) + ' → 收紧 ' + JSON.stringify(box) +
|
|
183
|
+
(tg?.from && tg?.to
|
|
184
|
+
? '(' + tg.from.join('×') + ' → ' + tg.to.join('×') +
|
|
185
|
+
(tg.areaRatio !== null && tg.areaRatio !== undefined ? ',面积 ' + tg.areaRatio + '×' : '') +
|
|
186
|
+
(tg.grew ? ',反而放大' : '') + ')'
|
|
187
|
+
: '') +
|
|
188
|
+
(tg?.looseMatch
|
|
189
|
+
? ';宽松框自匹配 ' + tg.looseMatch.score + (tg.looseMatch.positionOk ? '(位置正确,说明得分分辨不出贴合度)' : '(位置漂移)')
|
|
190
|
+
: '') +
|
|
191
|
+
(r.snapped ? '' : '(snap 无内容收紧,用原框)'),
|
|
192
|
+
' 自匹配 ' + (r.positionOk === false ? '位置错误(best 落在 ' + JSON.stringify(r.selfMatchBox ?? null) + ')' : '位置正确') +
|
|
193
|
+
',得分 ' + String(r.score) + '(' + String(r.tries) + ' 次评估)',
|
|
194
|
+
...(cross
|
|
195
|
+
? [' 跨帧验证 seq=' + String(cross.seq) + ':得分 ' + String(cross.score) +
|
|
196
|
+
(cross.posOk ? ',位置正确' : ',位置漂移 ' + JSON.stringify(cross.box ?? null))]
|
|
197
|
+
: [kfSource
|
|
198
|
+
? ' 跨帧验证:跳过(源为留存帧,它对应的状态通常已不在当前画面上;状态可复现时给 --cross)'
|
|
199
|
+
: (ctx.values['no-cross'] === true
|
|
200
|
+
? ' 跨帧验证:已按 --no-cross 关闭'
|
|
201
|
+
: ' 跨帧验证:未做(未连接设备)')]),
|
|
202
|
+
spaceLine,
|
|
203
|
+
...(r.provPath
|
|
204
|
+
? ['L2 出处:' + String(r.provPath) + '(来源 + 裁剪变换;随模板一起提交进仓库)']
|
|
205
|
+
: ['L2 出处:未写(--no-prov)']),
|
|
206
|
+
...(r.keptSource && r.keptSource.id
|
|
207
|
+
? ['源帧已留档:' + String(r.keptSource.id) + '(出处随之升级为可复核的 kf: 身份)']
|
|
208
|
+
: []),
|
|
209
|
+
...(r.warns ?? []).map((w) => ' 警告:' + w),
|
|
210
|
+
'pipeline 用法:roi ' + box.join(',') + ' + template 该文件(同帧验证:maafw-live reco --node …)',
|
|
211
|
+
];
|
|
212
|
+
const warns = r.warns ?? [];
|
|
213
|
+
return {
|
|
214
|
+
exitCode: warns.length ? EXIT.FINDINGS : EXIT.OK,
|
|
215
|
+
human,
|
|
216
|
+
data: r,
|
|
217
|
+
written: [String(r.path), ...(r.provPath ? [String(r.provPath)] : [])],
|
|
218
|
+
...(warns.length ? { warnings: warns } : {}),
|
|
219
|
+
};
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
return daemonFail(e);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
export const CROP_COMMANDS = [cropCommand];
|
|
228
|
+
//# sourceMappingURL=crop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.js","sourceRoot":"","sources":["../../src/commands/crop.ts"],"names":[],"mappings":"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"}
|