画像照合にSURF記述子を使用しています。特定の画像を画像のデータベースと照合することを計画しています。
import cv2
import numpy as np
surf = cv2.xfeatures2d.SURF_create(400)
img1 = cv2.imread('box.png',0)
img2 = cv2.imread('box_in_scene.png',0)
kp1,des1 = surf.detectAndCompute(img1,None)
kp2,des2 = surf.detectAndCompute(img2,None)
bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=True)
#I am planning to add more descriptors
bf.add(des1)
bf.train()
#This is my test descriptor
bf.match(des2)
問題はbf.match
は、次のエラーが発生することです。
OpenCV Error: Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)) in batchDistance, file /build/opencv/src/opencv-3.1.0/modules/core/src/stat.cpp, line 3749
Traceback (most recent call last):
File "image_match4.py", line 16, in <module>
bf.match(des2)
cv2.error: /build/opencv/src/opencv-3.1.0/modules/core/src/stat.cpp:3749: error: (-215) type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U) in function batchDistance
エラーは this postに似ています。与えられた説明は不完全で不十分です。この問題を解決する方法を知りたいです。私はORB記述子も使用しており、BFMatcherにはNORM_HAMMING
距離。エラーが再び発生します。どんな助けでもありがたいです。
これに使用した2つの画像は次のとおりです。
box.png
box_in_scene.png
LinuxではPython 3.5.2およびOpenCV 3.1.xを使用しています。
2つの画像の記述子間を検索するにはを使用します。
img1 = cv2.imread('box.png',0)
img2 = cv2.imread('box_in_scene.png',0)
kp1,des1 = surf.detectAndCompute(img1,None)
kp2,des2 = surf.detectAndCompute(img2,None)
bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=False)
matches = bf.match(des1,des2)
複数の画像を検索するには
add
メソッドは、複数のテスト画像の記述子を追加するために使用されます。すべての記述子にインデックスが付けられたら、train
メソッドを実行して基礎となるデータ構造を構築します(例:FlannBasedMatcherの場合に検索に使用されるKdTree)。次に、match
を実行して、どのテストイメージがどのクエリイメージに近いかを確認できます。 K-d_tree を確認して、多次元ベクトルを検索するためにどのように使用できるかを確認できます(Surfは64次元ベクトルを提供します)。
注:-名前が示すように、BruteForceMatcherには内部検索最適化データ構造がないため、空のtrainメソッドがあります。
複数画像検索のコードサンプル
import cv2
import numpy as np
surf = cv2.xfeatures2d.SURF_create(400)
# Read Images
train = cv2.imread('box.png',0)
test = cv2.imread('box_in_scene.png',0)
# Find Descriptors
kp1,trainDes1 = surf.detectAndCompute(train, None)
kp2,testDes2 = surf.detectAndCompute(test, None)
# Create BFMatcher and add cluster of training images. One for now.
bf = cv2.BFMatcher(cv2.NORM_L1,crossCheck=False) # crossCheck not supported by BFMatcher
clusters = np.array([trainDes1])
bf.add(clusters)
# Train: Does nothing for BruteForceMatcher though.
bf.train()
matches = bf.match(testDes2)
matches = sorted(matches, key = lambda x:x.distance)
# Since, we have index of only one training image,
# all matches will have imgIdx set to 0.
for i in range(len(matches)):
print matches[i].imgIdx
Bf.matchのDMatch出力については、 docs を参照してください。
これの完全な例は、こちら Opencv3.0 docs を参照してください。
その他の情報
OS:Mac。
Python:2.7.10。
Opencv:3.0.0-dev [正しく覚えていれば、brewを使用してインストール]。
同じエラーが発生しました。しかし、私の場合は、cv2.NORM_HAMMING
のcv2.BFMatcher_create
メトリックでSIFTを使用していたためです。指標をcv2.NORM_L1
に変更すると、問題が解決しました。
BFMatcher の引用ドキュメント:
normType
–NORM_L1
、NORM_L2
、NORM_HAMMING
、NORM_HAMMING2
のいずれか。L1
およびL2
ノルムは、SIFTおよびSURF記述子に適した選択肢です。NORM_HAMMING
はORB、BRISK、およびBriefとともに使用する必要があり、NORM_HAMMING2
はORBとともにWTA_K==3
または4
(ORB::ORB
コンストラクターの説明を参照)。
同じエラーが発生することがわかりました。理解するのにしばらく時間がかかりました-私の画像の一部は少し特徴がなく、したがってキーポイントが見つかりませんでした、そしてdetectAndCompute
は記述子に対してNone
を返しました。 BFMatcher.add()
に渡す前に、None
要素の記述子のリストを確認する価値があるかもしれません。
編集:使用するバージョンPython 3.6、OpenCV 3.4.1
[〜#〜] sift [〜#〜]または[を使用するプログラムを準備する間、私は多くの苦労しました〜#〜] orb [〜#〜]ユーザーの選択に応じて。最後に、BFMatcherの正しいパラメーターを[〜#〜] sift [〜#〜]および[〜#〜] orb [〜#〜]
import cv2
import numpy as np
# ask user whether to use SIFT or ORB
detect_by = input("sift or orb")
マッチャーオブジェクトの作成
if detect_by == "sift":
matcher = cv2.BFMatcher(normType=cv2.NORM_L2, crossCheck=False)
Elif detect_by is "orb":
matcher = cv2.BFMatcher(normType=cv2.NORM_HAMMING, crossCheck=False)
フレームをキャプチャして処理している間
while there_is_frame_to_process:
if detect_by is "sift":
matches = matcher.knnMatch(np.asarray(gray_des, np.float32), np.asarray(target_des, np.float32), k=2)
Elif detect_by is "orb":
matches = matcher.knnMatch(np.asarray(gray_des, np.uint8), np.asarray(target_des, np.uint8), k=2)