코너 검출
코너는 영상안에서 그림이 나타날 때 객체가 뾰족하게 튀어나온 부분이다.
코너는 변별력이 높은 편이며, 영상의 이동, 회전 변환에 강하다.
이와 반대로 평탄한 영역(flat)과 에지(edge) 영역은 고유한 위치를 찾기 어렵다.
A : 평탄
B : 엣지
C : 코너
평탄한 영역은 하늘에서 추출한 부분 영상으로, 이 부분 영상이 원본 영상에서 어느 부분인지 명확하지 않다.
모호한 부분이 많아 변별력이 떨어지며, 영상의 특징을 설명하는 데 적합하지 않다.
에지는 바다와 하늘이 만나는 부분으로, 원본 영상에서 x좌표가 명확하게 어느 부분인지 정확하게 찾기가 어렵다.
고유성과 변별성이 떨어진다.
코너는 로컬한 특징을 갖고있어서 변별성이 있고 고유성이 있다.
코너점을 찾아서 점들의 특징을 이용하여 두 개의 영상을 비교하거나 차이점을 찾거나 매칭을 하는 용도로 쓰인다.
다양한 코너 검출 방법
해리스 - Harris
- 1980년대에 나온 코너 검출 방법으로 성능이 좋기보다 코너점을 검출하는 이론적 토대를 잘 만들어서 유명
- Harris 함수이 반환한 값에 임계점을 설정해서 사용 (후처리 필요)
- 영상 내부 작은 영역이 모든 방향에 대해 변화가 큰 경우 코너로 규정
- 코너 응답 함수 R을 반환 -> R(x,y)가 충분히 크면 코너로 구분
- cv2.cornerHarris() 함수 사용
추적하기 좋은 특징 - Good Features to Track
- 해리스 코너 검출을 업그레이드 방법. 헤리스 코너 검출은 점이 붙어 있을수도 있고 로컬 맥시멀이 아닌 경우도 검출할 수 있음.
- 추적하지 좋은 특징 방법은 비최대 억제 수행으로 로컬맥시멈을 검출
- 반환값은 코너점을 반환
- 코너 품질 함수를 정의 -> 가장 값이 큰 순서대로 정렬하여 반환
- cv2.goodFeaturesToTrack() 함수 사용
FAST - Features from Accelerated Segment Test
- 기존의 방법들과 접근 방법이 다르게 코너를 검출
- 특정 픽셀 주변 16개 픽셀 값들을 조사해서 그 픽셀값이 가운데 픽셀보다 충분히 어둡거나 충분히 밝은 픽셀이 9개 이상 나타나면 코너라고 판단
- 기준 픽셀(p)보다 충분히 밝거나 또는 충분히 어두운 픽셀이 n개 연속으로 나타나면 코너로 인식(n은 보통 9)
- 해리스, GFTT 방법보다 매우 빠르게 동작
해리스 코너 응답 함수 계산 - cv2.cornerHarris
dst = cv2.cornerHarris(src, blockSize, ksize, k, dst=None, borderType=None)
- src : 입력 단일채널 8비트 또는 실수형 영상
- blockSize : 코너 응답 함수 계산에서 고려할 이웃 픽셀 크기. 보통 2~5.
- ksize : (미분을 위한) 소벨 연산자를 위한 커널 크기. 보통 3.
- k : 해리스 코너 검출 상수 (보통 0.04~0.06)
- dst : 해리스 코너 응답 계수. src와 같은 크기의 행렬(numpy.ndarray). dtype=numpy.float32.
- borderType : 가장자리 픽셀 확장 방식. 기본값은 cv2.BORDER_DEFAULT
추적하기 좋은 특징 코너 검출 - cv2.goodFeaturesToTrack()
corners = cv2.goodFeaturesToTrack(image,
maxCorners,
qualityLevel,
minDistance,
corners=None,
mask=None,
blockSize=None,
useHarrisDetector=None,
k=None)
- image: 8비트 또는 32비트 실수, 단일채널 영상
- maxCorners: 최대 코너 개수. maxCorners <=0 이면 무제한.
- qualityLevel: 코너점 결정을 위한 값. 보통 0.01 ~ 0.1.
- minDistance: 코너점 사이의 최소 거리
- corners: 검출된 코너점 좌표. numpy.ndarray. shape=(N, 1, 2). dtype=numpy.float32.
- mask: 마스크 영상
- blockSize: 코너 검출을 위한 블록 크기. 기본값은 3.
- useHarrisDetector: 해리스 코너 방법 사용 여부. 기본값은 False.
- k: 해리스 코너 검출 시 사용할 k 값
mindistancd는 코너점이 너무 근접하게 나타나면 하나를 버린다. 10으로 설정하면 10픽셀 근방 점들중 가장 큰거를 선택하고 나머지는 버린다.
FAST 코너 검출 - cv2.FastFeatureDetector_create()
cv2.FastFeatureDetector_create() 함수로 클래스 객체를 만들고 .detect() 함수로 코너점을 검출
retval = cv2.FastFeatureDetector_create(,
threshold=None,
nonmaxSuppression=None,
type=None)
- threshold: 중심 픽셀 값과 주변 픽셀 값과의 차이 임계값. 기본값은 10. 30~60 적절
- nonmaxSuppression: 비최대 억제 수행 여부. 기본값은 True.
- type: 코너 검출 방법. 기본값은 cv2.FAST_FEATURE_DETECTOR_TYPE_9_16.
- retval: FastFeatureDetector 객체
keypoints = cv2.FastFeatureDetector.detect(image)
- image: (입력) 그레이스케일 영상
- keypoints: (출력) 검출된 코너점 정보. cv2.KeyPoint 객체를 담은 리스트.
cv2.KeyPoint의 pt 멤버를 이용하여 코너 좌표 추출.
pt[0]은 x좌표, pt[1]은 y좌표.
GFTT와 FAST 코너 검출 예제
황선규 박사님 github홈페이지 sunkyoo.github.io/opencv4cvml/
import sys
import numpy as np
import cv2
src = cv2.imread('building.jpg', cv2.IMREAD_GRAYSCALE)
if src is None:
print('Image load failed!')
sys.exit()
tm = cv2.TickMeter()
# GFTT
tm.start()
corners = cv2.goodFeaturesToTrack(src, 400, 0.01, 10)
tm.stop()
print('GFTT: {}ms.'.format(tm.getTimeMilli()))
dst1 = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
if corners is not None:
for i in range(corners.shape[0]):
pt = (int(corners[i, 0, 0]), int(corners[i, 0, 1]))
cv2.circle(dst1, pt, 5, (0, 0, 255), 2)
# FAST
tm.reset()
tm.start()
fast = cv2.FastFeatureDetector_create(60)
keypoints = fast.detect(src)
tm.stop()
print('FAST: {}ms.'.format(tm.getTimeMilli()))
dst2 = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
for kp in keypoints:
pt = (int(kp.pt[0]), int(kp.pt[1]))
cv2.circle(dst2, pt, 5, (0, 0, 255), 2)
cv2.imshow('src', src)
cv2.imshow('dst1', dst1)
cv2.imshow('dst2', dst2)
cv2.waitKey()
cv2.destroyAllWindows()
코너 검출 방법 성능 비교
FAST 방법의 반복 검출률이 대체로 높습지만, 노이즈에 민감하다.
영상에 변형이 있더라도 FAST는 코너를 잘 찾지만 입력 영상에 노이즈가 들어가게 되면 검출률이 떨어진다.
하지만 속도가 월등히 빨라 가우시안 블러를 적용해서 사용하는 경우도 많다.
'OpenCV' 카테고리의 다른 글
[OpenCV with Python] 특징점 검출과 매칭 : 특징점 기술 (0) | 2022.02.05 |
---|---|
[OpenCV with Python] 특징점 검출과 매칭 : 특징점 검출 (0) | 2022.02.05 |
[OpenCV with Python] 영상 분할과 객체 검출 : HOG 알고리즘 - 보행자 검출 (0) | 2022.02.05 |
[OpenCV with Python] 영상 분할과 객체 검출 : 캐스케이드 분류기 - 얼굴 검출 (0) | 2022.02.05 |
[OpenCV with Python] 영상 분할과 객체 검출 : 템플릿 매칭2 - 인쇄체 숫자 인식 (0) | 2022.02.04 |