2012-06-20 10 views
8

私はpythonでopencvを使用しようとしています。私はopencv 2.4のC++バージョンで記述子(SIFT、SURF、ORB)にマッチするコードを書いた。このコードをpythonでopencvに変換したい。私はC++でopencv関数を使う方法についていくつかの文書を見つけましたが、pythonのopencv関数の多くは、それらを使う方法を見つけることができませんでした。ここに私のPythonコードがあります。私の現在の問題は、opencvの "drawMatches"をPythonでどのように使うのか分かりません。私はcv2.DRAW_MATCHES_FLAGS_DEFAULTを見つけましたが、私はそれをどのように使用するか考えていません。ここにORB記述子を使用して、一致の私のPythonコードは次のとおりです。pythonでopencvモジュールを使用してディスクリプタの一致を視覚化する方法

im1 = cv2.imread(r'C:\boldt.jpg') 
im2 = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY) 
im3 = cv2.imread(r'C:\boldt_resize50.jpg') 
im4 = cv2.cvtColor(im3, cv2.COLOR_BGR2GRAY) 

orbDetector2 = cv2.FeatureDetector_create("ORB") 
orbDescriptorExtractor2 = cv2.DescriptorExtractor_create("ORB") 
orbDetector4 = cv2.FeatureDetector_create("ORB") 
orbDescriptorExtractor4 = cv2.DescriptorExtractor_create("ORB") 

keypoints2 = orbDetector2.detect(im2) 
(keypoints2, descriptors2) = orbDescriptorExtractor2.compute(im2,keypoints2) 
keypoints4 = orbDetector4.detect(im4) 
(keypoints4, descriptors4) = orbDescriptorExtractor4.compute(im4,keypoints4) 
matcher = cv2.DescriptorMatcher_create('BruteForce-Hamming') 
raw_matches = matcher.match(descriptors2, descriptors4) 
img_matches = cv2.DRAW_MATCHES_FLAGS_DEFAULT(im2, keypoints2, im4, keypoints4, raw_matches) 
cv2.namedWindow("Match") 
cv2.imshow("Match", img_matches); 
ラインの

エラーメッセージ "img_matches = cv2.DRAW_MATCHES_FLAGS_DEFAULT(IM2、keypoints2、IM4、keypoints4、raw_matches)" 私が過ごした

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
TypeError: 'long' object is not callable 

を多くの時間の検索のドキュメントとpythonでopencv関数を使用する例しかし、pythonでopencv関数を使うことについての情報はほとんどないので、私は非常に不満です。 Pythonでopencvモジュールのあらゆる機能を使用する方法のドキュメントがどこにあるのか教えていただければ、非常に役に立ちます。私はあなたの時間と助けに感謝します。

答えて

2

エラーメッセージに示すように、DRAW_MATCHES_FLAGS_DEFAULTのタイプは「long」です。これは関数ではなく、cv2モジュールによって定義される定数です。残念ながら、あなたが望む関数 'drawMatches'はOpenCVのC++インタフェースにのみ存在します。

+0

感謝を! – user1433201

14

フィーチャマッチングをPythonで次のように視覚化することができます。 scipyライブラリの使用に注意してください。

# matching features of two images 
import cv2 
import sys 
import scipy as sp 

if len(sys.argv) < 3: 
    print 'usage: %s img1 img2' % sys.argv[0] 
    sys.exit(1) 

img1_path = sys.argv[1] 
img2_path = sys.argv[2] 

img1 = cv2.imread(img1_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) 
img2 = cv2.imread(img2_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) 

detector = cv2.FeatureDetector_create("SURF") 
descriptor = cv2.DescriptorExtractor_create("BRIEF") 
matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming") 

# detect keypoints 
kp1 = detector.detect(img1) 
kp2 = detector.detect(img2) 

print '#keypoints in image1: %d, image2: %d' % (len(kp1), len(kp2)) 

