비전 신호 처리II_코너 검출

17881 단어 VSPcppopencvVSP

코너 검출

영상에서 특징(feature)이란 영상으로부터 추출할 수 있는 유용한 정보를 의미

평균 밝기, 히스토그램, 에지, 직선 성분, 코너 등이 특징이 될 수 있음
코너(corner)는 에지의 방향이 급격하게 변하는 부분으로서 삼각형의 꼭지점이나 연필 심처럼 뾰족하게 튀어나와 있는 부분이 코너가 될 수 있음

코너처럼 한 점의 형태로 표현할 수 있는 특징을 특징점(feature point)이라고 함

영상에서 코너(corner)를 찾는 기본적인 아이디어는 아래 그림과 같이 영상에서 작은 윈도우를 조금씩 이동(shift)시켰을 때, 코너점의 경우는 모든 방향으로 영상변화가 커야 한다는 점

Moravec(사람 이름)
영상의 각 픽셀 위치에 대해 윈도우를 수직, 수평, 좌대각선, 우대각선 이렇게 4개 방향으로 1 픽셀씩 이동시켰을 때의 영상변화량(SSD) E를 계산한 후, E의 최소값을 해당 픽셀의 영상변화량 값으로 설정, 설정된 min(E) 값이 지역적으로 극대가 되는 지점을 코너점으로 찾는 방법을 사용

해리스 코너 검출기

Moravec의 방법을 수정 보완
영상의 특정 위치 (x, y)에서 Δx와 Δy 만큼 떨어진 픽셀과의 밝기 차이를 다음 수식으로 표현
만약 E(Δx,Δy) 함수가 모든 방향으로 값이 크게 나타난다면 점 (x, y)는 코너라고 간주할 수 있음
해리스는 E(Δx,Δy)가 모든 방향으로 그 값이 크게 나타나는지를 검사하기 위해 테일러 급수(Taylor series), 고윳값 분석(eigenvalue analysis) 등의 수학적 기법을 적용하여 코너 응답 함수 R을 유도함
코너 응답 함수 정의에서 상수 k 는 보통 0.04~0.06 사이의 값을 사용

해리스에 의해 정의된 코너 응답 함수 R은 입력 영상 각각의 픽셀에서 정의되는 실수 값임
R이 0보다 충분히 큰 양수이면 코너 점이라고 간주
R이 0에 가까운 실수이면 평탄한 영역
R이 0보다 작은 음수이면 에지라고 판별

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

예제1_해리스 코너 검출기

이웃 픽셀 크기, sobel mask 크기, 상수 값 설정 가능
추출 결과 float 자료형
실수 값에 대한 정규화 과정 필요(normalize)
정규화된 값들 중 임계치 120 이상인 픽셀의 경우 비최대 억제 수행, 코너 검출

void corner_harris()
{
	Mat src = imread("keyboard.bmp", IMREAD_GRAYSCALE);
		
	if (src.empty())
	{
		cerr << "Image load failed" << endl;
		return;
	}

	Mat harris;
	cornerHarris(src, harris, 3, 3, 0.04); // 3, 3의 sobel mask 사용

	Mat harris_norm; //정규화 과정
	normalize(harris, harris_norm, 0, 255, NORM_MINMAX, CV_8U);

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

	for (int j = 1; j < harris.rows - 1; j++) //코너 추출
	{
		for (int i = 1; i < harris.cols - 1; i++)
		{
			if (harris_norm.at<uchar>(j, i) > 120)
			{
				if (harris.at<float>(j, i) > harris.at<float>(j - 1, i) &&
					harris.at<float>(j, i) > harris.at<float>(j + 1, i) &&
					harris.at<float>(j, i) > harris.at<float>(j, i - 1) &&
					harris.at<float>(j, i) > harris.at<float>(j, i + 1))
				{
					circle(dst, Point(i, j), 5, Scalar(0, 0, 255), 2);
				}
			}
		}
	}

	imshow("src", src);
	imshow("harris_norm", harris_norm);
	imshow("dst", dst);

	waitKey(0);
	destroyAllWindows();
}

int main()
{
	corner_harris();
	return 0;
}

harris_norm은 해리스 코너 응답 함수 값을 0부터 255 사이로 정규화 하여 나타낸 그레이스케일 영상
지역 최대인 지점을 선별하여, 빨간색 원으로 표시한 결과를 dst 창에 나타냄

FAST 검출

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

수학적으로 표현하기 위해 점 p에서의 밝기를 Ip라고 표현함
만약 주변 16개의 픽셀 중에서 그 값이 Ip + t보다 큰 픽셀이 아홉 개 이상 연속으로 나타나면 점 p는 어두운 영역이 뾰족하게 돌출되어 있는 코너임
반면에 주변 16개의 픽셀 중에서 그 값이 Ip - t 보다 작은 픽셀이 아홉 개 이상 연속으로 나타나면 점 p는 밝은 영역이 돌출되어 있는 코너라고 간주함
여기서 t 는 충분히 밝거나 어두운 정도를 조절하기 위한 임계값을 의미

예제2_FAST 코너 검출

OpenCV는 FAST 코너 검출 방법을 구현한 FAST()를 제공
주변 코너 픽셀 중에서 가장 코너에 적합한
픽셀을 선택하는 비최대 억제 작업을 추가적으로 수행하는 것이 좋음
검출된 모든 코너점에 반지름이 5인 원 생성

void corner_fast()
{
	Mat src = imread("keyboard.bmp", 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(0);
	destroyAllWindows();
}

int main()
{
	corner_fast();
	return 0;
}

특정 코너 점 주변 픽셀들도 함께 코너로 검출하는 경우가 많음
경계 부분 혹은 모서리 부분에서 다수의 코너가 검출

좋은 웹페이지 즐겨찾기