Python+OpenCV|SIFT記述子

SIFT記述子

局所領域の内容を認識に有利な情報に変換する過程を記述という。
記述された情報を記述子という。

SIFT記述子は、局所輝度勾配ヒストグラムを利用した記述子である。
SIFTは、DoG画像の生成や画像のリサイズなどの処理が必要なため、計算コストが高いという問題がある。

大まかなアルゴリズム

  1. DoG画像の極値から特徴点候補を求めて、エッジやコントラストをもとにロバストな特徴点を選出する
  2. 特徴点の近傍でのDoG画像の勾配方向から勾配ヒストグラムを作成し、スケールと主方向を決定する(スケール不変性)
  3. 特徴点の近傍領域を主方向に合わせて回転する(回転不変性)
  4. 回転後の画像から勾配ヒストグラムを作成、総和をもとに正規化して特徴ベクトルとする(明度不変性)

論文

distinctive image features from scale-invariant keypoints

Python+OpenCV

import cv2
import numpy as np
img = cv2.imread('haruna_kankore.png')
gray=cv2.imread('haruna_kankore.png',0)
 
sift = cv2.xfeatures2d.SIFT_create()
 
kp = sift.detect(gray)
 
img_sift = np.zeros_like(img)
img_sift = cv2.drawKeypoints(img, kp, img_sift, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imwrite('img_sift.png', img_sift)

結果

元画像

SIFT記述子

プログラム+α

import cv2

img = cv2.imread('haruna_kankore.png')

detector = cv2.xfeatures2d.SIFT_create()

kp = detector.detect(img)


img_sift = cv2.drawKeypoints(img, kp, None)

cv2.imwrite("img_sift.png", img_sift)

特徴点のマッチング

import cv2

img1 = cv2.imread('haruna_kankore.png')
img2 = cv2.imread('haruna_kankore_temp.png')


sift = cv2.xfeatures2d.SIFT_create(500)


kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)


bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)


good = []
for m,n in matches:
    if m.distance < 0.75*n.distance:
        good.append([m])


img_sift = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good, None, flags=2)

cv2.imwrite('img_sift_match.png', img_sift)

元画像

SIFT記述子

参考

http://lang.sist.chukyo-u.ac.jp/classes/OpenCV/py_tutorials/py_feature2d/py_sift_intro/py_sift_intro.html

http://lang.sist.chukyo-u.ac.jp/classes/OpenCV/py_tutorials/py_feature2d/py_surf_intro/py_surf_intro.html

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_matcher/py_matcher.html

https://www.tech-tech.xyz/sift-surf-akaze/