ORB를 이용한 Local Feature 잡아내기

  • Oriented FAST and Rotated BRIEF라는 방법론을 이용해 Point Of Interest를 한번 잡아보도록 합니다. 다만, 성능은 보장하지 못합니다.
local feature orb

Local Feature 매칭

  • 우리는 대표적인 건물을 골라낼때 건물에서 첨탑과 같은 중요한 부분을 보고 골라냅니다.
  • 엑스포타워는 타워를 둘러싼 위성같은 문양, 남산타워도 마찬가지로 남산위에 솟아있는 타워, 롯데타워.. 아 롯데타워는 어디서나 보여서.. 어쨌든 그렇습니다.
  • Local Feature를 잘 골라내는것은 이미지를 판별하는데 중요합니다. 딥러닝을 이용해 Feature Extraction을 하지만 예전방식도 한번 볼까요?
  • 여기서는 Oriented FAST and Rotated BRIEF 로 작업합니다. 설명링크
  • 논문은 2011년이라 다소 오래되었습니다.
  • Ethan Rublee, Vincent Rabaud, Kurt Konolige, Gary R. Bradski: ORB: An efficient alternative to SIFT or SURF. ICCV 2011: 2564-2571.
In [5]:
import numpy as np
import pandas as pd
import cv2
import matplotlib.pyplot as plt
import os

%matplotlib inline

남산타워의 local feature잡아내기

  • local feature로는 해당 건물이라면 어떤 사진이든 잘 나타나야 합니다.
  • 그리고 해당하는 물건이나 건물에만 잘 나타나있는 것으로, 남산타워는 위의 동그란 부분이 될수있겠죠
In [6]:
dataset_path = './'
img_building = cv2.imread(os.path.join(dataset_path, 'nsan.jpg'))
img_building = cv2.cvtColor(img_building, cv2.COLOR_BGR2RGB)  # Convert from cv's BRG default color order to RGB

orb = cv2.ORB_create()  # OpenCV 3 backward incompatibility: Do not create a detector with `cv2.ORB()`.
key_points, description = orb.detectAndCompute(img_building, None)
img_building_keypoints = cv2.drawKeypoints(img_building, 
                                           key_points, 
                                           img_building, 
                                           flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) # Draw circles.
plt.figure(figsize=(16, 16))
plt.title('ORB Interest Points')
plt.imshow(img_building_keypoints); plt.show()

제일 잘맞는 feature 끼리의 유사 부분 확인

  • 이미지를 보면 그다지 유사하지는 않습니다만..
In [ ]:
def image_detect_and_compute(detector, img_name):
    img = cv2.imread(os.path.join(dataset_path, img_name))
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    kp, des = detector.detectAndCompute(img, None)
    return img, kp, des
    
In [19]:
orb = cv2.ORB_create()

img1, keypoint1, des1 = image_detect_and_compute(orb, 'nsan.jpg')
img2, keypoint2, des2 = image_detect_and_compute(orb, 'namsan2.png')
In [20]:
des1
Out[20]:
array([[130,  80, 146, ...,   8,  53, 138],
       [207, 112, 238, ..., 183,  88, 116],
       [ 85, 212,  62, ..., 122, 153,   3],
       ...,
       [134,  12,  22, ..., 125, 185, 134],
       [ 48,  96, 187, ..., 112, 102, 170],
       [ 36,  60, 187, ...,  77,   5, 247]], dtype=uint8)

Keypoint잡아내기

  • 총 20개의 keypoint를 잡아내는데, 남산타워의 중요한 지점을 잘 잡아내는듯한 느낌이지만, 그렇지 않을때도 많습니다.
In [24]:
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2)
matches = sorted(matches, key = lambda x: x.distance) 
In [30]:
matches[1].distance
Out[30]:
45.0
In [21]:
img_matches = cv2.drawMatches(img1, keypoint1, img2, keypoint2, matches[:20], img2, flags=2) # Show top 10 matches
plt.figure(figsize=(16, 16))
plt.imshow(img_matches); plt.show()

다른 이미지 해보기

  • 이번에는 잠실역에 있는 쌍둥이 타워를 대상으로 돌려봅니다.
  • 결과는 글쎄..음
In [38]:
def compare(i1, i2) : 
    img1, keypoint1, des1 = image_detect_and_compute(orb, i1)
    img2, keypoint2, des2 = image_detect_and_compute(orb, i2)

    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    matches = bf.match(des1, des2)
    matches = sorted(matches, key = lambda x: x.distance) 
    img_matches = cv2.drawMatches(img1, keypoint1, img2, keypoint2, matches[:20], img2, flags=2) # Show top 10 matches
    plt.figure(figsize=(16, 16))
    plt.imshow(img_matches); plt.show()
  • 비슷한걸 어렴풋하게 골라내는것같지만
In [40]:
compare('a1.PNG', 'a2.jpg')
  • 속이기도 쉽습니다.
In [43]:
compare('a1.PNG', 'a3.PNG')

답글 남기기