web-dev-qa-db-ja.com

OpenCV(Python)を使用して複数の画像を合成する

こんにちは、2枚の写真を使用して簡単な画像合成を行う方法のチュートリアルをたくさん見ましたが、それは問題ありません。
しかし、4〜6枚以上の画像からパノラマを作成したい場合はどうすればよいですか?

画像ファイルのリストを取り込むコードがあります(画像は、シーケンスの最初の画像から最後の画像の順になっています)。次に、各画像についてSIFT機能記述子を計算します。しかし、それから私は立ち往生しています。2つの画像の場合、FLANN kd-treeを使用してマッチャーを設定し、画像間の一致を見つけてホモグラフィを計算します。このチュートリアルと同様 http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html#py-feature-homography

しかし、最後に特徴点間の線を表示する代わりに、これを使用しました https://stackoverflow.com/a/20355545/622194 関数を使用して、2つの画像からパノラマを作成しました。しかし、3枚目と4枚目の画像をパノラマに追加したい場合、どうすればよいかわかりません。

編集:

答えから、私はイメージスティッチングスクリプトを実装して、イメージシーケンスで隣り合うイメージ間のホモグラフィマトリックスを計算しようとしました。つまり、I1、I2、I3、I4がある場合は、H_12、H_23、H_34になります。次に、H_12を使用してI1とI2をステッチすることから始めます。次に、累積ホモグラフィを見つけて、I3を現在のパノラマにステッチします。 H_13 = H_12 * H_23で画像3を現在のパノラマにステッチしますが、ここでパノラマ画像に非常に明らかなギャップが生じ、次の画像がステッチされると、ギャップがさらに大きくなり、画像が非常に引き伸ばされます。これが私のコードです http://Pastebin.com/dQjhE5VD

私がこれに適切なアプローチを使用しているかどうか誰かが教えてもらえますか、誰かがエラーを見つけたり、私が間違っていることを見ることができます.

15
krunarsson

4つの画像I0、I1、I2、I3をつなぎ合わせたい場合、段階的に、ホモグラフィH_0、H_1、H_2、H_3を計算します。

  1. すべてのペアワイズホモグラフィH_01、H_02、H_03、H_12、H_13、H_23を計算します。ホモグラフィH_01は画像I0をI1にワープします...
  2. アンカー画像を1つ選択します。 I1の位置は固定されたままです。つまり、H_1 = Identity
  3. 一貫性のある一致の最大数に基づいて、I1によりよく一致する画像を見つけます。 I3
  4. 更新H_3 = H_1 * inv(H_13)= inv(H_13)= H_31
  5. I1またはI3に一致する画像を見つけます(例:I3に一致するI2)
  6. 更新H_2 = H_3 * H_23
  7. 画像I0について上記と同じ
  8. バンドル調整を行って、アライメントをグローバルに最適化する

詳細な説明については、この重要な論文のセクション4を参照してください 不変の機能を使用した自動パノラマ画像合成

12
memecs

ハッキーなアプローチ

あなたが書いた関数を考えると、(超効率的ではありませんが)最も簡単な方法は、連続する各画像とつなぎ合わせてパノラマ画像を拡大することです。この疑似コードのようなもの:

panorama = images[0]
for i in 1:len(images)-1
    panorama = stitch(panorama,images[i])

このメソッドは基本的に、次の画像を現在のパノラマの任意の部分に一致させようとします。新しい各画像が現在のパノラマの境界線上のどこかにあり、遠近法による歪みがあまりないと仮定すると、それはきちんと機能するはずです。

数学的アプローチ

ステッチする順序がわかっている場合のもう1つのオプションは、ある画像から次の画像へのホモグラフィを見つけて、それらを乗算することです。結果は、その画像から画像0へのホモグラフィです。

たとえば、画像3を画像0に合わせて変換するHは、H_03 = H_01 * H_12 * H_23です。ここで、H_01は、画像1を変換して画像0と一致させるHです(コードがHを定義する方法によっては、上記の乗算順序を逆にする必要がある場合があります)。乗算してH_0iを取得し、それを使用して変換します。画像0に合わせる画像i。

変換を乗算する理由の背景については、次を参照してください 変換と行列乗算 特に「変換の構成」の部分。

4
Luke

画像間のギャップに関する同様の問題がありました。最初に行うべきことは、最初のフレームで識別するために、蓄積されたホモグラフィ行列を初期化することです。次に、新しいフレームごとに、現在のフレームと次のフレームの間のホモグラフィ行列を掛けます。 numpy配列ではなく、numpy行列を使用することに注意してください。 IDK理由ですが、乗算ルーチンが異なります。

これが私のコードです:

def addFramePair(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):        
    (imageA, imageB) = images
    (kpsA, featuresA) = self.detectAndDescribe(imageA)
    (kpsB, featuresB) = self.detectAndDescribe(imageB)

    H = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
    self.accHomography *= np.asmatrix(H)
    result = cv2.warpPerspective(imageA, np.linalg.inv(self.accHomography), (1600, 900))
    return result

imageAが現在のもので、imageBが次のものです。

お役に立てれば。

1
Borys Tymchenko