코너검출

Developer/OpenCV 2013. 1. 21. 21:19

객체를 효과적으로 추적하기 위해서는 독특하고 유일한 점을 선택하여, 다음 프레임에서 동일 한점을 다시 찾는다면 효과적인 추적이 될것이다. 이과같이 독특하고 유일한점을 코너라고한다.


코너

미분값이 크게 나타나는 점(픽셀값의 변화량이 큰점)은 영상에서 엣지 부변에 존재하는 점이 될것이다. 하지만 같은 엣지 상에 있는 점들은 모두 유사한 특성을 나타낼수 있기때문에 유일한점이라고 할수없다. 따라서 큰 미분값이 서로 직교하는 방향에서 동시에 나타난다면 이 점은 매우 독특 한점이라고 할수있다. 이와같이 직교하는 방향으로 미분값이 크게 나타나는 점들이 추적하기에 적합하며 이 점을 코너라고 부른다.


해리스 코너검출

영상의 밝기값의 2차미분값(픽셀값 변화량의 변화량)을 이용

각 점에 작은 윈도우를 설정하고, 이 윈도우 내에서 2차 미분 영상의 자기상관행렬을 구한다.

자기상관행렬의 고유값 두개가 모두 큰값을 가질경우 코너라고 판별한다.

Shi와 Tomasi는 두개의 고유값 중에서 작은 고유값의 크기가 특정 임계값도다 큰경우, 이 점이 좋은 코너


cvGoodFeatureToTrack()

2차 미분을 계산하고, 계산된 미분으로부터 고유값을 계산한다. 추적하기 좋은 특징들의 목록을 반환한다.

 void cvGoodFeaturesToTrack(

        const CvArr* image,

        CvArr* eig_image,

        CvArr* temp_image,

        CvPoint2D32f* corners,

        int* corner_count,

        double  quality_level,

        double  min_distance,

        const CvArr* mask=NULL,

        int block_size=3,

        int use_harris=0,

        double k=0.04

);

image : 입력영상, 8비트 또는 32비트인 단일 영상이어야한다.

eigImage : 함수 내부에서 알고리즘 계산을 위해 사용된다, 해당 픽셀에서 구해진 최소 고유값이 저장된다.

tempImage : 함수 내부에서 알고리즘 계산을 위해 사용된다.

corners : 실행 후 결과 점들이 저장될 32비트 실수형점의 배열, 이배열은 함수 호출전 미리 할당되어야한다.

corner_count : 함수가 검출할 수 있는 코너 점들의 최대 개수, 실행후 코너의 개수가 저장된다.

quality_level : 코너의 품질을 결정하는 역할, 코너 판별을 위해 사용되는 고유값의 임계값은 영상에ㅔ서 구한 작은 고유값들 중에서 

                       최대값과 quality_level을 곱하여 결정된다, 따라서 1을 넘어서는 안되고 보통 0.10, 0.01정도의 값을 갖는다.

min_distance : 반환되는 코너 점들 사이의 최소 거리(유클라디안 거리)

mask : 관심영역을 지정하는 용도로 사용된다. NULL일경우 전체에서 코너를 검출

block_size : 미분 계수의 자기 상관행렬을 계산할때 사용되는 블록의 크기

use_harris : 해리스 코너방법이 사용될지 말지를 나타냄

k : 코너 응답 함수식에서 대각합에 대한 가중치


 #include <cv.h>

#include <highgui.h>

 

const int MAX_CORNERS=500;

 

int main(void) {

       

        cvNamedWindow("lueseypid", CV_WINDOW_AUTOSIZE);

        IplImage* src=cvLoadImage("OpenCV_Chessboard.png", CV_LOAD_IMAGE_GRAYSCALE);

        IplImage* displayImg=cvLoadImage("OpenCV_Chessboard.png", CV_WINDOW_AUTOSIZE);

 

 

        IplImage* eig_image=cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 1);

        IplImage* temp_image=cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 1);

        CvPoint2D32f* corners=new CvPoint2D32f[MAX_CORNERS];

        int corner_count=MAX_CORNERS;

 

        cvGoodFeaturesToTrack(src, eig_image, temp_image, corners, &corner_count,

               0.05, 5.0, 0, 3, 0, 0.04);

 

        for(int i=0; i<corner_count; i++) {

               printf("{%f, %f}\n", corners[i].x, corners[i].y);

               cvCircle(displayImg, cvPoint(corners[i].x, corners[i].y), 5, CV_RGB(255, 0, 0), -1, 8);

        }

 

        cvShowImage("lueseypid", displayImg);

        cvWaitKey(0);

        cvReleaseImage(&src);

        cvDestroyWindow("lueseypid");

}


[출력결과]





Posted by No names
,