mcpField
V
vision-skills

vision-skills

github.com/anionex创意与媒体1.3k79 次安装2 周前更新
代码仓库

关于 vision-skills

vision-skills 是一组用于图像检查、几何处理、OCR、裁剪和比较的本地 CLI 与脚本,面向处理图像的文本型 Agent。它结合视觉模型查询与基于像素的操作。

主要功能

  1. 01使用 glance 描述图像并进行 OCR
  2. 02定位目标并枚举元素
  3. 03基于像素描摹形状与裁剪
  4. 04长截图 OCR 工作流
  5. 05图像差异与颜色分析
  6. 06将 HTML 渲染为截图

适用场景

  1. 01读取截图文字或检查细节
  2. 02查找并裁剪指定的界面元素
  3. 03比较截图并定位变化
  4. 04渲染 HTML 以进行视觉检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anionex/agent-vision-toolkit --skill vision-skills

安装后在 Claude Code 中输入/vision-skills确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
gui.md
long-screenshot-ocr.md
restore-graphic.md
restore-structure.md
restore-ui.md
scripts/
dominant_colors.py
extract_fg.py
html_shot.py
long_screenshot_ocr.py
pixel_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 "..."

例外:用户要求将图像保留在临时文件夹中。

你拿到的是描述而不是图像时

如果你只通过文本获得图像——例如由人、工具或其他模型撰写的描述——而且对话中能看到图像的文件路径,不要根据缺失的细节进行推测。亲自再查看一遍:

  1. glance <path> -q "<the specific detail>" — 进行一次定性追问。
  2. ground <path> "<target>",然后执行 glance <path> --region <that box> -q "..." — 定位后放大。这是仔细检查单个元素的可靠方法。

如果文件已不存在,请如实说明,不要猜测。

由粗到细——上述所有任务背后的方法

对于有关图像的单个问题,glance 就能给出完整答案。对于任何多步骤任务,都应由外向内进行:

  1. 先完整查看一次图像(使用 glance,或查看已有描述),了解布局并盘点各元素的位置。
  2. 对于任何重要元素,先用 ground 定位,再通过 glance --region <box> -q "..." 放大查看。完整图像的查看经常会漏掉小字和图标;裁剪后,所有像素都集中在一个细节上,因此模型能以更高的有效分辨率查看它。如果需要多次检查同一个框,先用 crop 将其裁剪到文件中。
  3. 对像素级事实(精确颜色、细微偏移、尺寸),绝不要只相信文字描述——视觉模型可能会自信地报告实际并不存在的样式,例如黑白代码块中的彩色语法高亮,或根本不存在的边框。应从 trace、ground 框或 pixel_diff 获取数值;只有这些方法无法提供时,才自行采样像素。

使用场景

以下每个文件对应一项完整任务:说明适用情况、调用顺序,以及如何判断任务是否成功。

任务阅读
对长截图、滚动页面或聊天记录进行 OCR,避免在分块边界处丢失文本references/long-screenshot-ocr.md
将页面或组件重建为 HTML/CSS,包括约三分钟的快速近似模式;或根据参考图对齐现有 UIreferences/restore-ui.md
将图标、徽标、插画或其他独立图形提取或重建为透明 PNG/SVGreferences/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

评论

支持 Markdown