关于 vision-skills
vision-skills 是一组用于图像检查、几何处理、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-skills安装后在 Claude Code 中输入/vision-skills确认已加载。
包含的文件
除 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-skills
五个本地 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
detect <image> "text" --fail-on-empty # fail if no text is detected
默认类别面向 UI 截图。对于照片或视频帧,请传入明确的类别,例如 "objects" 或 "text"。清单为空时通常会打印 no elements detected 并以 0 退出;使用 --fail-on-empty 则会打印 stderr 诊断信息且不输出 stdout,并以 1 退出。这表示模型返回结果为空,并不能证明图像中没有匹配的元素。
使用 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"
手动模式会保留区域中所有足够大的连通分量(分离的 Logo 子形状会保留在一起;小斑点会被剔除)。自动模式接收以图标为中心的 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