SIFT의 동작은
아래와 같이 호출됩니다.
int sift_features( IplImage* img, struct feature** feat )
{
return _sift_features( img, feat,
SIFT_INTVLS,
SIFT_SIGMA,
SIFT_CONTR_THR,
SIFT_CURV_THR,
SIFT_IMG_DBL,
SIFT_DESCR_WIDTH,
SIFT_DESCR_HIST_BINS );
}
영상과 feature는 포인터로 전달되고 나머지는 매크로로 정의되어 있습니다. 이렇게 하면
최상위 함수는 매크로에 따라 파라미터를 줄 수 있고 이하 하위 함수들은 인자들을 기반으로 할 수 있으므로
프로그램 테스트 등이 편리해집니다.
정의된 매크로들은 나중에 코드를 읽어가면서 새로운 그리고 필요한 매크로가 나온다면, 그때마다
하나씩 확인해 가기로 하고 여기서는 건너 뜁니다.
실제 호출은 위의 코드에서 보는 바와 같이 _sift_features를 호출하여 구동합니다.
이 함수는 다음과 같은 순서로 동작합니다.
1. 인자를 검사해서 오류가 있는지 확인을 합니다.
2. 주어진 이미지로 이미지 피라미드를 구축합니다.
3. 구축한 이미지 피라미드에서 DoG를 구축합니다.
4. DoG에서 특징점들을 추출하고
5. 특징점 을 좌표에 매핑하고,
6. 특징점 기술자들을 논문대로 정리한다.
이를 위한 호툴된 함수는 다음과 같습니다.
기계적으로 따라갑니다.
int _sift_features( IplImage* img, struct feature** feat, int intvls,
double sigma, double contr_thr, int curv_thr,
int img_dbl, int descr_width, int descr_hist_bins )
{
IplImage* init_img;
IplImage*** gauss_pyr, *** dog_pyr;
CvMemStorage* storage;
CvSeq* features;
int octvs, i, n = 0;
/* check arguments
인자를 검사한다. NULL Pointer이면 에러를 출력한다.*/
if( ! img )
fatal_error( "NULL pointer error, %s, line %d", __FILE__, __LINE__ );
if( ! feat )
fatal_error( "NULL pointer error, %s, line %d", __FILE__, __LINE__ );
/* build scale space pyramid; smallest dimension of top level is ~4 pixels
이미지 피라미드를 구축한다.
최상위 피라미드는 그 크기가 4 픽셀 정도이다.
*/
/* 최초의 이미지를 만들어 냅니다. 이 이미지는 그레이 스케일로 생성됩니다.. */
init_img = create_init_img( img, img_dbl, sigma );
octvs = log( MIN( init_img->width, init_img->height ) ) / log(2) - 2;
/* 이미지를 가지고 가우시안 스케일 피라미드를 구성합니다. */
gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );
/* DoG 이미지 피라미드를 구성합니다. */
dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );
storage = cvCreateMemStorage( 0 );
DoG에서 특징점들을 열심히 추출합니다.
features = scale_space_extrema(
dog_pyr,
octvs,
intvls,
contr_thr,
curv_thr,
storage );
/* 추출된 특징들의 특성들을 계산합니다. */
calc_feature_scales( features, sigma, intvls );
/* 이미지가 2배로 키워서 특징점들을 추출하였을 경우 이를 다시 조절합니다. */
if( img_dbl )
adjust_for_img_dbl( features );
/* 정규 좌표를 계산합니다. */
calc_feature_oris( features, gauss_pyr );
/* Lowe’s Paper 6절에 따라서 특징점 기술자를 만들어냅니다. */
compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );
/* sort features by decreasing scale and move from CvSeq to array */
cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );
n = features->total;
*feat = calloc( n, sizeof(struct feature) );
*feat = cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ );
for( i = 0; i < n; i++ )
{
free( (*feat)[i].feature_data );
(*feat)[i].feature_data = NULL;
}
cvReleaseMemStorage( &storage );
cvReleaseImage( &init_img );
release_pyr( &gauss_pyr, octvs, intvls + 3 );
release_pyr( &dog_pyr, octvs, intvls + 2 );
return n;
}
'Computer Vision' 카테고리의 다른 글
SURF Lib (3) | 2010.06.22 |
---|---|
Rob Hess의 SIFT [8] (7) | 2009.06.21 |
OpenCV - Alpha Blending cvAddWeighted , cvFillPoly (2) | 2009.04.25 |
JPEG2AVI 를 맥에서 빌드하기 (0) | 2009.04.24 |
OpenCV - cvSmooth (2) | 2009.04.22 |