728x90
728x90
특징점 매칭 (feature point matching)
• 두 영상에서 추출한 특징점 기술자를 비교하여 서로 유사한 기술자를 찾는 작업
특징 벡터 유사도 측정 방법
• 실수 특징 벡터: L2 노름(L2 norm) 사용
• 이진 특징 벡터: 해밍 거리(hamming distance) 사용
OpenCV 특징점 매칭 클래스
• BF: Brute-force (전수 조사)
== 각 특징점 하나씩 다 매칭해보면서 가장 distance가 작은 것을 골라낸다
• Flann: Fast Library for Approximate Nearest Neighbor (K-D Tree 사용)
== 너무 특징점이 많을 때 사용
==> 완전히 최소값 매칭이 어려워(속도는 빠름) but 특징점이 몇천개 정도면 별차이 없음
==> 영상 사이즈가 너무 커져서 너무느리다 싶으면 사용
좋은 매칭 선별 방법 1
• 가장 좋은 매칭 결과에서 distance 값이 작은 것 N개를 사용
• cv2.DMatch.distance 값을 기준으로 정렬 후 상위 N개 선택
# 영상 불러오기
src1 = cv2.imread('ch09\\images\\graf1.png', cv2.IMREAD_GRAYSCALE)
src2 = cv2.imread('ch09\\images\\graf3.png', cv2.IMREAD_GRAYSCALE)
if src1 is None or src2 is None:
print('Image load failed!')
sys.exit()
feature = cv2.KAZE_create()
# feature = cv2.AKAZE_create()
# feature = cv2.ORB_create()
# 특징점 검출 및 기술자 계산
kp1, desc1 = feature.detectAndCompute(src1, None)
kp2, desc2 = feature.detectAndCompute(src2, None)
# 특징점 매칭
matcher = cv2.BFMatcher_create()
'''
+ BFMatcher_create : Brute-force (전수 조사)
+ cv2.FlannBasedMatcher : 특징점이 너무 많을 시 사용(근사화)
# 실수 기술자 KAZE(default = cv2.NORM_L2)
# 이진 기술자 AKAZE, ORB(=cv2.NORM_HAMMING)
'''
matches = matcher.match(desc1, desc2)
'''
cv2.DescriptorMatcher.match(queryDescriptors, trainDescriptors, mask=None)
-> matches
• queryDescriptors: (기준 영상 특징점) 질의 기술자 행렬
• trainDescriptors: (대상 영상 특징점) 학습 기술자 행렬
• mask: 매칭 진행 여부를 지정하는 행렬 마스크.
• matches: 매칭 결과. cv2.DMatch 객체의 리스트.
*멤버함수*
+ queryIdx : 기준 영상 특징점(src1)
+ trainIdx : 대상 영상 특징점(src2)
+ imgIdx : 매칭할 영상(src2)를 여러장 줄 수 있는데 그중 가장 비슷한 것을 찾는 형태로 동작
+ distance
'''
# 좋은 매칭 결과 선별
# 값이 작은것이 먼저오고 큰 값이 뒤로
matches =sorted(matches, key=lambda x: x.distance)
good_matches = matches[:80]
print('# of kp1:', len(kp1))
print('# of kp2:', len(kp2))
print('# of matches:', len(matches)) # matching 개수는 kp1
print('# of good_matches:', len(good_matches)) # 80개
# 특징점 매칭 결과 영상 생성
dst = cv2.drawMatches(src1, kp1, src2, kp2, matches, None)
dst1 = cv2.drawMatches(src1, kp1, src2, kp2, good_matches, None)
cv2.namedWindow('dst', cv2.WINDOW_NORMAL)
cv2.imshow('dst', dst)
cv2.imshow('dst1', dst1)
cv2.waitKey()
cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2, outImg,
matchColor=None, singlePointColor=None, matchesMask=None,
flags=None) -> outImg
• img1, keypoints1: 기준 영상과 기준 영상에서 추출한 특징점 정보
• img2, keypoints2: 대상 영상과 대상 영상에서 추출한 특징점 정보
• matches1to2: 매칭 정보. cv2.DMatch의 리스트.
• outImg: 출력 영상
• matchColor: 매칭된 특징점과 직선 색상
• singlePointColor: 매칭되지 않은 특징점 색상
• matchesMask: 매칭 정보를 선택하여 그릴 때 사용할 마스크
• flags: 매칭 정보 그리기 방법.
기본값은 cv2.DRAW_MATCHES_FLAGS_DEFAULT.
좋은 매칭 선별 방법 2
• 가장 좋은 매칭 결과의 distance 값과 두 번째로 좋은 매칭 결과의 distance 값의 비율을 계산
# 영상 불러오기
src1 = cv2.imread('ch09\\images\\graf1.png', cv2.IMREAD_GRAYSCALE)
src2 = cv2.imread('ch09\\images\\graf3.png', cv2.IMREAD_GRAYSCALE)
if src1 is None or src2 is None:
print('Image load failed!')
sys.exit()
feature = cv2.KAZE_create()
# feature = cv2.AKAZE_create()
# feature = cv2.ORB_create()
kp1, desc1 = feature.detectAndCompute(src1, None)
kp2, desc2 = feature.detectAndCompute(src2, None)
matcher = cv2.BFMatcher_create()
# 이진 기술자의 경우
# matcher = cv2.BFMatcher_create(cv2.NORM_HAMMING)
matches = matcher.knnMatch(desc1, desc2, 2) # k: 매칭할 근접 이웃 개수
# [[DMatch], [DMatch]] 형태
'''
가장 좋은 매칭 결과의 distance 값과 두 번째로 좋은 매칭 결과의
distance 값의 비율을 계산
'''
good_matches = []
for m in matches: # len(matches) = 3159
# [0] 값이 작고 / [1] 값이 큼
# (<DMatch 0000025608092BF0>, <DMatch 0000025608092C10>) ....
if m[0].distance / m[1].distance < 0.7: # 비율이 임계값(e.g. 0.7)보다 작으면 선택
good_matches.append(m[0])
print('# of kp1:', len(kp1))
print('# of kp2:', len(kp2))
print('# of matches:', len(matches))
print('# of good_matches:', len(good_matches))
# 잘못된 매칭이 간혹 보이는데 호모그래피 사용하여 보완
dst = cv2.drawMatches(src1, kp1, src2, kp2, good_matches, None)
cv2.imshow('dst', dst)
cv2.waitKey()
728x90
'OpenCV > OpenCV-Chapter' 카테고리의 다른 글
CH09 OpenCV-Python 스티칭 Stitching(PANORAMA) (0) | 2021.12.25 |
---|---|
CH09 OpenCV-Python 호모그래피와 영상 매칭 (0) | 2021.12.25 |
CH09 OpenCV-Python SIFT, KAZE, AKAZE, ORB.. (0) | 2021.12.25 |
CH09 OpenCV-Python 특징점 검출(Corner) (0) | 2021.12.25 |
CH08 OpenCV-Python HOG 보행자 검출 (0) | 2021.12.24 |
댓글