ANTIGRAVITY LABEN
記事一覧/連携・プラグイン
連携・プラグイン/2026-07-07上級

サムネイルの見た目が少しずつズレていた — pHash と SSIM で画像アセットの回帰をエージェント運用に組み込む

エージェントに画像パイプラインを書き換えさせた後の「静かな見た目のズレ」を、pHash と SSIM という二つの数値で検知して CI で止める実装をまとめました。壁紙サムネイルや OGP 画像を対象に、しきい値の決め方からゲートスクリプト、Antigravity への組み込みまで扱います。

antigravity420image-regressionphashssimci-cd15premium15

プレミアム記事

import RelatedArticles from "@/components/RelatedArticles";

個人開発で運営している壁紙アプリのサムネイルが、いつの間にか少しだけ眠くなっていました。

きっかけは、Antigravity のエージェントに「サムネイル生成をもう少し速くしてほしい」と頼んだことでした。エージェントは Pillow のリサンプリング方法を差し替え、JPEG の品質パラメータを調整し、処理時間を三割ほど縮めてくれました。差分を眺めても妥当な変更に見えます。テストも通っています。私はそのままマージしました。

数日後、ストアの新着一覧を眺めていて、グラデーションの縁にうっすらとバンディング(階調の段差)が出ていることに気づきました。ユーザーからの苦情はありません。けれど、確かに前より粗い。原因はあのリサンプリング変更でした。動作は壊れていない、けれど見た目だけが静かに後退していた——このタイプの後退は、assert では捕まえられません。

サムネイルは App Store と Google Play の新着一覧、そして OGP 画像として人目に触れ、AdMob 収益につながるインストールの入口でもあります。見た目の後退は、静かにインストール率を削るのです。

ここで扱うのは、その「見た目の後退」を一つの数値に落とし込み、エージェントの変更を CI でせき止める設計です。pHash と SSIM という二つのものさしを使い分けながら、生成済み画像アセットの回帰を機械的に検知する仕組みを、私自身の運用を下地に組み立てていきます。

なぜ「完全一致」でも「目視」でもうまくいかないのか

最初に思いつくのは、生成結果のハッシュを取って完全一致で比べる方法です。しかしこれはすぐに破綻します。JPEG エンコーダのバージョンが一つ上がるだけでバイト列は変わりますし、EXIF のタイムスタンプ、カラープロファイルの埋め込み、圧縮テーブルのわずかな違い——どれも「見た目は同じなのにバイトは違う」状況を作ります。md5 ゲートは、意味のない差分で毎回赤くなり、やがて誰も見なくなります。

反対に、目視レビューは続きません。サムネイルが数十枚ならまだしも、解像度バリアントまで含めれば数百枚になります。人間の目は、隣り合わせに並べれば 5% の劣化に気づきますが、単体で見せられると 15% でも見逃します。しかも毎回のリリースで全部を並べて確認する集中力は、二週間ももちません。

必要なのは、その中間にある「知覚的な近さ」を数値化するものさしです。バイト単位ではなく、人間が見て同じに見えるかどうかに近い指標。ここで pHash(知覚ハッシュ)と SSIM(構造的類似度)が効いてきます。

手法拾えるもの見落とすもの向いている用途
バイト一致(md5)完全な同一性見た目が同じでも別物と判定キャッシュキー・重複排除
pHash構図・明暗の大きな変化局所的なノイズ・バンディング「別の画像に化けた」の検知
SSIM局所的な質感・階調の劣化全体を平行移動した変化に弱い「同じ構図で品質が落ちた」の検知

この表のとおり、pHash と SSIM は得意分野が異なります。私は最終的に両方を併用する形に落ち着きました。片方だけでは、私を最初に困らせたバンディングを取りこぼしていたからです。

pHash でズレを一つの数値にする

pHash は、画像を小さなグレースケールに縮小し、離散コサイン変換(DCT)の低周波成分から 64 ビットの指紋を作ります。二枚の画像が知覚的に近ければ、指紋のビットもほとんど一致します。差の大きさは「ハミング距離」——何ビット違うか——で測れます。

Python では imagehashPillow で数行です。

from PIL import Image
import imagehash
 
def phash_distance(path_a: str, path_b: str) -> int:
    """2枚の画像の知覚ハッシュのハミング距離を返す。0=ほぼ同一。"""
    hash_a = imagehash.phash(Image.open(path_a))
    hash_b = imagehash.phash(Image.open(path_b))
    return hash_a - hash_b  # ImageHash 同士の減算がハミング距離
 
if __name__ == "__main__":
    d = phash_distance("baseline/thumb_001.jpg", "candidate/thumb_001.jpg")
    print(f"pHash distance = {d}")

imagehash.phash が返す ImageHash オブジェクトは、- 演算子でそのままハミング距離になります。ここが imagehash の気持ちよいところで、自前でビットを数える必要はありません。

なぜ pHash が「別の画像に化けた」を得意とするかというと、DCT の低周波成分は画像全体の大まかな構図や明暗の配置を表すからです。サムネイルの被写体が入れ替わったり、切り抜き位置が動いたりすると、この成分が大きく変わり、ハミング距離が跳ね上がります。逆に、圧縮率がわずかに変わった程度では低周波成分はほとんど動きません。だからこそ、意味のない差分で赤くならずに済みます。

私が実際の壁紙サムネイル 300 枚で「変更なし再エンコード」を測ったところ、ハミング距離はほぼ 0〜2 に収まりました。一方、被写体を差し替えたテスト画像では 18〜30 まで開きます。この分布の広さが、しきい値を引く余地になります。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
エージェントに画像処理を触らせた後の「静かな見た目のズレ」を、pHash のハミング距離という一つの数値で検知できるようになります
完全一致では厳しすぎ、目視では続かない、その中間を SSIM としきい値設計で埋める実運用パターンを持ち帰れます
生成済みのサムネイルや OGP 画像を対象に、明日から動かせる Python のゲートスクリプトと GitHub Actions 断片をそのまま使えます
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

連携・プラグイン2026-06-17
axe-core の検出をエージェントに渡して直す — アクセシビリティ改善を CI に組み込む実装メモ
axe-core で検出したアクセシビリティ違反を Antigravity のエージェントに渡し、検出→トリアージ→修正→再検証のループを CI に組み込む実装メモです。新規違反だけを止める差分ゲートと、エージェントの修正範囲を絞る設計を本番運用の形でまとめました。
連携・プラグイン2026-05-01
Antigravity × Lighthouse CI で Web パフォーマンス劣化を自動検出する — 予算・PR コメント・段階的ブロッキング戦略
Antigravity の AI と Lighthouse CI を GitHub Actions で結合し、パフォーマンス劣化を本番に出る前にせき止める実装ガイドです。予算設計から PR コメント、段階的ブロッキングまで本番運用で使える形でまとめました。
連携・プラグイン2026-03-27
Antigravity × GitHub で Pull Request レビューを AI 自動化する実践ガイド
Antigravity の AI エージェントを活用して GitHub Pull Request のコードレビューを自動化する方法を、環境構築からワークフロー設計まで丁寧に解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →