OpenCV - SIFTを使った特徴量算出及びマッチング
Web+DB Express Vol.83を購入したところ特集として画像認識が
いやあWeb技術者もComputer Visionが必要な時代かあ。。。と思い読み進めると、Javaでのコーディング例も載っていてかなり実用的でいい感じ
しかしJavaよりかはPythonでお手軽にコーディングしたいよね!ってことで、掲載のと同じSIFTを使った特徴量算出及びマッチング、画像表示をPythonで書いてみました
import cv2 # 画像を読み込み白黒化する im = cv2.imread('test.jpg') im2 = cv2.imread('test2.jpg') gray= cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) gray2= cv2.cvtColor(im2,cv2.COLOR_BGR2GRAY) # SIFT特徴量算出アルゴリズムモジュールを呼び出す sift = cv2.SIFT() # 特徴量を算出する kp ,des = sift.detectAndCompute(gray, None) kp2 ,des2 = sift.detectAndCompute(gray2, None) # 類似点を算出する matcher = cv2.DescriptorMatcher_create("FlannBased") matches = matcher.match(des,des2) # 類似点を表示する img3 = cv2.drawMatches(gray,kp,gray2,kp2,matches[:10])
簡単、簡単♪と実行してみてると
AttributeError: 'module' object has no attribute 'drawMatches'
は????
え、python経由でdrawMatchesって使えないの???
ネットの海をあさった結果、なんか使えなさそうな雰囲気(詳しい人がいたら教えてほしいです…)
というわけでStackOverflowを参考にdrawMatchesを自作することに
import numpy as np import cv2 def drawMatches(img1, kp1, img2, kp2, matches): 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') out[:rows1,:cols1,:] = np.dstack([img1, img1, img1]) out[:rows2,cols1:cols1+cols2,:] = np.dstack([img2, img2, img2]) for mat in matches: img1_idx = mat.queryIdx img2_idx = mat.trainIdx (x1,y1) = kp1[img1_idx].pt (x2,y2) = kp2[img2_idx].pt 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) cv2.line(out, (int(x1),int(y1)), (int(x2)+cols1,int(y2)), (255, 0, 0), 1) cv2.imshow('Matched Features', out) cv2.waitKey(0) cv2.destroyAllWindows() # 画像を読み込み白黒化する im = cv2.imread('test.jpg') im2 = cv2.imread('test2.jpg') gray= cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) gray2= cv2.cvtColor(im2,cv2.COLOR_BGR2GRAY) # SIFT特徴量算出アルゴリズムモジュールを呼び出す sift = cv2.SIFT() # 特徴量を算出する kp ,des = sift.detectAndCompute(gray, None) kp2 ,des2 = sift.detectAndCompute(gray2, None) # 類似点を算出する matcher = cv2.DescriptorMatcher_create("FlannBased") matches = matcher.match(des,des2) # 類似点を表示する img3 = drawMatches(gray,kp,gray2,kp2,matches[:10])
これで動作は問題ないみたい
drawKeypointsはあるのになあ