vision-skills について
vision-skillsは、画像の確認、形状処理、OCR、切り抜き、比較を行うローカルCLIとスクリプトをまとめたスキルです。画像を扱うテキストベースのエージェント向けに、ビジョンモデルとピクセル処理を組み合わせています。
主な機能
- 01glanceによる画像説明とOCR
- 02対象の位置特定と要素の列挙
- 03ピクセルベースの形状トレースと切り抜き
- 04長いスクリーンショットのOCR
- 05画像差分と色の分析
- 06HTMLから画像へのスクリーンショット生成
活用シーン
- 01スクリーンショットの文字や細部の確認
- 02指定したUI要素の特定と切り抜き
- 03スクリーンショットを比較して変更箇所を特定
- 04HTMLをレンダリングして視覚的に確認
インストール
コマンドをコピーしてターミナルで実行します。
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
テキストのみを扱うエージェントに目を与える、5 つのローカル CLI です。共通のビジョン設定(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 |
| 「アイコン/ロゴの前景を透過 PNG として抽出する — 手動で領域を指定、または自動抽出(切り抜き・拡大縮小済みのスクリーンショット)」 | scripts/extract_fg.py |
| 「この HTML ファイルをビューポートまたはフルページのスクリーンショットにする」 | scripts/html_shot.py |
| 「ある領域で優勢な色と、それに合うパレット値は?」 | scripts/dominant_colors.py |
| どのツールでも返せない関係 — 隙間や、位置が分かっている 2 つのものの間の距離 | ピクセルを使ったコード(Pillow) |
glance はそれが何かを、ground と detect はどこにあるかを答えます。
ground には特定のものの説明を渡し、detect には種類を渡すと、その種類のものを列挙します。
どちらも実際の座標を返しますが、ピクセル単位で正確ではありません。ボックスは 0〜1000 のグリッド上で返され、画像のサイズに合わせて拡大縮小されるため、最後の数ピクセルは信頼できません。切り抜きやクリック、位置の比較には十分な精度です。数値を正確に求める必要がある場合、trace は実際のピクセルからオフセット、サイズ、形状を導き出します。
手作業でピクセル処理を実装する前に、用意されたツールを使う
このツールキットにツールが用意されている処理は、すべてそのツールを呼び出してください。タスクの途中で Pillow を使って書き直さないでください。CLI を使えば、同じピクセル処理を毎回異なる方法で手作業で実装せずに済みます。
- 画像からボックスを切り出す →
Image.open(...).crop(...)ではなくcrop - 領域のパレットをサンプリングする →
scripts/dominant_colors.py - 2 つの画像を比較する →
scripts/pixel_diff.py - SVG にベクター化する →
trace - 要素を特定/一覧化する →
ground/detect - 画像を説明/OCR する →
glance - 長いスクリーンショットを安全に分割し、OCR して結合する →
scripts/long_screenshot_ocr.py - HTML ファイルをビューポートまたはフルページのスクリーンショットにする →
scripts/html_shot.py
手書きの Pillow コードを使うのは、既存のツールで返せない処理だけです。すでに特定した 2 つのものの間の関係(隙間や距離)、リサイズやオーバーレイ、描画などが該当します。上記のいずれかのツールで対応できるのに .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 で比較する場合は、すべてのパスを 1 回の呼び出しに渡してください。別々に呼び出すと両方の画像を同時に見られないため、2 つの説明を後から比較する方法では、比較ではなく幻覚の余地が 2 つ生まれます。--region を指定すると切り抜きだけがアップロードされるため、小さな文字やアイコンも読み取れるようになります。
ただし、「この 2 つの間で何が変わりましたか?」は glance に尋ねる質問ではありません。1 語だけのバッジやわずかな移動は、ビジョンモデルには丸め誤差のようなものですが、scripts/pixel_diff.py なら正確に検出できます。まず差分を取ってボックスを見つけ、そのボックスに対して glance --region を実行し、実際に何が変わったのかを読み取ってください。
縦長のスクロールするスクリーンショットでは、画像全体を 1 回の 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?"
この 2 段階の手順で、画像全体を処理しただけでは細かすぎて捉えられないものを調べられます。
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"
手動モードでは、領域内の十分な大きさの連結成分をすべて保持します(別々のロゴの形状はまとめて保持され、小さな点は除外されます)。自動モードでは、アイコンが中央に配置された crop --scale の切り抜きを使用します(円盤+グリフ)。円盤の中心は画像の中心で、円盤の半径はデフォルトで min(w,h)/2 * 0.6 です。円盤の色は中心の周囲のリングからサンプリングされ、その色を除外したうえで、色付きの上位 3 つの連結成分のうち最も彩度が高いものをグリフとして選びます(白いリング、波紋、テキストは除外されます)。出力は 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 — 2 つの画像の差異を確認します(ローカル、ビジョン 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
ビジョンモデルは「ライトグレー」のように色を表現しますが、具体的な値は示しません。最初のモードでは、縮小、量子化、近似色の統合を行い、各色の占有率とともに領域の主な色を一覧表示します。ヒストグラムで、背景色とアクセントカラーを確認できます。指定したラベルから候補のパレットを用意すると、2 つ目のモードで領域のピクセルとの近さを候補ごとにスコア化し、最も近い色を出力します。値は glance の文章ではなく、ここから取得してください。パスはこのスキルのディレクトリを基準とします。
一時パスではなく、コピーを使用してください
画像が一時ディレクトリにある場合は、その画像を使った最初のツール呼び出しの前に、永続的な場所へコピーし、以降はそのコピーを対象にすべての処理を実行してください。そうすることで、後からも画像にアクセスできます。
cp "<the temp path>" work/shot.png
glance work/shot.png -q "..."
例外:ユーザーが画像を一時フォルダーに置いたままにするよう求めている場合。
画像の代わりに説明がある場合
画像が、人、ツール、または別のモデルが書いた説明文としてのみ渡されていて、会話内に画像のファイルパスが表示されている場合は、不明な点を推測で補わず、もう一度自分で確認してください。
glance <path> -q "<the specific detail>"— 定性的な追加確認を 1 回行います。ground <path> "<target>"の後にglance <path> --region <that box> -q "..."— 対象を特定してから拡大します。要素を詳しく確認するための確実な方法です。
ファイルがもう存在しない場合は、推測せず、そのことを伝えてください。
全体から細部へ — 上記すべてのタスクで使う手法
画像についての質問が 1 つだけなら、glance だけで十分です。複数の手順が必要な場合は、外側から内側へ進めます。
- まず画像全体を 1 回確認し(
glanceを使うか、すでに説明があればそれを利用します)、レイアウトと各要素の位置を把握します。 - 重要な要素は
groundで特定し、glance --region <box> -q "..."で拡大します。画像全体の確認では、小さなテキストやアイコンを見落としがちです。切り抜くとピクセルを 1 つの要素に集中させられるため、モデルは実質的に高解像度で確認できます。同じボックスを複数回確認する場合は、まずcropでファイルに切り出してください。 - ピクセル単位の事実(正確な色、小さな位置のずれ、サイズなど)を、文章による回答だけで判断しないでください。ビジョンモデルは、存在しないスタイルを自信を持って報告することがあります。たとえば、単色のコードブロックに色付きの構文ハイライトがあるとしたり、実際には存在しない境界線を報告したりします。数値は
trace、groundのボックス、またはpixel_diffから取得してください。それらで取得できない場合に限り、自分でピクセルをサンプリングしてください。
ユースケース
以下の各ファイルでは、該当する状況、呼び出し手順、正しく完了したかを確認する方法を含め、1つの作業を最初から最後まで説明しています。
| 作業 | 参照先 |
|---|---|
| 長いスクリーンショット、スクロールするページ、チャット履歴を、チャンク境界でテキストを失わずに OCR する | references/long-screenshot-ocr.md |
| 約3分で仕上げる高速近似モードを使ってページやコンポーネントを 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 のみです。
- コマンドが見つからない場合は、オプションのツールがインストールされていません。代替手段を即興で用意するのではなく、その旨をユーザーに伝えてください。
- Vision API が失敗した場合は、エラーを忠実に伝えてください。画像の内容を捏造してはいけません。
ソースリポジトリ:https://github.com/Anionex/agent-vision-toolkit
インストールガイド:https://github.com/Anionex/agent-vision-toolkit/blob/main/AGENT_INSTALL.md