특징을 나타내는 값을 매칭하기 위해서는 회전이나 크기 등에 영향이 없어야 하며, 이를 위해서는 feature descriptor(특징 디스크립터)가 필요하다. 특징 디스크립터는 keypoint의 주변의 밝기나 색상 등의 정보를 표현한 것으로, keypoint의 주변 픽셀을 일정한 크기로 나눈 후 각 영역에 대한 pixel의 그래디언트를 계산한 것이 된다. 특징 디스크립터를 활용한 검출기의 종류는 다음과 같다.
ORB(Oriented FAST and Roteted BRIEF) | FAST 코너 검출기와 BRIEF의 회전이 고려되도록 한 것 |
SIFT(Scale Invariant Feature Transform) | 크기 변화에 관계없이 특징 검출이 이루어지도록 한 것 |
SURF(Speed Up Robust Features) | SIFT의 처리 속도를 개선한 것 |
1. ORB
ORB에서 BRIEF(Binary Robust Independent Elementary features)는 특징 디스크립터를 검출하지 않고 binary 문자열을 구하는 역할을 한다. 단, OpenCV 4.2.0 버전에서는 SIFT와 SURF가 지원되지 않는다.
pip install opencv-python==3.4.2.16
pip install opencv-contrib-python==3.4.2.16
SIFT와 SURF를 사용하려면 커맨드 창에서 위와 같이 OpenCV 버전 다운그레이드를 통해서 실행할 수는 있으나 작업 환경 유지를 위해 이 글에서는 ORB를 중심으로만 다룬다. ORB로 keypoint를 검출하는 방법은 아래와 같다.
import cv2
import numpy as np
img = cv2.imread('weapon/search/vector.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# ORB 생성
orb = cv2.ORB_create(50)
# keypoint 검출 및 descriptor 계산
keypoint, descriptor = orb.detectAndCompute(img, None)
# keypoint 표시
draw = cv2.drawKeypoints(img, keypoint, None, flags = cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow('ORB', draw)
cv2.waitKey()
cv2.destroyAllWindows()
ORB 검출기를 생성하는 cv2.ORB_create()는 [최대 검출 특징 수, 이미지 피라미드 비율, 이미지 피라미드 계층, 제외할 테두리 크기, 이미지 피라미드 최초 계층, 임의의 좌표 생성 수, keypoint 검출 방식, descriptor 패치 크기, FAST에 사용할 임계값]을 인자로 사용한다. default 값으로는 다음과 같이 설정된다.
최대 검출 특징 수 | 500 |
이미지 피라미드 비율 | 1.2 |
이미지 피라미드 계층 | 8 |
제외할 테두리 크기 | 31 |
이미지 피라미드 최초 계층 | 0 |
임의의 좌표 생성 수 | 2 |
keypoint 검출 방식 | cv2.ORB_HARRIS_SCORE |
descriptor 패치 크기 | 31 |
FAST에 사용할 임계값 | 20 |
이미지 피라미드란 다음을 의미한다. 일반적으로는 일정한 크기의 이미지로 작업을 수행하지만, 이미지의 크기를 확대하거나 축소하면서 해상도가 다른 이미지를 만들어서 분석하는 경우도 발생한다. 이 때, 이렇게 생성된 이미지 집합을 이미지 피라미드라 한다. 또한, cv2.ORB_create()를 사용할 때는 제외할 테두리 크기와 descriptor 패치 크기는 같은 값을 설정해야 한다. keypoint 검출 방식의 경우 cv2.ORB_FAST_SCORE로 바꿔서 속도를 높일수는 있지만 좋지 못한 결과를 얻을 수도 있으니 주의해야 한다.
2. BFmatcher
BRMacther(Brute-Force matcher)는 매칭의 기준이 되는 디스크립터와 매칭의 대상이 되는 디스크립터에 대해 하나씩 매칭하는 것으로 cv2.BFMatcher를 사용한다.
import cv2
import numpy as np
img1 = cv2.imread('lion.jpg')
img2 = cv2.imread('image.jpg')
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
orb = cv2.ORB_create(50)
keypoint1, descriptor1 = orb.detectAndCompute(gray1, None)
keypoint2, descriptor2 = orb.detectAndCompute(gray2, None)
# BFmatcher 생성 및 계산
matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck = True)
match = matcher.match(descriptor1, descriptor2)
draw = cv2.drawMatches(img1, keypoint1, img2, keypoint2, match, None, flags = cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('BFMatcher & ORB', draw)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.BFMatcher는 [거리 측정 방법, 상호 매칭 반영 여부]가 인자로 사용되며, 거리 측정 방법의 종류는 다음과 같다.
cv2.NORM_L1 | |
cv2.NORM_L2(default) | |
cv2.NORM_L2SQR | |
cv2.NORM_HAMMING | |
cv2.NORM_HAMMING2 |
상호 매칭 반영 여부는 default로 False가 설정되며, ORB의 경우 NORM_HAMMING을 주로 사용한다. 상호 매칭 반영 여부를 True로 지정하면 2가지의 디스크립터 모두에서 매칭이 성립하는 것만 반영된다는 장점을 얻지만 속도가 느려진다는 단점도 갖는다.
'데이터 분석 & 시각화 > OpenCV' 카테고리의 다른 글
[OpenCV Practice 05] 이미지 속성과 관심 영역 지정(ROI) (0) | 2020.08.12 |
---|---|
[OpenCV Practice 04] 트랙바 (Trackbar) (0) | 2020.08.11 |
[OpenCV Practice 03] OpenCV를 이용한 도형그리기 (0) | 2020.08.10 |
[OpenCV Practice 02] 비디오 reading and writing (0) | 2020.08.08 |
[OpenCV Practice 01] 이미지 reading and writing (0) | 2020.08.07 |
최근댓글