OpenCV | 코너 검출

박나연·2021년 6월 5일
0

OpenCV

목록 보기
37/40

해리스 코너 검출 방법

템플릿 매칭의 한계점을 해결하기 위해 두 영상 사이에 기하학적 변환이 있어도 효과적으로 사용할 수 있는 지역 특징점 기반 매칭 방법에 대해 살펴본다.

영상에서 특징이란 영상으로부터 추출할 수 있는 유용한 정보를 의미하며, 평균 밝기, 히스토그램, 에지, 직선 성분, 코너 등이 특징이 될 수 있다. 영상의 특징 중에서 에지, 직선 성분, 코너처럼 영상 전체가 아닌 일부 영역에서 추출할 수 있는 특징을 지역 특징이라고 한다. 영상의 지역 특징 중 코너는 에지의 방향이 급격하게 편하는 부분으로서 삼각형의 꼭지점이나 연필 심처럼 뾰족하게 튀어나와 있는 부분이 코너가 될 수 있다.

코너는 에지나 직선 성분 등의 다른 지역 특징에 비해 분별력이 높고 대체로 영상 전 영역에 골고루 분포하기 때문에 영상을 분석하는 데 유용한 지역 특징으로 사용된다. 코너처럼 한 점의 형태로 표현할 수 있는 특징을 특징점이라고 하며, 특징점은 키포인트 또는 관심점이라고 부르기도 한다.


해리스 코너 검출 방법에서는, 영상의 특정 위치에서 delta x와 delta y만큼 떨어진 픽셀과의 밝기 차이를 다음 수식으로 표현한다.

w(x,y)는 균일한 값을 갖는 사각형 윈도우 또는 가우시안 형태의 가중치를 갖는 윈도우이다. 만약 E()함수가 모든 방향으로 값이 크게 나타난다면 점 (x,y)는 코너라고 간주 할 수 있다.

모든 방향으로 그 값이 크게 나타나는지 확인하기 위해 테일러 급수, 고윳값 분석 등의 수학적 기법을 적용하여 코너 응답 함수 R을 유도한다.

Det()는 행렬식, Tr()는 대각합을 의미하고, 행렬 M은 다음과 같이 정의된다.

앞 수식에서 각 I는 x축방향과 y축방향으로 편미분한 결과이다. 보통 k는 0.04 ~ 0.06 사이의 값을 사용한다.

R은 입력영상 각각의 픽셀에서 정의되는 실수 값이며, 0에 가까운 실수이면 평탄한 영역, 0보다 작은 음수이면 에지라고 판별한다.

OpenCV는 해리스 코너 응답함수 값을 계산하는 cornerHarris()함수를 제공한다.

cornerHarris()

void cornerHarris(InputArray src, OutputArray dst, int blockSize, 
int ksize, double k, int borderType = BORDER_DEFAULT);

src : 입력영상
dst : 해리스 코너 응답 함수 값을 저장할 행렬
blockSize : 행렬 M연산에 사용할 이웃 픽셀 크기
ksize : 소벨 연산자를 위한 커널 크기
k : 해리스 코너 검출 상수
borderType : 가장자리 픽셀 확장 방식


FAST 코너 검출 방법

FAST 코너 검출 방법은 단순한 픽셀 값 비교 방법을 통해 코너를 검출한다. 영상의 모든 픽셀에서 픽셀을 둘러싸고 있는 16개의 주변 픽셀과 밝기를 비교하여 코너 여부를 판별한다. 만약 주변 16개의 픽셀 중에서 점 p보다 충분히 밝거나 또는 충분히 어두운 픽셀이 아홉개 이상 연속으로 존재하면 코너로 정의한다.

OpenCV 는 FAST 코너 검출 방법을 구현한 FAST()함수를 제공한다.

FAST()

void FAST(InputArray image, std::vector<KeyPoint>& keypoints,
int threshold ,bool nonmaxSuppression = true);

image : 입력 그레이스케일 영상
keypoints : 검출된 특징점을 표현하는 KeyPoint 객체의 벡터
threshold : 중심 픽셀 값과 주변 픽셀 값과의 차이 임계값
nonmaxSuppression : 비최대 억제 수행 여부


void corner_fast() {
	Mat src = imread("building.jpg", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return;
	}

	vector<KeyPoint> keypoints;
	FAST(src, keypoints, 60, true);

	Mat dst;
	cvtColor(src, dst, COLOR_GRAY2BGR);

	for (KeyPoint kp : keypoints) {
		Point pt(cvRound(kp.pt.x), cvRound(kp.pt.y));
		circle(dst, pt, 5, Scalar(0, 0, 255), 2);
	}
	imshow("src", src);
	imshow("dst", dst);

	waitKey();
	destroyAllWindows();
}

profile
Data Science / Computer Vision

0개의 댓글