質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1048閲覧

OpenCVでのdrawMatchesをfor文で出来ない

Manabi

総合スコア4

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2022/02/23 02:30

編集2022/03/06 09:25

今,opencvのpythonでimage stitchingを学んでいる大学生です。
imageStitcher関数で画像を繋げることができたので特徴量を抽出してから各画像ごとにmatchingすることを目標にこのコードを書いています。二つの画像を入力してその特徴量の抽出とマッチングをすることができたので入力を複数画像にしようと試みたところエラーが出て行き詰まってしまったので質問させていただいている次第です。
1枚目がのコードのスクリーンショットが成功した2画像の入力です。
2枚目のスクリーンショットがエラーがでて画像も生成されずに困っているコードです。
ちなみにIn[2]までは実行できたのでそこまでに間違いはないと思っています。

おそらくfor文に問題があると思うのですが自分では今何が間違っていて実行できていないのかわかりません。
どなたかわかる方返信よろしくお願いします。

すみません....
成功したコード↓

python

1import cv2 2import numpy as np 3img_ = cv2.imread('./IMG_9644.JPG') 4img1 = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY) 5img = cv2.imread('./IMG_9646.JPG') 6img2 = cv2.cvtColor(img_, cv2.COLOR_BGR2GRAY) 7sift = cv2.SIFT_create() 8#find keypoints 9kp1, des1 = sift.detectAndCompute(img1,None) 10kp2, des2 = sift.detectAndCompute(img2,None) 11match = cv2.BFMatcher() 12matches = match.knnMatch(des1, des2, k =2) 13good = [] 14for m,n in matches: 15 if m.distance < 0.5*n.distance: 16 good.append([m]) 17img3 = cv2.drawMatchesKnn(img_, kp1, img, kp2,good,None,flags=2) 18cv2.imshow('IMG_drawMatches',img3) 19cv2.waitKey(0)

失敗したコード↓

python

1mport cv2 2import numpy as np 3import glob 4 5image_path=glob.glob('/view_img/*.JPG') 6images = [] 7kp = [] 8gray = [] 9des =[] 10feature = [] 11for image in image_path: 12 img = cv2.imread(image) 13 images.append(img) 14 cv2.imshow("Image",img) 15 cv2.waitKey(0)#0を画像上で入力すると次の画像へ 16#print(img) 17 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#グレースケール 18 cv2.imshow('grayImg',gray) 19 cv2.waitKey(0) 20 sift = cv2.SIFT_create() 21 #find keypoints 22 kp,des =sift.detectAndCompute(gray,None)#kpには特徴点の座標の情報、desには特徴量記述子の情報が格納 23cv2.imshow('IMG_keypoints', cv2.drawKeypoints(img,kp,None)) 24cv2.waitKey(0) 25 26matches =[] 27match = cv2.BFMatcher() 28for i in range(len(img)): 29 for j in range(len(img)): 30 if i!= j: 31 matches = match.knnMatch(des[i], des[j], k=2) 32 good = [] 33# Apply ratio test 34for m,n in matches: 35 if m.distance < 0.5*n.distance: 36 good.append([m]) 37 feature = cv2.drawMatchesKnn(img[i], kp[i], img[j], kp[j], good, None, flags=2) 38 #cv2.imwrite("f'fea{i:03d}.png",feature) 39 cv2.imshow('IMG_drawMatches',feature) 40cv2.waitKey(0)
IndexError Traceback (most recent call last) /var/folders/fm/c943c_r93bzd8zk1ht89x4dr0000gn/T/ipykernel_3610/2609149258.py in <module> 4 for j in range(len(img)): 5 if i!= j: ----> 6 matches = match.knnMatch(des[i], des[j], k=2) 7 good = [] 8 # Apply ratio test IndexError: index 1414 is out of bounds for axis 0 with size 1414

このように表示されました。

aradbrandingg👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuki23

2022/02/23 06:17

