- Oriented FAST and Rotated BRIEF라는 방법론을 이용해 Point Of Interest를 한번 잡아보도록 합니다. 다만, 성능은 보장하지 못합니다.
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]:
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]:
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')