# descriptors 
k1, d1 = descriptor.compute(img1, kp1) 
k2, d2 = descriptor.compute(img2, kp2) 

print '#keypoints in image1: %d, image2: %d' % (len(d1), len(d2)) 

# match the keypoints 
matches = matcher.match(d1, d2) 

# visualize the matches 
print '#matches:', len(matches) 
dist = [m.distance for m in matches] 

print 'distance: min: %.3f' % min(dist) 
print 'distance: mean: %.3f' % (sum(dist)/len(dist)) 
print 'distance: max: %.3f' % max(dist) 

# threshold: half the mean 
thres_dist = (sum(dist)/len(dist)) * 0.5 

# keep only the reasonable matches 
sel_matches = [m for m in matches if m.distance < thres_dist] 

print '#selected matches:', len(sel_matches) 

# ##################################### 
# visualization of the matches 
h1, w1 = img1.shape[:2] 
h2, w2 = img2.shape[:2] 
view = sp.zeros((max(h1, h2), w1 + w2, 3), sp.uint8) 
view[:h1, :w1, :] = img1 
view[:h2, w1:, :] = img2 
view[:, :, 1] = view[:, :, 0] 
view[:, :, 2] = view[:, :, 0] 

for m in sel_matches: 
    # draw the keypoints 
    # print m.queryIdx, m.trainIdx, m.distance 
    color = tuple([sp.random.randint(0, 255) for _ in xrange(3)]) 
    cv2.line(view, (int(k1[m.queryIdx].pt[0]), int(k1[m.queryIdx].pt[1])) , (int(k2[m.trainIdx].pt[0] + w1), int(k2[m.trainIdx].pt[1])), color) 


cv2.imshow("view", view) 
cv2.waitKey() 
+0