ソースコードとエラーメッセージはテキストで質問文に貼り付けてください。 その際ソースコードの上下を```で囲ってください。
jbpb0

2022/02/23 11:21

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください または、 https://teratail.storage.googleapis.com/uploads/contributed_images/56957fe805d9d7befa7dba6a98676d2b.gif を見て、そのようにしてみてください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
jbpb0

2022/03/04 11:34

「for image in image_path:」のループ内での「kp,des =sift.detectAndCompute(...」で、「kp」と「des」には毎回「sift.detectAndCompute()」の結果が上書きされるので、ループが終わった後に「kp」と「des」に入ってるのは最後の画像での結果だけなので、後で「kp[i]」とか「des[i]」とかしても、それは質問者さんが意図してる処理ではありません 一旦別の変数に「sift.detectAndCompute()」の結果を入れて、それを「kp」と「des」にappendする必要があります (「images.append(img)」のように) 「img」も同様に、ループ内での「img = cv2.imread(image)」で毎回上書きされるので、後で「len(img)」とか「img[i]」とかしても、それは質問者さんが意図してる処理ではありません 読み込んだ画像は、「images.append(img)」で全部「images」に入ってるので、「len(images)」とか「images[i]」とかに変えたら大丈夫なはず 「matches」も同様で、一旦別の変数に「match.knnMatch()」の結果を入れて、それを「matches」にappendする必要があります 他にも間違ってるところがあります 自分でも探してみてください
Manabi

2022/03/06 07:52

ご回答ありがとうございます。
guest

回答1

0

試行錯誤の結果キーポイントと特徴記述子を複数画像でマッチさせることができました。
しかし画像を合成するとなると不具合が生じました。
以下がマッチングまで成功したプログラムです。

python

1def get_features(img): 2 # 特徴点情報抽出 3 orb = cv2.ORB_create() 4 kp, des = orb.detectAndCompute(img, None) 5 keypoints_drawn = cv2.drawKeypoints(img, kp, None, color=(0, 0, 255)) 6 description = des 7 keypoint = kp 8 return keypoints_drawn,description,keypoint 9 10descript = [] 11keypoint = [] 12for i in range (len(image_path)): 13 features = get_features(images[i]) 14 plot_images(images[i],features[0]) 15 descript.append(features[1]) 16 keypoint.append(features[2]) 17 #print(len(keypoint)) 18 #print(features[0]) 19 20bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 21for i in range (len(image_path)): 22 for j in range (len(image_path)): 23 if j<i: 24 matches = bf.match(descript[i],descript[j]) 25 matches_drawn = cv2.drawMatches(images[i],keypoint[i],images[j],keypoint[j],matches, None, matchColor=(0,0,255), flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS) 26 plot_images(matches_drawn) 27limit = 10 28best = sorted(matches, key = lambda x:x.distance)[:limit] 29 30for i in range (len(image_path)): 31 for j in range (len(image_path)): 32 if j<i: 33 best_matches_drawn = cv2.drawMatches(images[i], keypoint[i], images[j], keypoint[j], best, None, matchColor=(0,0,255), flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS) 34 plot_images(best_matches_drawn) 35left_pts = [] 36right_pts = [] 37#print(keypoint) 38for m in best: 39 l = features[2][m.trainIdx].pt 40 r = features[2][m.queryIdx].pt 41 left_pts.append(l) 42 right_pts.append(r)

しかし1ペアの画像をこのプログラムで動かしたときと以下のプログラムで動かしたときに上のプログラムでは画像を合成できませんでした。(下のプログラムでは合成できました。)
print文からキーポイントが異なるからではないかそれによりホモグラフィーが異なるのでそれが原因ではないかと考えましたがなぜ同じペアの画像を入力してキーポイントが変わってしまったのかわからなくて手詰まりの状態です。for文を用いる以外は同じプログラムになっていると思います。
このとこについてご存知の方がいらっしゃいましたら回答よろしくお願いします。

以下は2画像なら合成可能になっています。

python

1orb = cv2.ORB_create() 2kp_left, des_left = orb.detectAndCompute(left, None) 3kp_right, des_right = orb.detectAndCompute(right, None) 4 5keypoints_drawn_left = cv2.drawKeypoints(left, kp_left, None, color=(0, 0, 255)) 6keypoints_drawn_right = cv2.drawKeypoints(right, kp_right, None, color=(0, 0, 255)) 7 8plot_images(left, keypoints_drawn_left, right, keypoints_drawn_right) 9 10bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) 11matches = bf.match(des_left,des_right) 12matches_drawn = cv2.drawMatches(left, kp_left, right, kp_right, matches, None, matchColor=(0,0,255), flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS) 13plot_images(matches_drawn) 14 15limit = 10 16best = sorted(matches, key = lambda x:x.distance)[:limit] 17 18best_matches_drawn = cv2.drawMatches(left, kp_left, right, kp_right, best, None, matchColor=(0,0,255), flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS) 19plot_images(best_matches_drawn) 20 21left_pts = [] 22right_pts = [] 23for m in best: 24 l = kp_left[m.queryIdx].pt 25 r = kp_right[m.trainIdx].pt 26 left_pts.append(l) 27 right_pts.append(r) 28 29M, _ = cv2.findHomography(np.float32(right_pts), np.float32(left_pts)) 30 31dim_x = left.shape[1] + right.shape[1] 32dim_y = max(left.shape[0], right.shape[0]) 33dim = (dim_x, dim_y) 34warped = cv2.warpPerspective(right, M, dim) 35 36plot_images(warped) 37 38comb = warped.copy() 39# combine the two images 40comb[0:left.shape[0],0:left.shape[1]] = left 41# crop 42r_crop = 1920 43comb = comb[:, :r_crop] 44plot_images(comb)

投稿2022/03/06 08:36

Manabi

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問