web-dev-qa-db-ja.com

OpenCVスローエラーでのBFMatcherの一致

画像照合に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.png

box_in_scene.png

box_in_scene.png

LinuxではPython 3.5.2およびOpenCV 3.1.xを使用しています。

14
motiur

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を使用してインストール]。

7
saurabheights

同じエラーが発生しました。しかし、私の場合は、cv2.NORM_HAMMINGcv2.BFMatcher_createメトリックでSIFTを使用していたためです。指標をcv2.NORM_L1に変更すると、問題が解決しました。

BFMatcher の引用ドキュメント:

normTypeNORM_L1NORM_L2NORM_HAMMINGNORM_HAMMING2のいずれか。 L1およびL2ノルムは、SIFTおよびSURF記述子に適した選択肢です。NORM_HAMMINGはORB、BRISK、およびBriefとともに使用する必要があり、NORM_HAMMING2はORBとともにWTA_K==3または4ORB::ORBコンストラクターの説明を参照)。

3
Georgy

同じエラーが発生することがわかりました。理解するのにしばらく時間がかかりました-私の画像の一部は少し特徴がなく、したがってキーポイントが見つかりませんでした、そしてdetectAndComputeは記述子に対してNoneを返しました。 BFMatcher.add()に渡す前に、None要素の記述子のリストを確認する価値があるかもしれません。

3
eldorz

編集:使用するバージョン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")
  1. マッチャーオブジェクトの作成

    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)
    
  2. フレームをキャプチャして処理している間

    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)
    
1
Ali Eren Çelik