web-dev-qa-db-ja.com

複数の画像のOpenCV機能マッチング

FLANNを使用して多くの画像のSIFT特徴マッチングを最適化するにはどうすればよいですか?

Python OpenCVドキュメントから取得した実用的な例があります。ただし、これは1つの画像を別の画像と比較しているため、時間がかかります。一連の画像(数千)で一致する特徴を検索するために必要です。 )そして私はそれをより速くする必要があります。

私の現在の考え:

  1. すべての画像を実行し、機能を保存します。どうやって?
  2. カメラからの画像を上のベースと比較して、正しいものを見つけてください。どうやって?
  3. 結果、一致する画像などを教えてください。

http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_feature_homography/py_feature_homography.html

 import sys#デバッグ専用
 import numpy as np 
 import cv2 
 from matplotlib import pyplot as plt 
 
 MIN_MATCH_COUNT = 10 
 
 img1 = cv2.imread( 'image.jpg'、0)#queryImage 
 img2 = cv2.imread( 'target.jpg'、0)#trainImage 
 
#SIFT検出器を開始します
 sift = cv2.SIFT()
 
#SIFT 
 kp1、des1でキーポイントと記述子を見つけます= sift.detectAndCompute(img1、None)
 kp2、des2 = sift.detectAndCompute(img2、None)
 
 FLANN_INDEX_KDTREE = 0 
 index_params = dict(algorithm = FLANN_INDEX_KDTREE、trees = 5)
 search_params = dict(checks = 50)
 
 flann = cv2.FlannBasedMatcher(index_params、search_params)
 
一致= flann.knnMatch(des1、des2、k = 2)
 
#Loweの比率テストに従ってすべての良い一致を保存します。
 good = [] 
 for一致するm、n:
 if m.distance MIN_MATCH_COUNT:
 src_pts = np.float32([kp1 [m.queryIdx] .pt for m in good])。reshape(-1,1,2)
 dst_pts = np.float32([kp2 [m.trainIdx] .pt for m in good])。reshape(-1,1,2 )
 
 M、マスク= cv2.findHomography(src_pts、dst_pts、cv2.RANSAC、5.0)
 matchesMask = mask.ravel()。tolist()
 
 h、w = img1.shape 
 pts = np.float32([[0,0]、[0、h-1]、[w-1、h-1]、[w -1,0]])。reshape(-1,1,2)
 dst = cv2.perspectiveTransform(pts、M)
 
 img2 = cv2.polylines(img2、 [np.int32(dst)]、True、255,3、cv2.LINE_AA)
 
 else:
 print "十分な一致が見つかりません-%d /%d" %(len(good)、MIN_MATCH_COUNT)
 matchesMask = None 
 
 draw_params = dict(matchColor =(0,255,0)、#一致を緑色で描画
 singlePointColor = None、
 matchsMask = matchesMask、#インライアのみを描画
 flags = 2)
 
 img3 = cv2.drawMatches(img1、kp1、img2、kp2、 good、None、** draw_params)
 
 plt.imshow(img3、 'gra y ')、plt.show()

