今,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
このように表示されました。
ソースコードとエラーメッセージはテキストで質問文に貼り付けてください。
その際ソースコードの上下を```で囲ってください。
pythonのコードの一番最初の行のすぐ上に
```python
だけの行を追加してください
また、pythonのコードの一番最後の行のすぐ下に
```
だけの行を追加してください
または、
https://teratail.storage.googleapis.com/uploads/contributed_images/56957fe805d9d7befa7dba6a98676d2b.gif
を見て、そのようにしてみてください
現状、コードがとても読み辛いです
質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなります
「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する必要があります
他にも間違ってるところがあります
自分でも探してみてください
ご回答ありがとうございます。