Vyntek 机器视觉验证与完善路线
规格 ID:TC020 — 稳定标识(页面改名/迁移不变),全站对照见设计规格索引。
实现边界:阶段退出条件未达成。公开头和 smoke 不是阶段完成。T15 只登记风险,不在本页扩做。 关联:toolgroup · test-contracts · examples-scenarios
Vyntek 机器视觉验证与完善路线
目标设计与 API 草案,尚未实施。总体边界和推进状态见设计概述。
编排权威见 toolgroup.mdx;成像专题只验收像素/句柄/显示/采集契约。
本文区分确认契约、待细化机制和尚未取得的证据,组织收敛与验收,不改写当前控件事实。
关联:概述 · Tool / ToolGroup(编排) · 头文件/打包 · 输出观察(T10;TC-OUT-) · 采集 / 会话(TC-ACQ- / TC-SESS-) · C# 绑定 · 模型 · 内存(TC-MEM-) · ImageDisplay(TC-DISP-;仅 C#) · 性能 · 示例场景规划(验收用例灵感,薄;含 S10 / S11 / S12 / S13) · 测试契约表(R4 · §10.1 全文可勾选;TC-OUT-;TC-ACQ-* / TC-SESS-;TC-MEM-;TC-DISP-*) · 伪仓库树(R5 · 示意对照,不可编译) · 宿主集成契约(R7 · headless/C# 同核) · 术语终检
当前确认与待细化边界
| 范围 | 已确认 | 仍需具体化或验证 |
|---|---|---|
| 图像模型 | 四格式、Info 合并、稳定 ReadOnly 与可写输出分离 | 泛型返回桥接的最小编译证据;工厂与外部适配边界 |
| 内存 | 独立引用、共享读/独占写、显式完成、pin 延寿;可勾选 TC-MEM-* / S12 | 初始根范围登记;权限/取消竞争;归还并发与容量预约(实现证据仍待;不把「归还变慢」perf 塞进本轮文档勾选) |
| ToolGroup | 顺序 Run、终端链接、T3–T7;T8 schema vs component_version + 缺属性→Validate;T9 停止矩阵;T13 §10.1↔测阶段映射;失败中止与禁用;不兼容 .vpp | 公共 API 落地;.avtg 读写;headless §9.1(fake);H1–H10;见 toolgroup.mdx §6.5 / §7.4.3 / §7.4.6 / §7.6 / §10.1 |
| 最近输出 | KeepLatest 与连接分离;T10 集合事件:EmptySnapshot / Unavailable / Evicted;失败保留上次成功;观察不驱动 Run;对外 ToolId;可勾选 TC-OUT-* / S10 | 订阅/重放与打开竞争的实现证据;UI 绑定另议 |
| 相机 | 可持帧则导入,否则回调内复制;可勾选 TC-ACQ-* / S11 | SDK 在 Stop/Close/断线时的地址保证、线程协议和池余量(实现证据) |
| 显示 | 直接接收图像,复制/保留/脱离分别确认;可勾选 TC-DISP-* / S13(仅 C#;≠ T15 R10) | 四格式后端能力、线性化/mip、上传成本及像素对照(实现证据仍待;不塞 perf KPI) |
| 性能 | 全链路有界,真实归还与任务完成分离 | 稳态内存、归还尾延迟、停流基线、故障和平台证据 |
开放项不能弱化确认契约。例如可评估编译期只读接口,但不能允许工具组改写已发布输入;某 SDK 不支持持帧时复制接入,不假设地址一直有效。
分阶段推进与退出条件
| 阶段 | 涉及专题 | 退出条件 |
|---|---|---|
| A. API 契约 | 图像模型、内存 | 最小声明可编译;格式、所有权、能力上限及错误类别一致 |
| B. 存储协调 | 内存;test-contracts TC-MEM-* / S12;诊断 | 初始化/恢复、最后引用、pin、取消/授予竞争及回调失败可验证;文档侧可勾选契约已收口(实现证据仍待;perf「归还变慢」不进本轮) |
| C. ToolGroup MVP 与成像交接 | ToolGroup、内存、会话 | 编排:§10.1 可勾选(注册→建组→Link/Validate→Run→Cancel/失败中止→Load 复载→H1–H10→fake;见 T13 映射);含 T8 缺属性 Validate、T9 停止矩阵;非目标:无边就绪调度器、无 VP、无脚本与产线 IO。成像侧按内存/会话验收 |
| D. 相机适配 | 采集、会话;test-contracts TC-ACQ-* / TC-SESS-* / S11 | 持帧/复制、SDK 满池、归还变慢、断线、排空与超时有证据;文档侧可勾选契约已收口(实现证据仍待) |
| E. 输出观察 | 动态调试(T10);test-contracts TC-OUT-* / S10 | 集合事件(含空快照)、Unavailable/Evicted、失败保留、动态连接、重放和查看者寿命一致;观察永不驱动 Run |
| F. 显示集成 | ImageDisplay、示例;test-contracts TC-DISP-* / S13(仅 C#;≠ T15 R10) | 四格式、ROI/负步长、取样、脱离、卸载/context 重建及失败保留;文档侧可勾选契约已收口(实现证据仍待) |
| G. 系统验收 | 全部专题 | 长时间负载/故障验证、平台说明、NativeAOT 和当前文档迁移 |
阶段可在文档和原型层交叉推进,集成不能绕过前置资源安全验证。本轮只完成文档组织与契约整理,没有接口原型、源码工程或运行验证。验收用例编排可参考 examples-scenarios.mdx(S01–S13)作灵感;全文可勾选契约见 test-contracts.mdx(R4;TC-OUT-;TC-ACQ- / TC-SESS-;TC-MEM-;TC-DISP-*),不以场景文代替 §10.1 / 契约表勾选正文。
:文档侧阶段 B–F(及编排侧 C 的契约/索引)已收口——除阶段 A 模型契约(图像模型最小编译证据仍待);实现证据另册。§10.1 T13 阶段索引已对齐 OUT/ACQ/SESS/MEM/DISP + S10–S13;不改 Diagnostic / T9 / toolgroup v1.9。T15 无 R13。
设计收敛时优先处理的问题
- 类型能力:当前格式接口仍暴露写申请,输入由 Access.ReadOnly 在运行时拒绝。评估编译期只读时同时考虑工厂、Clone、ShareImage 和泛型桥接,避免两套图像模型。
- 发布完整性:首次根范围、正常 ROI 改写与 Invalid 恢复有不同边界,需收敛到能验证的协调状态,不把 Complete 当成自动覆盖检测。
- 清理调度:接受 SDK 引用前预约归还容量;一个卡住的供应商回调不能阻塞其他存储。抽象、并发与关闭归属在实际 SDK 协议下验证。
- 集合观察(T10 已定):最近输出按调用集合更新;空成功 →
EmptySnapshot(禁止静默);保留失败 →Unavailable;淘汰 →Evicted;失败保留上次成功;对外 ToolId。实现证据与订阅竞争仍待验证;见 output-inspection.mdx。 - 配额口径:区分唯一分配、逻辑视图、SDK 槽、打开的调试引用和退休任务,明确预约、释放及故障成本。
正文在对应专题维护,本表只记录推进入口,不建立第二份 API。
ToolGroup 已定项与后续项(与 MVP 验收对齐)
| 项 | 定稿 | 归类 |
|---|---|---|
| 扩展名与顶层字段名 | .avtg;JSON 顶层字段保持 toolgroup §6.3 已定写法(schema_version/kind/meta/group),不来回改名;嵌套见 §6.6 | 已定 |
| TypeDesc / 属性路径 / Value(T3) | MVP 子集与可链接/提升/图像精确匹配;路径 tool_id.prop[.sub…] 无表达式;几何非第二图模型;名 TypeDesc | 已定 |
| Diagnostic(T4) | DiagnosticCode 闭集 + severity;Validate/Run/Load 结构化列表;对齐 toolgroup §7.4.6 / §10.1 | 已定 |
.avtg 嵌套 schema(T5) | 展开 group/tools/links/terminals;assets[]:kind:"golden_image"+path;可选 role/tool_id;像素不嵌入;component_version 可选不拦 Load | 已定 |
| 句柄交接对照(T6) | PixelImageHandle:Share/Complete/CompleteAndOpenRead/链接赋值/Clone 等;每条可测断言;ReadOnly 发布、已交下游不得改写、链接≠调度;见 toolgroup §3.4 / §10.1 | 已定 |
| Tool 作者契约与 fake(T7) | Run/属性袋/type id/失败语义;Registry 约定;MVP fake:FakeAcq/FakePMAlign/Passthrough/FailOnce 等;见 toolgroup §7.6 | 已定 |
| schema vs component + 缺属性(T8) | schema_version 过高→Load SchemaTooNew;component_version 可选不拦 Load;已知 type 缺必填属性→ Validate MissingRequiredProperty(无静默默认);未知 type 仍 UnknownTypeId;见 toolgroup §6.5 / §7.4.6 / §10.1 | 已定 |
| 停止矩阵(T9) | Cancel Run=协作式/Cancelled、不再启动后续 Tool;宿主停相机≠自动 Cancel 在途 Run;显示只观察不停编排;见 toolgroup §7.4.3 ↔ session-lifecycle | 已定 |
| 集合事件(T10) | 空成功 → EmptySnapshot(禁静默);不可用 → Unavailable;淘汰 → Evicted;失败保留上次成功;观察永不驱动 Run;对外 ToolId;见 output-inspection.mdx;可勾选 (TC-OUT-* / S10) | 已定 |
| C# 适配(T11) | MVP 绑定= PInvoke;C++/CLI 非默认;opaque handle + Release/Dispose;ImageDisplay 仅 C# 经绑定消费;见 csharp-binding.mdx | 已定 |
| examples 语言分工(T12) | 编排/成像核心示例= C++;ImageDisplay= C#;见 examples.mdx / overview | 已定 |
| §10.1↔测生命周期(T13) | 验收勾选映射注册→建组→Link/Validate→Run→Cancel/失败中止→Load 复载→H1–H10→fake;增 OUT/ACQ/SESS/MEM/DISP + S10–S13 索引;见 toolgroup §10.1 | 已定 |
| 测试契约表(契约可测化) | §10.1 / H1–H10 / Diagnostic / S01–S08 收成「前置·动作·期望 code/状态·章节」可勾选表;§10.1 摘要回链;见 test-contracts.mdx。勿与下文开放风险 ID R4(脚本钩子)混淆 | 已定 |
| 伪仓库树 | 最小可看见树:公开头路径 + fake_acq / Load .avtg / headless 碎片;ImageDisplay 仅 C# 文件名;见 sketch。不可编译;无稳定 ABI;不写 CMake;非验收正文 | 已定 |
| 负路径与嵌套场景 | S09a–d:嵌套+Encapsulation / SourceDisabled+InvalidBinding / IoFailure+停相机≠Cancel / 可选 §9.2 两组串联;契约映射与 TC-RUN-06·07;见 examples-scenarios.mdx / test-contracts.mdx。不改 v1.9 语义与 Diagnostic 码表。勿与下文开放风险 ID R6(IPC)混淆 | 已定 |
| 宿主集成契约 | headless / C# 显示宿主同核;示意 vyntek_toolgroup_* / vyntek_imaging_*(Create/Load/Validate/Run/RequestCancel/诊断/Adopt·Release);跨边界 opaque + Diagnostic 上抛 + UI 只消费投影 + 观察不驱动 Run;停止矩阵宿主侧分派(Cancel / 停相机 / 关显示);见 host-integration.mdx。不改 v1.9 语义与 Diagnostic 码表。勿与下文开放风险 ID R7(稳定 ABI)混淆 | 已定 |
| 导读与术语终检 | 角色化 ~10 分钟路径(overview);术语终检表 Tool/ToolGroup/ToolId/TypeDesc/DiagnosticCode/.avtg/PixelImageHandle/Access·ReadOnly/Adopt·Release/同核;禁混词;S07↔host-integration 薄回链;见 overview.mdx / glossary.mdx。保持 toolgroup v1.9;不改语义与码表。 | 已定 |
| 输出观察可勾选 | T10 集合事件 → TC-OUT-01…09 + 场景 S10;升格/对齐 TC-RUN-05(观察永不驱动 Run);薄回链 output-inspection / overview;见 test-contracts.mdx / examples-scenarios.mdx。不改 T10 事件闭集与 toolgroup v1.9 码表/语义。勿与下文开放风险 ID R9(编辑 UI)混淆 | 已定 |
| 阶段 D 采集/会话可勾选 | camera-acquisition / session-lifecycle 散文 → TC-ACQ-01…07 + TC-SESS-01…05 + 薄场景 S11;薄回链 host-integration「两端都停」/ overview;见 test-contracts.mdx / examples-scenarios.mdx。不改 Diagnostic / T9 停止矩阵语义与 toolgroup v1.9 码表。勿与下文开放风险 ID R10(C++ UI·已关闭)混淆 | 已定 |
| 阶段 B 存储/pin 可勾选 | memory-management 散文 → TC-MEM-01…13 + 薄场景 S12;薄回链 overview / validation 阶段 B;见 test-contracts.mdx / examples-scenarios.mdx。不改 Diagnostic / T9 停止矩阵与 toolgroup v1.9 | 已定 |
| 阶段 F 显示集成可勾选 | image-display 散文 → TC-DISP-01…12 + 薄场景 S13;显示契约仅 C#;薄回链 overview 第 6 步 / validation 阶段 F / host-integration·TC-CTL-05 / examples 显示段;见 test-contracts.mdx / examples-scenarios.mdx。不改 Diagnostic / T9 停止矩阵与 toolgroup v1.9。勿与 T15 开放风险 R10(C++ UI·已关闭)互替 | 已定 |
| 打包 / 库名(T14) | 库名倾向 libvyntek_toolgroup / libvyntek_imaging;头安装树跟 cpp-headers.mdx;MVP 无稳定 ABI;不写完整 CMake | 已定 |
| 开放风险登记(T15) | 只登记、不扩做;见下文「开放风险登记表」;与 toolgroup §10.2「不做」一致 | 已定 |
| 未知工具类型 | MVP 严格失败;编辑器占位只读归后续 | 已定 / 后续 |
同 RunSession 重入 | 拒绝(排队留后阶段);须单测;码 Busy | 已定 |
| 未知可选字段 | 保留(可告警、不剥掉) | 已定 |
| 取消粒度 | MVP 协作式(工具边界检查);工具内抢占 不做进 MVP(后议);码 Cancelled | 已定 / 后议 |
| 脚本、产线 IO、IPC 服务化 | 不阻塞 MVP | 后续 |
边就绪调度 / .vpp | 非目标 | 关闭 |
开放风险登记表(T15 · 薄 · 只登记不扩做)
编号说明:下表
R1–R10属 T15 开放风险命名空间;引用须写「T15 开放风险 Rn」。
| ID | 风险 / 后续项 | 登记口径 | 归类 |
|---|---|---|---|
| R1 | 工具内抢占取消 | MVP = 协作式(工具边界检查);工具内抢占 不做进 MVP | 后议 |
| R2 | 编辑器未知工具占位只读 | MVP 未知 type → 严格失败;占位打开归后续 | 后续 |
| R3 | 同 RunSession 排队 | MVP 重入 → 拒绝(Busy);排队留后阶段 | 后续 |
| R4 | 脚本钩子 / 脚本语言 | 不阻塞 MVP;见 §10.2 | 后续 |
| R5 | 产线 IO(PLC/现场总线等) | 不阻塞 MVP;专文或高级阶段 | 后续 |
| R6 | 进程外 IPC 服务化 | 演进选项(toolgroup §7.2);不做进 MVP | 后续 |
| R7 | 稳定 ABI / 符号版本 | MVP 无稳定 ABI 承诺(示意头≠已发布);见 T14 / cpp-headers | 后续(发布期再议) |
| R8 | 边就绪调度 / .vpp | 非目标 | 关闭 |
| R9 | 编辑 UI / 属性网格 / 画布 | 不做进 MVP | 后续 |
| R10 | ImageDisplay 写成 C++ UI | 禁止;显示仅 C# 经绑定消费句柄 | 关闭(口径) |
开放项不得弱化已定契约。验收仍以 toolgroup §10.1、test-contracts.mdx 与上表「已定」为准。
当前实现与目标边界
| 项目 | 当前源码事实 | 目标设计 |
|---|---|---|
| 输入 | 静态 ImageSource 与专门的 FrameImageSource | 控件直接接收 IPixelImage,文件解码在图像创建阶段完成 |
| 内容模型 | ImageFrame 同时拥有 owner 和一次提交身份 | 存储、读写对象、静态图像与显示更新分别负责 |
| 编号 | SubmitAsync 要求 FrameId 严格递增 | 业务 ImageId 可空、可重复、可倒退,不参与排序 |
| 推进 | 单生产者等待绘制确认后继续提交 | 宿主按需设置下一张静态图像,无逐张绘制承诺 |
| 异步协调 | 来源会话、输入等待、绘制背压 | 新请求使旧准备失效,旧任务不能覆盖新意图 |
| 当前缓存 | 快照、mip 与 Skia tile 持有原图引用 | 内部不可变 DisplaySnapshot,区分原始存储与显示映射缓存 |
| 像素查询 | UI 当前原始帧的灰度值 | UI 当前快照的灰度、RGB/BGR 或深度原始样本 |
| 冻结 | IsFrozen 暂停流消费 | 宿主暂停提交即可保持当前图像,不设流冻结状态 |
| 主题与宿主 | Skia composition,主题设置焦点和裁剪 | 本专项不改变主题、坐标、交互或覆盖层职责 |
根因是将显示表面建模成连续帧消费者,使内存寿命、业务帧号和生产调度互相绑定。目标直接表达“设置当前图像”,不再叠加第二套流发布 API。
本次仅调整 specs。目标涉及 FrameImageSource、帧相关成员与事件的迁移或删除,是明确的 API/行为重设计,不再以“旧流协议完全保持”为目标。实际实施时同步库、Gallery、测试和当前控件文档,不能仅删一条帧号比较而保留整套流架构。
实施边界、迁移与验证
本次只调整设计稿,不修改源码、Gallery 或现有控件说明。实施按图像模型、显示捕获与释放、多格式渲染、调用方迁移四部分完成,每部分分别验证;完整交付时统一更新当前控件文档。
基础包抽取、ToolGroup 与成像句柄所有权集成和 SDK 会话适配必须有独立验证,不把 ImageDisplay 能显示一张图视为基建已稳定。API 草案中精确格式接口、泛型返回桥接及访问对象创建能力在实施前先做最小编译验证;外部扩展优先通过工厂导入存储和显式格式支持接入,不要求第三方绕过协调实体自行构造访问对象。
| 旧成员或旧草案 | 目标 |
|---|---|
| ImageFrame / FrameImageSource / SubmitAsync | IPixelImage / 格式接口,持续 SetImage 刷新 |
| FrameId 递增、单生产者和绘制背压 | 由宿主调度,不再成为显示契约 |
| ImageDisplay.Source: ImageSource? | Source: IPixelImage?,编码加载在外部完成 |
| PixelImageSource 显示适配层 | 删除该拟议类型,控件直接申请图像读取 |
| 灰度专用 ImagePixel.Gray | 多格式原始样本与显式 TryGet 方法 |
| FramePresentation / FrameRendered | ImageDisplayUpdate / ImageRendered,安装与绘制分开 |
| IsFrozen | 宿主暂停提交,当前快照保持静态 |
这是明确的 API/行为重设计;特别是 Source 类型与文件加载职责变化,不承诺旧二进制或 XAML 写法兼容。不得通过 Source: object、隐式格式猜测或保留另一条私有流管线掩盖迁移。现有模板、视口、覆盖层、工具接口和渲染后端继续复用;工具的像素展示与 Gallery API 示例必须同步调整。
验证重点:
- 四种图像接口与 Info/像素类型一致;工厂、Clone、Share、ROI、负步长、行尾空隙不破坏语义或布局。
- 基础包无 Avalonia/Skia/控件/流程引擎依赖,文件解码适配不能反向污染图像核心。
- 覆盖 0→0、0→N、N→0、N→M、图像列表、输入别名、多 ROI 输出、空/可选输入及非图像容器内图像的所有权。
- ToolGroup:链接类型兼容与列表序校验(源须在目标之上;禁止用环表达采集);自上而下顺序 Run;失败中止与禁用策略见 toolgroup.mdx。成像交接:0~N 输入/输出句柄稳定 ReadOnly;输入写申请立即拒绝,Clone 的新存储才可写(不以边就绪调度为编排模型);可测对照 §3.4 H1–H10;headless 可用 §7.6.3 fake 替身。
- 已暂存多个输出后失败、AddOwned 中途拒绝、重复 handle、借入输入误提交、下游部分接受时都恰好关闭对应所有权。
- 无下游输出仍可被调试观察;缓存淘汰与打开竞争、连续运行/重试定位、共享/独立快照及配额失败均不破坏业务输出或已打开查看者。
- 调试器运行中连接、断开和重新连接不影响工具组;KeepLatest 可重放当前集合,查询/订阅不漏更新,ReleaseAfterRouting 不冒充可恢复已回收历史。
- 工具成功的空输出清除旧当前集合,失败不冒充新的成功结果;最近输出替换、已打开查看者和 SDK 脱离分别管理引用。
- ToolGroup 自有输出的调试观察可稳定 Share,不阻塞后续创建新输出;SDK 快照仍验证及时归还,共享查看者未退出不误报原槽已回收。
- 初次只写 ROI 不可发布整图,ROI 写入中止使全存储 Invalid,普通类型化写不能错误恢复;padding 不进入默认导出。
- SDK 持帧与回调临时指针分别验证;地址复用不复用 BufferId,停止/断线协议不使在途地址提前失效。
- SDK 满池、归还线程变慢、归还失败、Latest 连续替换和 UI 长时间暂停均保持约束,回收责任可追溯。
- 排空和中止分别验证,工具/native 不响应取消时不强制释放;正常停流回到资源基线,外部保留和归还失败明确报告。
- 输出暂存、输入队列、缓存、合流配对表、并发工具及临时分配都受限制,不能仅证明控件缓存有界。
- 相同实例重复提交、相同或倒退业务编号均合法;原地写入完成后只有显式新请求才刷新。
- SetImage 对稳定输入保留固定内容,对可写输入异步申请读取;不把通用请求登记误报成已完成捕获,期望版本按实际授权验证。
- 当前 RetainInput、写者排队、同图或同缓冲 ROI 重复提交时,复用已授予读取,不排队形成读写自锁;脱离副本的来源身份不误当实际原图读取。
- 同一原图分别供多个算法和窗口读取,所有权独立,调用方关闭 handle 不破坏已经登记的显示。
- 一个准备工作和最新候选有界;快速提交、权限等待、替换和卸载不会积累旧读取或发生授权/取消泄漏。
- 候选失败保留旧图,Source/Current/渲染消息职责清晰,过时输入或显示参数任务不能覆盖最新意图。
- RGB/BGR 通道正确;Depth16 范围、无效码、尺度缺失、边界夹取和色表结果明确,ushort 运算不下溢。
- UI 取样是原始像素;缩小、伪彩、曝光变化与副本脱离均不改变取样值或来源版本。
- Snapshot 和 Detach 保存完整原格式;候选未授予读取、复制中和已安装阶段均能正确脱离。
- Completion、InputReleased、ImageRendered、ReturnCompleted 互不冒充;卸载及清空只排空对应旧输入。
- SDK 的调用方 handle、原图读取和 pin 未关闭时不得误报真实归还;native 工作真正退出前不复用其缓冲。
- CPU/GPU 计量覆盖格式差异、暂存、重叠 ROI 去重、峰值与退休工作;预算失败不提前丢弃旧画面。
- 文件加载的宿主顺序校验、错误归属和取消清理明确,控件没有残留第二条编码来源或流输入通道。
- 模板重建、隐藏、重挂载、图形 context 重建与真实后台绘制遵守同一快照寿命;不以仅模型单测替代显示验证。
- 生成器、绑定和接口分发不依赖运行时反射扫描;发布前完成对应 NativeAOT 验证。
测试生命周期遵循测试价值与生命周期。实施需分别报告构建、模块测试、真实显示、多格式持续更新负载和 NativeAOT。本次文档仅检查链接、API 一致性与 diff,不提供实现或性能验证结论。
文档状态:设计草案。同步 toolgroup v1.9:T8–T13;T14 打包/库名;T15 开放风险登记;R4 test-contracts.mdx;R5 sketch;R7 host-integration.mdx;术语终检见 overview.mdx / glossary.mdx;TC-OUT- / S10;TC-ACQ-* / TC-SESS-* / S11;TC-MEM-* / S12;TC-DISP-* / S13(显示仅 C#;≠ T15 R10)。*
实现现状
阶段 A–G 的退出条件仍开。成像/采集/显示有外形与薄摘现状,见各 test-contracts-tc-*.md。不要把本页路线表读成已验收清单。