[〜#〜]更新[〜#〜]

多くのことを試した後、私は今解決策に近づいたかもしれません。インデックスを作成して、次のように検索できることを願っています。

 flann_params = dict(algorithm = 1、trees = 4)
 flann = cv2.flann_Index(npArray、flann_params)
 idx、dist = flann.knnSearch(queryDes、1、params = {})

ただし、受け入れられたnpArrayをflann_Indexパラメーターに構築することはまだできていません。

すべての画像を画像としてループします:
 npArray.append(sift.detectAndCompute(image、None))
 npArray = np.array(npArray)
8
Jafu

私はこれをPythonで解決したことはありませんが、環境をC++に切り替えました。この場合、OpenCVの例が増え、ドキュメントの少ないラッパーを使用する必要がなくなります。

複数のファイルでのマッチングに関する問題の例は、次の場所にあります: https://github.com/Itseez/opencv/blob/2.4/samples/cpp/matching_to_many_images.cpp

4
Jafu

@ stanleyxu2005の返信に加えて、私は現在そのようなことをしているので、マッチング全体を行う方法についていくつかのヒントを追加したいと思います。

  1. Cv :: Matをラップするだけでなく、他のさまざまな重要なデータも格納するカスタムクラスを作成することを強くお勧めします。私の場合、ImageContainerに元の画像(最終的なステッチに使用します)、処理された画像(グレースケール、歪みなしなど)、そのキーポイント、およびそれらの記述子を保存します。そうすることで、非常によく整理された状態で、一致するすべての関連情報にアクセスできます。キーポイントの抽出と記述子の生成をその中に実装するか、クラスの外部でそれを実行して、結果をそのコンテナーに格納することができます。
  2. 簡単にアクセスできるように、すべての画像コンテナを何らかの構造(通常はベクトルが適切な選択)に格納します。
  3. また、ImageMultiMatchContainerというクラスを作成しました。このクラスは、特定のクエリ画像(すべての画像はクエリ画像)へのポインタ、すべてのトレイン画像(画像セットの単一のクエリ画像の場合は他のすべてはトレイン画像)へのポインタを持つベクトルを格納します。それに一致し、それらの各一致の一致ベクトルのベクトルも一致しました。ここで私はストレージの問題に遭遇しました。つまり、最初に画像とそれ自体の照合をスキップする必要があります。これは無意味であるためです。次に、2つの画像を2回比較する問題があり、画像が多い場合はかなりのオーバーヘッドが発生します。 2番目の問題は、すべての画像(クエリ画像)を反復処理し、それらをセット内の残りの画像(トレイン画像)と比較するという事実によるものです。ある時点で、画像X(クエリ)が画像Y(電車)と一致しますが、後で画像Y(現在のクエリ)も画像X(現在の電車)と一致します。ご覧のとおり、これも基本的に同じ画像のペアを2回照合するため、意味がありません。これは、一致したペアの2つの画像のそれぞれへのポインターと一致ベクトルを格納するクラス(MatchContainer)を作成することで解決できます(現在これに取り組んでいます)。これを中央の場所(私の場合はこれが私のマッチャークラス)に保存し、クエリ画像としての各画像について、電車の画像の一致した画像のリストを確認します。空の場合は、新しいMatchContainerを作成し、残りのMatchContainerに追加します。そうでない場合は、それを調べて、現在のクエリ画像がそこに存在しないかどうかを確認します(ポインタの比較は高速な操作です)。その場合は、これら2つの画像の一致を格納するMatchContainerのベクターアイテムへのポインターを渡すだけです。そうでない場合は、空であるかのように行い、新しいMatchContainerなどを作成します。MatchingContainerは、多くのことを確認し、最初から最後までコストを繰り返すため、アクセス時間が短いデータ構造に格納する必要があります。たくさんの時間。地図の使用を検討していますが、ある種の木がいくつかの利点を提供できるかもしれません。
  4. ホモグラフィの推定は非常に難しい部分です。ここでは、バンドルブロック調整を確認することをお勧めします。 OpenCVのスティッチャークラスにはBundleBaseクラスがあることがわかりましたが、何が含まれているかを確認するためにまだテストしていません。

一般的な推奨事項は、OpenCVのステッチングプロセスを確認し、ソースコードを読むことです。スティッチングパイプラインは単純な一連のプロセスであり、単一のステップをどの程度正確に実装できるかを確認する必要があります。

3
rbaleksandar

これが私のアドバイスのいくつかです:

  1. 適切な手法を使用して、ポイントデータの量を減らす必要があります。
  2. 参照画像を繰り返し計算するのは無駄です。計算されたすべての参照を永続化する必要があります。
  3. 計算をモバイルデバイスに配置しないでください。キャプチャされた画像の計算された参照を強力なサーバーにアップロードし、そこで検索することをお勧めします。

これは非常に興味深いトピックです。私の耳も開いています。

3
stanleyxu2005