# dsh-visibridge — USB 摄像头视觉闭环设计文档 - 日期:2026-08-18 - 状态:设计(待评审) - 关联插件:dsh-visibridge(宿主级,`analyze_image` 工具已上线) --- ## 1. 背景与目标 DeepSeek 官方视觉模型 `deepseek-v4-flash-vision-exp` 已接入 dsh-visibridge 并实测可用。 本文档设计**摄像头自动拍摄 + 模型自治识别**能力,核心价值: > **让模型在调试循环里自己"看"**——模型改参数/烧录程序后,主动调用摄像头观察实际显示效果, > 形成「改 → 拍 → 看 → 再改」的视觉闭环,替代人工文字描述(慢、不准、有理解偏差)。 ### 目标场景 | 场景 | 说明 | 拍摄距离 | |------|------|---------| | **嵌入式/GUI 调试**(主) | 手机屏、T-Display 小屏、板卡、仪器/示波器屏幕——模型自己看显示内容、报错、状态变化 | 10–25cm | | **手机改造辅助** | 屏幕 GUI 设计/调试时观察实际渲染效果 | 10–25cm | | **文档/OCR 扫描** | A4 文档、标签、白板文字提取 | 25–40cm | --- ## 2. 架构总览 ``` ┌─ dsh 会话(DeepSeek V4 主模型)────────────────────────────┐ │ 调试循环:改参数 → 烧录 → 调用 capture_image → 看结果 → 再改 │ └──────────────┬────────────────────────────────────────────┘ │ capture_image 工具调用(模型自主) ▼ ┌─ dsh-visibridge 插件(宿主级)─────────────────────────────┐ │ capture_image 工具 │ │ ├─ ① 拍照:spawn python capture.py → 抓帧存 jpg │ │ ├─ ② 识别:复用 analyze 管线(base64 → 后端 → 结构化证据) │ │ └─ ③ 返回:证据 + 图片路径 + 时间戳 │ │ analyze_image 工具(现有,不变) │ └──────────────┬────────────────────────────────────────────┘ │ backend 切换:deepseek / ollama / xiaomi / custom ▼ 视觉模型(DeepSeek / minicpm-v4.5 / mimo-v2.5 ...) ``` --- ## 3. 组件设计 ### 3.1 `capture_image` 工具(新增,Host) **Schema** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `question` | string | 否 | 聚焦识别方向(如"屏幕显示什么错误""看当前渲染效果") | | `camera` | integer | 否 | 摄像头设备号,默认 0 | **返回(结构化,与 analyze_image 同构 + 拍照信息)** ```json { "summary": "一句话总结画面内容", "ocr": { "full_text": "...", "lines": [...] }, "layout": { "regions": [...] }, "semantics": { "scene": "...", "entities": [...] }, "visual": { "dominant_colors": [...], "style": "..." }, "uncertainty": [...], "model": "deepseek-v4-flash-vision-exp", "capture": { "path": "D:/.../.captures/cap-20260818-193000.jpg", "camera": 0, "capturedAt": "2026-08-18T19:30:00+08:00" } } ``` **行为** - 拍照失败(无摄像头/打不开)→ 明确报错,提示用文件路径走 `analyze_image` - 识别失败 → 复用现有降级兜底(summary + uncertainty 标注) - 工具描述明确告知模型:调试循环中可主动调用观察变化 ### 3.2 `capture.py` 拍照脚本(新增,随插件分发) Python + OpenCV(本机已装 4.13.0)。 **参数**(命令行): ``` capture.py --out [--camera 0] [--width 1280] [--height 720] [--preview 0] ``` **流程**: 1. 枚举设备(`cv2.VideoCapture` 打开 + 设备名探测,0..N) 2. 打开指定设备 → 设置分辨率(默认 1280×720)→ **开自动对焦**(`CAP_PROP_AUTOFOCUS=1`) 3. **预热 0.5s**(丢弃前几帧,让曝光/对焦稳定) 4. 抓取 1 帧 → 写 jpg(质量 90) 5. 正常退出(exit 0);失败 → stderr 输出原因(exit 非 0) **保存位置**:工作区 `.captures/` 目录(时间戳命名 `cap-YYYYMMDD-HHMMSS.jpg`,自动创建) ### 3.3 复用管线(现有,不新增) - 拍照产物 → 走现有识别管线(`pure.js` 的 mergeVisionConfig / 后端选择 / extractJson / normalizeEvidence) - `backend` 切换(deepseek / ollama / xiaomi / custom)对 capture_image 同样生效 - host 校验、密钥脱敏、json_schema(Ollama)等现有机制全部复用 --- ## 4. 数据流 ``` 模型调用 capture_image(question) → 确定保存路径 .captures/cap-.jpg → spawn python capture.py --out --camera N → 成功:读 jpg → base64 data URL → 后端 POST /chat/completions → 结构化证据(容错提取 + 归一化)→ 返回 + capture 信息 → 失败:无摄像头报错 / 识别降级兜底 ``` **变化对比支持**:时间戳截图留存在 `.captures/`,模型可连续调用两次并对比两张图(cap-001 vs cap-002)观察调试变化。 --- ## 5. 错误处理 | 错误 | 处理 | |------|------| | 未检测到摄像头 | `capture_image` 报"未检测到可用摄像头",提示用 `analyze_image` + 文件路径 | | 设备被占用 | 报"摄像头被其他程序占用",提示关闭占用程序 | | 对焦/曝光不稳定 | 预热 0.5s + 重试抓帧一次 | | 识别降级 | 复用现有不确定性标注,不中断 | | 图片超限 | 分辨率默认 1280×720(约 200–500KB),远低于 8MB 上限 | --- ## 6. 硬件要求(供选购,摄像头用户自购) | 指标 | 要求 | 原因 | |------|------|------| | 像素 | **1080p 即够**(不必 4K) | 视觉模型内部降采样,清晰度靠对焦不靠像素 | | 自动对焦 | **必须支持 AF** | 拍摄距离 10–40cm 变化 | | **最近对焦距离** | **≤ 10cm** | 手机屏/小屏近摄关键;普通摄像头 50cm 外才合焦会糊 | | 镜头 | 广角 3–4mm | 近距覆盖 A4 文档 | | 接口 | USB(UVC 免驱) | OpenCV 直接可用 | **推荐类型**:带 AF 的 USB「文档摄像头/视频展台」类(最近对焦 5–10cm),或带微距的 AF 会议摄像头。 **已确认选型(2026-08-18)**:JX 系列 USB 摄像头(商家确认**工作距离 5–35cm**,俯拍适用) - JX-500(5MP,推荐)/ JX-800(8MP,余量可选)/ JX-1300(13MP,过剩不推荐) - 三者同镜头(3.6mm 广角,H52°/V67°/D79°)同对焦(自动 0.2s 锁焦),仅像素不同 - 5cm 最近对焦满足手机屏(10–25cm)、板卡、A4 俯拍(25–35cm)全部场景 --- ## 7. 测试计划 **无硬件阶段(先做)**: - `capture.py` 无摄像头时正确报错 - `capture_image` 无摄像头时降级提示 + 仍可用文件路径 - 单元/手动验证:工具 schema、参数校验、错误路径 **有硬件阶段(用户购摄像头后)**: - 真机拍摄:手机屏小字、A4 文档、板卡丝印各拍一张识别 - 对焦质量验证:近距 15cm 是否清晰 - 调试闭环演练:模型连续调用 capture_image 观察两次状态变化 --- ## 8. 实施阶段 | 阶段 | 内容 | 依赖 | |------|------|------| | **P1 骨架** | `capture.py` + `capture_image` 工具注册 + 拍照→识别管线 + 错误处理 | 无硬件可测 | | **P2 完善** | 设备枚举、自动对焦、预热、多分辨率、参数调优 | 无硬件可测 | | **P3 实测** | 用户购摄像头后真机调试、对焦调优、截图对比演练 | 摄像头 | --- ## 9. 开放问题 1. 是否需要 `compare_captures`(对比两张截图差异)内置工具?——起步可让模型自行对比,暂不做 2. 拍照分辨率是否需要可配置到 4K?(默认 1080p 足够) 3. 是否自动清理 `.captures/` 旧文件?(建议保留最近 N 张,默认不清理) --- *本文档为设计稿,评审通过后进入实施。*