关于 vision-tools
vision-tools 是一组用于图像检查、几何处理、OCR、裁剪和比较的本地 CLI 与脚本,面向处理图像的文本型 Agent。它结合视觉模型查询与基于像素的操作。
主要功能
- 01使用 glance 描述图像并进行 OCR
- 02定位目标并枚举元素
- 03基于像素描摹形状与裁剪
- 04长截图 OCR 工作流
- 05图像差异与颜色分析
- 06将 HTML 渲染为截图
适用场景
- 01读取截图文字或检查细节
- 02查找并裁剪指定的界面元素
- 03比较截图并定位变化
- 04渲染 HTML 以进行视觉检查
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anionex/ agent-vision-toolkit --skill vision-tools安装后在 Claude Code 中输入/vision-tools确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/gui.mdlong-screenshot-ocr.mdrestore-graphic.mdrestore-structure.mdrestore-ui.mdscripts/dominant_colors.pyextract_fg.pyhtml_shot.pylong_screenshot_ocr.pypixel_diff.py详细介绍
vision-tools
五个本地 CLI,为纯文本 Agent 提供视觉能力。它们读取一份共享的视觉配置(VISION_API_KEY / VISION_BASE_URL / VISION_MODEL /
LANG),以及可选的 Python 客户端设置 VISION_API_PROTOCOL、
VISION_REASONING_EFFORT 和 VISION_USER_AGENT——无需额外凭据。
根据你要回答的问题选择工具:
| 问题 | 工具 |
|---|---|
| “这张图片展示了什么/写了什么?” | glance |
| “X 在哪里?”——你能说出名称的东西 | ground |
| “所有 X 都在哪里?”——某一类的每个实例 | detect |
| “它的精确形状、大小和偏移是多少?” | trace |
| “把这个框裁剪出来,另存为图像文件” | crop |
| “对这张长截图/滚动页面/聊天记录进行 OCR” | scripts/long_screenshot_ocr.py |
| “将图标/Logo 前景提取为透明 PNG——手动指定区域或自动提取(适用于裁剪并缩放过的截图)” | scripts/extract_fg.py |
| “将这个 HTML 文件转换为视口或整页截图” | scripts/html_shot.py |
| “某个区域以哪些颜色为主,哪个调色板值与之匹配?” | scripts/dominant_colors.py |
| 它们都无法返回的关系——两个已定位对象之间的间隙或距离 | 对像素进行编程处理(Pillow) |
glance 回答某物是什么;ground 和 detect 回答某物在哪里。
你向 ground 提供特定事物的描述;你向 detect 提供一种类别,它会列出所有实例。
两者都会给出真实坐标,但并非精确到像素:框以 0-1000 的网格给出,再按你的图像缩放,因此最后一两个像素不可靠。这足以用于裁剪、点击和位置比较。需要精确数值时,trace 会根据实际像素计算偏移、大小和形状。
优先使用提供的工具,不要手动处理像素
对于这个工具包提供了工具的所有操作,都应调用相应工具——不要在任务中途用 Pillow 重写。提供这些 CLI,是为了避免每次都用不同方式手动编写相同的像素处理代码:
- 从图像中裁剪一个框 → 使用
crop,而不是Image.open(...).crop(...) - 获取区域的调色板 → 使用
scripts/dominant_colors.py - 比较两张图像 → 使用
scripts/pixel_diff.py - 矢量化为 SVG → 使用
trace - 定位/清点元素 → 使用
ground/detect - 描述图像/进行 OCR → 使用
glance - 安全拆分、进行 OCR 并合并长截图 → 使用
scripts/long_screenshot_ocr.py - 将 HTML 文件转换为视口或整页截图 → 使用
scripts/html_shot.py
只有当这些工具都无法返回所需结果时,才手动编写 Pillow 代码:计算两个已定位对象之间的关系(间隙、距离)、调整大小或叠加图像、绘图。如果你发现自己在编写 .crop()、.convert() 或直方图代码,而上面的某个工具正好适用,就改为调用该工具——坐标和框格式相同,输出也能直接传给下一个工具。
glance——询问图像内容
glance <image> # detailed description
glance <image> -q "<question>" # targeted question (qualitative only)
glance <image> --ocr # verbatim OCR
glance <image> --region X1,Y1,X2,Y2 -q "..." # zoom into a crop
glance <img1> <img2> -q "..." # compare in ONE call
使用 glance 进行比较时,请在一次调用中传入所有路径——分开调用无法同时看到两张图像,因此先生成两段描述再进行比较,会产生两个幻觉风险点,而非真正的比较。--region 只会上传裁剪区域,因此小字和图标也能看清。
但“这两张图之间有什么变化?”并不是 glance 的问题。一个字的徽标或细微的位移,对视觉模型而言只是舍入误差,而 scripts/pixel_diff.py 能精确识别。先进行差异比较以获取框,再用 glance --region 查看该框,识别具体变化内容。
对于较长的滚动截图,不要将整张图一次性发送给 OCR 并接受模型缩放造成的信息损失。请运行长截图工作流:它会查找低内容切割带,对每个分块调用 glance,对聊天记录使用结构化提取,只合并重复的重叠部分,并生成边界审计:
python3 scripts/long_screenshot_ocr.py work/page.png -o work/page.ocr.md
python3 scripts/long_screenshot_ocr.py work/chat.png --mode chat --resume -o work/chat.ocr.md
使用前请阅读 references/long-screenshot-ocr.md。其中定义了用于检查不安全切割和聊天消息边界的验证步骤。
ground — 定位指定目标
ground <image> "<target description>"
ground <image> "<target>" --region X1,Y1,X2,Y2
输出:以原图像素为单位的 x1: .., y1: .., x2: .., y2: ..;使用
--region 时也一样(裁剪区域中的命中会映射回原图)。
各提供方原生的 0-1000 边界框数组顺序并不一致:Gemini 使用
[y0, x0, y1, x1],而 Qwen3-VL、Qwen3.5 和 Qwen3.6 使用
[x0, y0, x1, y1]。Grounding 代码必须按模型系列(或显式覆盖)选择顺序,再缩放到像素;切勿把每个提供方的结果都按 Gemini 风格的 yxyx 解析。
如果返回了多个带编号的边界框,说明你的描述匹配到了多个元素,而非单个目标。请用目标的区别特征缩小范围——其文字、位置或所在区块——然后再次提问。
边界框不只是答案,也是一个定位句柄,可供下一次调用使用:
$ ground screenshot.png "the send button"
x1: 1067, y1: 841, x2: 1108, y2: 881
$ glance screenshot.png --region 1067,841,1108,881 -q "is it enabled or greyed out?"
这两步就能检查那些小到无法在整图处理时保留下来的内容。
detect — 找出某一类别的所有实例
detect <image> # every UI element
detect <image> "buttons" # one kind only
detect <image> --region X1,Y1,X2,Y2 # inside one box
使用 ground 时,你指定某个具体目标;使用 detect 时,你指定某个类别,它会枚举该类别的实例。输出为编号列表,包含每个项目的可见文字和边界框。整屏处理是快速的初稿——在内容密集的屏幕上,每次运行的计数可能不同。若要确保完整性,先检测布局区块,再对每个区块使用 detect --region。
trace — 精确形状几何(本地运行,无需视觉 API)
trace <image> # b/w spline SVG to stdout
trace <image> --polygon # boxy diagrams/wireframes
trace <image> --region X1,Y1,X2,Y2 -o out.svg # crop first
坐标来自实际像素,而非模型估算。仅适用于扁平、高对比度图形;文字会变成曲线(文字内容重要时,可搭配 --ocr)。小图会在描摹前自动放大,因此描摹 30px 图标和描摹屏幕截图一样轻松——不必因为尺寸小而跳过此工具。发布或复用描摹后的 SVG 前,请阅读
references/restore-graphic.md——其中说明了复用时的注意事项,以及应该发布还是手工编写。
crop — 从图像中裁切像素边界框(本地运行,无需视觉 API)
crop <image> --region X1,Y1,X2,Y2 # writes <image-stem>.crop.png next to the input
crop <image> --region X1,Y1,X2,Y2 -o out.png
crop <image> --region X1,Y1,X2,Y2 --scale 4 # upscale the cut-out 4x (LANCZOS) first
使用 ground/detect 打印的相同 X1、Y1、X2、Y2 像素边界框,并限制在图像范围内。一旦某个边界框值得保留——同一裁剪图即将依次传入 pixel_diff、dominant_colors 和 trace——就将它裁切到文件中一次并重复使用,而不是每次调用都在内存中重新裁切。写入前,--scale N 会放大裁剪结果(默认输出文件名会变为
<image-stem>[email protected]):对于小到 ground/trace 无法清晰识别的图标,可使用 --scale 4 裁切,然后对放大后的文件运行 ground/trace——返回的坐标位于放大后的网格中,除以 N 即可映射回原图。需要可选依赖 pillow。
extract_fg — 将图标前景提取为透明 PNG:手动指定区域或自动处理(本地运行,无需视觉 API)
# manual: you know the region (and optionally the background colour)
python3 scripts/extract_fg.py shot.png --region X1,Y1,X2,Y2 -o icon.png
python3 scripts/extract_fg.py shot.png --region X1,Y1,X2,Y2 --mode dark # grey/black line logos
python3 scripts/extract_fg.py shot.png --region X1,Y1,X2,Y2 --exclude-color '#E6E6E6'
# auto: `crop --scale` cut-outs with the icon centred — no region needed
crop shot.png --region X1,Y1,X2,Y2 --scale 4 -o d/icon1.png
python3 scripts/extract_fg.py d/icon1.png d/icon2.png # writes <stem>.clean.png next to each input
python3 scripts/extract_fg.py d/icon1.png --disc-radius 60
python3 scripts/extract_fg.py d/icon1.png --boxes "101,84,184,171"
手动模式会保留区域内所有足够大的连通分量(分开的徽标子形状会保留在一起;微小斑点会被丢弃)。自动模式接收使用 crop --scale 裁切并将图标居中显示的图像(圆盘 + 字形):圆盘中心就是图像中心,圆盘半径默认为
min(w,h)/2 * 0.6,并从中心周围的环带采样圆盘颜色;该颜色会被排除,字形则从面积最大的三个彩色分量中选取饱和度最高者(白色环、波纹和文字会被去除),输出为 1:1 透明 PNG。自动推断失败时,可使用 --disc-radius 覆盖半径,或将 ground 边界框(位于放大后的网格中)作为 --boxes 传入,以重新居中并根据重叠关系重新筛选。可一次传入多张图像(自动模式)。
需要可选依赖 pillow(自动模式还需要 numpy)。
html_shot — 将 HTML 文件渲染为图像(本地运行,需要 Chrome 系浏览器)
python3 scripts/html_shot.py page.html # writes page.png, 1280x800
python3 scripts/html_shot.py page.html --width 1440 --height 900 -o page.png
python3 scripts/html_shot.py page.html --scale 2 # 2x pixels: small text stays readable
python3 scripts/html_shot.py page.html --full-page # complete scroll height, same layout viewport
python3 scripts/html_shot.py page.html --full-page --max-pixels 40000000
视觉对齐循环:编写 HTML,在参考视口下截屏,然后与设计稿比较。使用 pixel_diff 查找明显差异,而不是一味追求差异为零的分数。渲染在无头 Chrome/Chromium/Edge 中进行,不需要 Python 依赖。默认只捕获视口。使用 --full-page 捕获完整文档,同时保持 --width 和 --height 作为布局视口,这样 vh/svh 和响应式断点就不会改变。如果页面高度不可信,可添加 --max-pixels N。--wait-ms N 会在捕获前暂停,以等待字体、图像或动画加载。路径相对于此技能自身的目录。
pixel_diff — 查找两张图像的差异(本地运行,无视觉 API)
python3 scripts/pixel_diff.py <a> <b> # path is relative to this skill dir
输出整体差异百分比,以及差异最明显的区域,格式为 x1: .. 框,可直接传给 glance --region。对于视觉模型四舍五入的结果,它能提供精确值。
dominant_colors — 获取某个区域的调色板,并从候选值中找出精确颜色(本地运行,无视觉 API)
python3 scripts/dominant_colors.py <image> --region X1,Y1,X2,Y2 # top colour clusters + shares
python3 scripts/dominant_colors.py <image> --region X1,Y1,X2,Y2 \
--candidates '#F9FAFA,#F5F5F5,#F3F3F3,#EDEDED' # pick the best candidate
视觉模型会描述一种颜色(“浅灰色”),但不会给出其数值。第一种模式会对图像缩小采样、量化并合并近似颜色,从而列出该区域的主要颜色及各自占比——直方图能显示哪种颜色是背景色,哪种是强调色。根据标签所暗示的候选调色板,第二种模式会评估每个候选颜色与区域像素的接近程度,并输出最匹配的颜色。请从这里获取数值,不要采用 glance 的文字描述。路径相对于此技能自身的目录。
使用副本,不要使用临时路径
如果图像位于临时目录中,在首次对其调用工具之前,请将它复制到持久位置,并对副本执行所有操作——这样才能确保之后仍可访问该图像:
cp "<the temp path>" work/shot.png
glance work/shot.png -q "..."
例外:用户要求将图像保留在临时文件夹中。
你拿到的是描述而不是图像时
如果你只通过文本获得图像——例如由人、工具或其他模型撰写的描述——而且对话中能看到图像的文件路径,不要根据缺失的细节进行推测。亲自再查看一遍:
glance <path> -q "<the specific detail>"— 进行一次定性追问。ground <path> "<target>",然后执行glance <path> --region <that box> -q "..."— 定位后放大。这是仔细检查单个元素的可靠方法。
如果文件已不存在,请如实说明,不要猜测。
由粗到细——上述所有任务背后的方法
对于有关图像的单个问题,glance 就能给出完整答案。对于任何多步骤任务,都应由外向内进行:
- 先完整查看一次图像(使用
glance,或查看已有描述),了解布局并盘点各元素的位置。 - 对于任何重要元素,先用
ground定位,再通过glance --region <box> -q "..."放大查看。完整图像的查看经常会漏掉小字和图标;裁剪后,所有像素都集中在一个细节上,因此模型能以更高的有效分辨率查看它。如果需要多次检查同一个框,先用crop将其裁剪到文件中。 - 对像素级事实(精确颜色、细微偏移、尺寸),绝不要只相信文字描述——视觉模型可能会自信地报告实际并不存在的样式,例如黑白代码块中的彩色语法高亮,或根本不存在的边框。应从
trace、ground框或pixel_diff获取数值;只有这些方法无法提供时,才自行采样像素。
使用场景
以下每个文件对应一项完整任务:说明适用情况、调用顺序,以及如何判断任务是否成功。
| 任务 | 阅读 |
|---|---|
| 对长截图、滚动页面或聊天记录进行 OCR,避免在分块边界处丢失文本 | references/long-screenshot-ocr.md |
| 将页面或组件重建为 HTML/CSS,包括约三分钟的快速近似模式;或根据参考图对齐现有 UI | references/restore-ui.md |
| 将图标、徽标、插画或其他独立图形提取或重建为透明 PNG/SVG | references/restore-graphic.md |
| 将草图、图表或白板内容转换为 Mermaid、Graphviz 或其他结构化表示 | references/restore-structure.md |
| 根据截图操作 GUI——定位、执行操作并逐步验证 | references/gui.md |
注意事项
- 仅支持 PNG / JPEG / GIF / WebP 图像。
- 如果找不到某条命令,说明未安装可选工具——请告知用户,不要临时编造替代方案。
- 如果视觉 API 调用失败,请如实转述错误;切勿捏造图像内容。
源代码仓库:https://github.com/Anionex/agent-vision-toolkit
安装指南:https://github.com/Anionex/agent-vision-toolkit/blob/main/AGENT_INSTALL.md