あなたのコードを実行すると、66行目にエラーが表示されます。 '' 'TypeError:integer argument expected、float'''' – gilbertbw

+0

@ wall-e匿名ユーザーがあなたの投稿を編集したばかりで、 – OGHaza

+0

view [:h1、:w1、:] = img1 ValueError:入力配列を形状(322,518)から形状(322,518,3)にブロードキャストできませんでした – Giuseppe

9

私もちょうどOpenCVのPythonインタフェースを使用して、私はscipyを使用していないことを何か自分自身を書きました。 drawMatchesはOpenCV 3.0.0の一部であり、現在使用しているOpenCV 2の一部ではありません。私はパーティーに遅刻していますが、私の能力の中でdrawMatchesを模倣した私自身の実装です。

私は自分自身の画像を提供しました。一方はカメラマンで、もう一方は同じ画像ですが反時計回りに55度回転しています。

私が書いたことの基本的な前提は、出力イメージに両方のイメージを配置するのに対応するために行の量が最大である出力RGBイメージを割り当て、列は単純に合計です両方の列の一緒に。それぞれの画像を対応するスポットに配置し、一致したすべてのキーポイントのループを実行します。 2つの画像の間で一致するキーポイントを抽出し、(x,y)の座標を抽出します。次に、検出された場所のそれぞれに円を描き、これらの円を結ぶ線を描きます。

第2の画像の検出されたキーポイントは、それ自身の座標系に関するものであることに注意してください。これを最終出力イメージに配置する場合は、列座標が出力イメージの座標系と一致するように、最初のイメージからの列の量だけ列座標をオフセットする必要があります。私はOpenCVののを使用

enter image description here

enter image description here

import numpy as np 
import cv2 

def drawMatches(img1, kp1, img2, kp2, matches): 
    """ 
    My own implementation of cv2.drawMatches as OpenCV 2.4.9 
    does not have this function available but it's supported in 
    OpenCV 3.0.0 

    This function takes in two images with their associated 
    keypoints, as well as a list of DMatch data structure (matches) 
    that contains which keypoints matched in which images. 

    An image will be produced where a montage is shown with 
    the first image followed by the second image beside it. 

    Keypoints are delineated with circles, while lines are connected 
    between matching keypoints. 

    img1,img2 - Grayscale images 
    kp1,kp2 - Detected list of keypoints through any of the OpenCV keypoint 
       detection algorithms 
    matches - A list of matches of corresponding keypoints through any 
       OpenCV keypoint matching algorithm 
    """ 

    # Create a new output image that concatenates the two images together 
    # (a.k.a) a montage 
    rows1 = img1.shape[0] 
    cols1 = img1.shape[1] 
    rows2 = img2.shape[0] 
    cols2 = img2.shape[1] 

    out = np.zeros((max([rows1,rows2]),cols1+cols2,3), dtype='uint8') 

    # Place the first image to the left 
    out[:rows1,:cols1,:] = np.dstack([img1, img1, img1]) 

    # Place the next image to the right of it 
    out[:rows2,cols1:cols1+cols2,:] = np.dstack([img2, img2, img2]) 

    # For each pair of points we have between both images 
    # draw circles, then connect a line between them 
    for mat in matches: 

     # Get the matching keypoints for each of the images 
     img1_idx = mat.queryIdx 
     img2_idx = mat.trainIdx 

     # x - columns 
     # y - rows 
     (x1,y1) = kp1[img1_idx].pt 
     (x2,y2) = kp2[img2_idx].pt 

     # Draw a small circle at both co-ordinates 
     # radius 4 
     # colour blue 
     # thickness = 1 
     cv2.circle(out, (int(x1),int(y1)), 4, (255, 0, 0), 1) 
     cv2.circle(out, (int(x2)+cols1,int(y2)), 4, (255, 0, 0), 1) 

     # Draw a line in between the two points 
     # thickness = 1 
     # colour blue 
     cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (255, 0, 0), 1) 


    # Show the image 
    cv2.imshow('Matched Features', out) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows() 

が、これは、ここで私が使用した2枚の画像があり、働くことを示すために:さらに騒ぎがなければ

ORB検出器でキーポイントを検出し、これはバイナリ・ディスクリプタであるため、正規化されたハミング距離を類似度の距離測定値として使用しました。そのように:

import numpy as np 
import cv2 

img1 = cv2.imread('cameraman.png') # Original image 
img2 = cv2.imread('cameraman_rot55.png') # Rotated image 

# Create ORB detector with 1000 keypoints with a scaling pyramid factor 
# of 1.2 
orb = cv2.ORB(1000, 1.2) 

# Detect keypoints of original image 
(kp1,des1) = orb.detectAndCompute(img1, None) 

# Detect keypoints of rotated image 
(kp2,des2) = orb.detectAndCompute(img2, None) 

# Create matcher 
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 

# Do matching 
matches = bf.match(des1,des2) 

# Sort the matches based on distance. Least distance 
# is better 
matches = sorted(matches, key=lambda val: val.distance) 

# Show only the top 10 matches 
drawMatches(img1, kp1, img2, kp2, matches[:10]) 

これは私が取得イメージです。ご返信用

enter image description here

+0

Hii @rayryeng私は上記のコードを実行しようとしているとき、私は得ている トレースバック(最新の呼び出し最後) : ファイル "orb1.py"、行33、 out [:rows1、:cols1 ,:] = np.dstack([img1、img1、img1]) ValueError:入力配列をシェイプからブロードキャストできませんでした(900 、1440,9)shape(900,1440,3) –

+2

@BhushanPatil - 関数のドキュメントストリングを注意深く読んでください**。グレースケール画像が必要です。 ** RGB **画像を使用しています。この機能を使用するには、イメージをグレースケールに変換する必要があります。単純な呼び出し 'cv2.cvtColor'で十分です。' img = cv2.cvtColor(img、cv2.COLOR_BGR2GRAY) 'が動作します。次回使用する前に、関数のドキュメントを実際にお読みください。これは、他の人のコードを使用するときに開発者が学ばなければならない標準的なスキルです。 – rayryeng

関連する問題