【Python/OpenCV】コラージュ画像を自動分割!AI(VLM)とルールベースを組み合わせたハイブリッドアプローチの挑戦

こんにちは、開発チームです。本日はフィギュア画像のデータセット作成において、複数のアングルが1枚にまとめられた「コラージュ画像」の自動分割に取り組みました。

背景

スクレイピング収集した画像の中には、全身図、顔アップ、背面図などが1枚の画像にタイル状に配置されているものがあります。これを検索システム(ベクトル検索)で精度良く扱うためには、個別の画像(Single View)に切り出す必要があります。

アプローチ1:VLM (Visual Language Model) による座標推定

最初は「今のAIなら画像のどこに何があるかわかるだろう」と考え、ローカルLLM環境(Ollama)上の Qwen3-VLGemma3 に画像の切り出し座標(Bounding Box)を聞いてみました。

結果:構成はわかるが、座標は苦手

  • Qwen3-VL: 「左に全身、右上に顔、右下に背面」といった構成の理解力は抜群。しかし、正確な座標を出力させようとすると不安定。
  • Gemma3: 座標は返すが、「画像のちょうど半分」といった単純な推測値になりがちで、ピクセル単位の正確なクロップには使えませんでした。

アプローチ2:OpenCVによるルールベース分割

そこで、画像の境界線を検出して切る、古典的かつ高速な OpenCV を採用しました。

試行錯誤のプロセス

  1. v1 (背景除去): 白背景なら分離できるが、画像同士が隙間なく接しているコラージュには無力。
  2. v3 (グリッド検出): Hough変換で直線を検出。単純な格子状なら良いが、非対称なレイアウト(左1枚、右2枚など)に対応できず。
  3. v4 (再帰分割): 画像を再帰的に分割するロジックを実装。これで「左を切って、残った右をさらに上下に切る」が可能に。

課題:過剰分割と過小分割のジレンマ

パラメータ(線の検出感度やマージン)を調整する中で、難しい問題に直面しました。

  • 258番の画像(複雑なコラージュ):感度を上げないと切れないが、上げると画像内部の模様で過剰に切れてしまう(バラバラになる)。
  • 281番の画像(単純な3分割):中央の分割線が検出されにくく、感度を下げると切れない。

この「あちらを立てればこちらが立たず」の状況を打破するために、v5 では「画像中央付近の分割線を優先する(マージン40%)」というロジックを導入し、なんとか実用的な落とし所を見つけました。

ブレイクスルー:AIによる事後検証 (Verify)

パラメータ調整だけでは限界があるため、新たなアプローチとして「AIによる事後検証(Human-in-the-loopならぬAI-in-the-loop)」を導入しました。

OpenCVで分割した結果の画像を、再度 Qwen3-VL に投げ、以下の質問をします。

「この画像は1枚の絵として成立していますか?(Single)それとも、まだ複数の絵が混ざっていますか?(Collage)」

これにより、OpenCVが切り漏らした「Collage」画像を特定し、それだけを対象にパラメータを緩めて再分割するというループが可能になります。検証の結果、Qwen3-VLはこの判定を非常に高い精度で行えることがわかりました。

まとめ

  • 座標指定はOpenCV:ピクセル単位の正確な処理はルールベースが強い。
  • 判断はAI:画像の構成理解や品質チェックはVLMが強い。

これらを組み合わせることで、高速かつ柔軟な画像処理パイプラインが構築できました。

参考リンク


記事作成:Gemini 3