画像結合のためのアルゴリズムを考えてみた
はじめに
撮りたい対象が非常に大きい時、一枚の写真では収まりきらないケースというのはよくあります。そのような時に、複数の写真を結合して一枚の写真にしなければ、画像として視認性が低くなってしまいます。この記事では、そのようなケースに対応するための画像結合のためのアルゴリズムを考え、Pythonで実装してみました。提案アルゴリズムは、「入力画像の共通部分を事前情報なしで検出し、自動的に結合する」ことが可能です。
作成したソースコードについてはGitHubにて公開しています。興味のある方は以下のリンクからご覧ください。
出力例
以下に、アルゴリズムを用いて結合した出力例を示します。初めに、アルゴリズムに入力する画像の例を添付します。具体的には、以下に示す2枚の画像の結合を行います。画像については、CIFAR-10データセットの中から選択しました。
図中の赤いエリアは、データが存在しない部分を表しています。また、右側の画像は、正解画像に比べて90度回転しています。開発したアルゴリズムは、この回転を加味して画像を結合することが可能です。
続いて、右画像の回転を補正し、左右の向きを揃えた結果が上図の通りです。緑色の枠で囲まれている部分が、アルゴリズムが自動的に検知した共通部分です。また、タイトル中に記載されている角度(上図では270°)が、アルゴリズムが検出した回転すべき最適な角度を意味しています。入力画像は、元データを90°回転させていることから、最適な角度を検出できていることがわかると思います。
そして、最終的に結合した結果が上図の通りです。アルゴリズムは、入力画像の共通部分を事前情報なしで検出し、自動的に結合することが可能であることが、この例から直感的に理解していただけると思います。
なお、他の実験結果例については、ここでは省略しますが、GitHubの tutorial.ipynb にて公開しているので、興味のある方はそちらをご覧ください。
アルゴリズムの概要
以下では、提案アルゴリズムの概要を説明します。
1. 共通部分探索
概要図は上記のとおりです。提案アルゴリズムは、
- Image1の左上とImage2の右下の重複部分
- Image1の右上とImage2の左下の重複部分
- Image1の左下とImage2の右上の重複部分
- Image1の右下とImage2の左上の重複部分(上図に対応)
これらにより、特定の共通部分に対して、4箇所を探索することで、過不足なく共通部分を検索することが可能です。
for hc in range(min_h, max(h1, h2) + 1):
for wc in range(min_w, max(w1, w2) + 1):
for ix in range(2):
for iy in range(2):
上記のコードのix
とiy
の組み合わせが、上記の4箇所に対応しています。
局所解に対する対策
画像結合において、局所解への収束は、品質の低い画像提供を意味します。このような問題を防ぐために、提案アルゴリズムは共通部分の最小値を設定することが可能です。共通部分のサイズをベースとした全探索を用いたことで、このような問題に簡単に対応可能です。
画像の回転に対する対策
画像の回転に対しては、探索アルゴリズムを適用する前に片方の入力画像 (Image2) を回転させるというシンプルな方法で対処しています。
for angle in [0, 90, 180, 270]:
# 画像を回転
_image2 = rotate(image2, angle, resize=True, preserve_range=True).astype(np.uint8)
2. 共通部分の拡張
上記で説明したアルゴリズムは、共通部分のサイズが
まとめ
本記事では、画像結合のためのアルゴリズムを提案し、Pythonで実装してみました。提案アルゴリズムは、入力画像の共通部分を事前情報なしで検出し、自動的に結合することが可能です。また、提案アルゴリズムは、局所解への収束や画像の回転に対しても対処可能です。最後に、提案アルゴリズムの概要を説明し、その有効性を出力例を基に明らかにしました。
追記
2024/10/01: 200+ GitHub Stars🌟 を頂きました。ありがとうございます!
Discussion