SIFT算法实现理解及注释详解基于RobHess源码.docx

上传人:b****5 文档编号:12328559 上传时间:2023-04-18 格式:DOCX 页数:37 大小:29.13KB
下载 相关 举报
SIFT算法实现理解及注释详解基于RobHess源码.docx_第1页
第1页 / 共37页
SIFT算法实现理解及注释详解基于RobHess源码.docx_第2页
第2页 / 共37页
SIFT算法实现理解及注释详解基于RobHess源码.docx_第3页
第3页 / 共37页
SIFT算法实现理解及注释详解基于RobHess源码.docx_第4页
第4页 / 共37页
SIFT算法实现理解及注释详解基于RobHess源码.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

SIFT算法实现理解及注释详解基于RobHess源码.docx

《SIFT算法实现理解及注释详解基于RobHess源码.docx》由会员分享,可在线阅读,更多相关《SIFT算法实现理解及注释详解基于RobHess源码.docx(37页珍藏版)》请在冰豆网上搜索。

SIFT算法实现理解及注释详解基于RobHess源码.docx

SIFT算法实现理解及注释详解基于RobHess源码

RobHess的SIFT算法实现理解及注释

    SIFT算法不用我多解释了,这是一个很强大的算法,主要用于图像配准和物体识别等领域,但是其计算量相比也比较大,性价比比较高的算法包括PCA-SIFT和SURF其中OpenCV提供了SURF算法,但是为了方便理解。

这里给出了RobHess所实现的SIFT算法的实现以及注释,结合我自己的理解,如果,您有关于SIFT算法不理解的地方咱们可以一起交流一下。

或者您认为不详细的地方提出来。

    SIFT算法的主要实现在sift.c这个文件,其主要流程为:

(1)首先创建初始图像,即通过将图像转换为32位的灰度图,然后将图像使用三次插值来方大,之后通过高斯模糊处理

(2)在此基础上进行高斯金字塔的构建以及高斯差分金字塔的构建

(3)对图像进行极值点检测

(4)计算特征向量的尺度

(5)调整图像大小

(6)计算特征的方向

(7)计算描述子,其中包括计算二维方向直方图并转换直方图为特征描述子

首先给出sift算法的整体框架代码:

输入参数:

img为输入图像;

feat为所要提取的特征指针;

intvl指的是高斯金字塔和差分金字塔的层数;

sigma指的是图像初始化过程中高斯模糊所使用的参数;

 contr_thr是归一化之后的去除不稳定特征的阈值;

curv_thr指的是去除边缘的特征的主曲率阈值;

img_dbl是是否将图像放大为之前的两倍;

descr_with用来计算特征描述子的方向直方图的宽度;

descr_hist_bins是直方图中的条数

1.int _sift_features( IplImage* img, struct feature** feat, int intvls,  

2.                   double sigma, double contr_thr, int curv_thr,  

3.                   int img_dbl, int descr_width, int descr_hist_bins )  

4.{  

5.    IplImage* init_img;  

6.    IplImage*** gauss_pyr, *** dog_pyr;  

7.    CvMemStorage* storage;  

8.    CvSeq* features;  

9.    int octvs, i, n = 0;  

10.  

11.    /* check arguments */  

12.    if( !

 img )  

13.        fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );  

14.  

15.    if( !

 feat )  

16.        fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );  

17.  

18.    /* build scale space pyramid; smallest dimension of top level is ~4 pixels */  

19.    /* 构建高斯尺度空间金字塔,顶层最小的为4像素 */  

20.    init_img = create_init_img( img, img_dbl, sigma );  

21.    octvs = log( double MIN( init_img->width, init_img->height ) ) / log(2.0) - 2;  

22.    //构建高斯金字塔和高斯差分金字塔  

23.    gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );  

24.    dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );  

25.  

26.    storage = cvCreateMemStorage( 0 );  

27.  

28.    //尺度空间极值点检测  

29.    features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr,  

30.        curv_thr, storage );  

31.      

32.    //画出去除低对比度的极值点  

33.    //draw_extrempoint(img , features);  

34.  

35.  

36.  

37.  

38.    //计算特征向量的尺度  

39.    calc_feature_scales( features, sigma, intvls );  

40.    if( img_dbl )  

41.        adjust_for_img_dbl( features );  

42.    //计算特征的方向  

43.    calc_feature_oris( features, gauss_pyr );  

44.    //计算描述子,包括计算二维方向直方图和转换其为特征描述子  

45.    compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins );  

46.  

47.    /* sort features by decreasing scale and move from CvSeq to array */  

48.    cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL );  

49.    n = features->total;  

50.    *feat = static_cast( calloc( n, sizeof(struct feature) ) );  

51.    *feat = static_cast( cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ ) );  

52.  

53.  

54.  

55.  

56.    for( i = 0; i < n; i++ )  

57.    {  

58.        free( (*feat)[i].feature_data );  

59.        (*feat)[i].feature_data = NULL;  

60.    }  

61.  

62.    cvReleaseMemStorage( &storage );  

63.    cvReleaseImage( &init_img );  

64.    release_pyr( &gauss_pyr, octvs, intvls + 3 );  

65.    release_pyr( &dog_pyr, octvs, intvls + 2 );  

66.    return n;  

67.}  

(1)初始化图像

输入参数:

这里不需要解释了

该函数主要用来初始化图像,转换图像为32位灰度图以及进行高斯模糊。

1.static IplImage* create_init_img( IplImage* img, int img_dbl, double sigma )  

2.{  

3.    IplImage* gray, * dbl;  

4.    float sig_diff;  

5.  

6.    gray = convert_to_gray32( img );  

7.    if( img_dbl )  

8.    {  

9.        sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA * 4 );  

10.        dbl = cvCreateImage( cvSize( img->width*2, img->height*2 ),  

11.            IPL_DEPTH_32F, 1 );  

12.        cvResize( gray, dbl, CV_INTER_CUBIC );  

13.        cvSmooth( dbl, dbl, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );  

14.        cvReleaseImage( &gray );  

15.        return dbl;  

16.    }  

17.    else  

18.    {  

19.        sig_diff = sqrt( sigma * sigma - SIFT_INIT_SIGMA * SIFT_INIT_SIGMA );  

20.        cvSmooth( gray, gray, CV_GAUSSIAN, 0, 0, sig_diff, sig_diff );  

21.        return gray;  

22.    }  

23.}  

(2)构建高斯金字塔

输入参数:

octvs是高斯金字塔的组

invls是高斯金字塔的层数

sigma是初始的高斯模糊参数,后续也通过它计算每一层所使用的sigma

1.

13px;">static IplImage*** build_gauss_pyr( IplImage* base, int octvs,int intvls, double sigma )  

2.{  

3.    IplImage*** gauss_pyr;  

4.    double* sig = static_cast( calloc( intvls + 3, sizeof(double)) );  

5.    double sig_total, sig_prev, k;  

6.    int i, o;  

7.  

8.    gauss_pyr = static_cast( calloc( octvs, sizeof( IplImage** ) ) );  

9.    for( i = 0; i < octvs; i++ )  

10.        gauss_pyr[i] = static_cast( calloc( intvls + 3, sizeof( IplImage* ) ) );  

11.  

12.    /* 

13.        precompute Gaussian sigmas using the following formula:

 

14.        预计算每次高斯模糊的sigma 

15. 

16.        \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2 

17.    */  

18.    sig[0] = sigma;  

19.    k = pow( 2.0, 1.0 / intvls );  

20.    for( i = 1; i < intvls + 3; i++ )  

21.    {  

22.        sig_prev = pow( k, i - 1 ) * sigma;  

23.        sig_total = sig_prev * k;  

24.        sig[i] = sqrt( sig_total * sig_total - sig_prev * sig_prev );  

25.    }  

26.      

27.      

28.    for( o = 0; o < octvs; o++ )  

29.        for( i = 0; i < intvls + 3; i++ )  

30.        {  

31.            //对每一层进行降采样,形成高斯金字塔的每一层  

32.            if( o == 0  &&  i == 0 )  

33.                gauss_pyr[o][i] = cvCloneImage(base);  

34.  

35.            /* base of new octvave is halved image from end of previous octave */  

36.            //每一组的第一层都是通过对前面一组的最上面一层的降采样实现的  

37.            else if( i == 0 )  

38.                gauss_pyr[o][i] = downsample( gauss_pyr[o-1][intvls] );  

39.  

40.            /* blur the current octave's last image to create the next one */  

41.            //每一组的其他层则使通过使用不同sigma的高斯模糊来进行处理  

42.            else  

43.            {  

44.                gauss_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i-1]),  

45.                    IPL_DEPTH_32F, 1 );  

46.                cvSmooth( gauss_pyr[o][i-1], gauss_pyr[o][i],  

47.                    CV_GAUSSIAN, 0, 0, sig[i], sig[i] );  

48.            }  

49.        }  

50.  

51.    free( sig );  

52.    return gauss_pyr;  

53.}  

降采样处理

输入参数:

不解释

这就是降采样,其实就是将图像通过最近邻算法缩小为原来的一半

1.static IplImage* downsample( IplImage* img )  

2.{  

3.    IplImage* smaller = cvCreateImage( cvSize(img->width / 2, img->height / 2),  

4.        img->depth, img->nChannels );  

5.    cvResize( img, smaller, CV_INTER_NN );  

6.  

7.    return smaller;  

8.}  

(3)构建高斯差分金字塔

输入参数:

不解释了参见上面的说明即可

实际上差分金字塔的构成是通过对相邻层的图像进行相减获得的

1.

16px;">static IplImage*** build_dog_pyr( IplImage*** gauss_pyr, int octvs, int intvls )  

2.{  

3.    IplImage*** dog_pyr;  

4.    int i, o;  

5.  

6.    dog_pyr = static_cast( calloc( octvs, sizeof( IplImage** ) ) );  

7.    for( i = 0; i < octvs; i++ )  

8.        dog_pyr[i] = static_cast( calloc( intvls + 2, sizeof(IplImage*) ) );  

9.  

10.    for( o = 0; o < octvs; o++ )  

11.        for( i = 0; i < intvls + 2; i++ )  

12.        {  

13.            dog_pyr[o][i] = cvCreateImage( cvGetSize(gauss_pyr[o][i]),  

14.                IPL_DEPTH_32F, 1 );  

15.            cvSub( gauss_pyr[o][i+1], gauss_pyr[o][i], dog_pyr[o][i], NULL );  

16.        }  

17.  

18.    return dog_pyr;  

19.}  

(4)极值点检测

输入参数:

contr_thr是去除对比度低的点所采用的阈值

curv_thr是去除边缘特征的阈值

1.static CvSeq* scale_space_extrema( IplImage*** dog_pyr, int octvs, int intvls,  

2.                                   double contr_thr, int curv_thr,  

3.                                   CvMemStorage* storage )  

4.{  

5.    CvSeq* features;  

6.    double prelim_contr_thr = 0.5 * contr_thr / intvls;  

7.    struct feature* feat;  

8.    struct detection_data* ddata;  

9.    int o, i, r, c;  

10.  

11.    features = cvCreateSeq( 0, sizeof(CvSeq), sizeof(struct feature), storage );  

12.    for( o = 0; o < octvs; o++ )  

13.        for( i = 1; i <= intvls; i++ )  

14.            for(r = SIFT_IMG_BORDER; r < dog_pyr[o][0]->height-SIFT_IMG_BORDER; r++)  

15.                for(c = SIFT_IMG_BORDER; c < dog_pyr[o][0]->width-SIFT_IMG_BORDER; c++)  

16.                    /* perform preliminary check on contrast */  

17.                    if( ABS( pixval32f( dog_pyr[o][i], r, c ) ) > prelim_contr_thr )  

18.                        if( is_extremum( dog_pyr, o, i, r, c ) )  

19.                        {  

20.                            feat = interp_extremum(dog_pyr, o, i, r, c, intvls, contr_thr);  

21.                            if( feat )  

22.                            {  

23.                                ddata = feat_detection_data( feat );  

24.                                if( !

 is_too_edge_like( dog_pyr[ddata->octv][ddata->intvl],  

25.                                    ddata->r, ddata->c, curv_thr ) )  

26.                                {  

27.                                    cvSeqPush( features, feat );  

28.                                }  

29.                                else  

30.                                    free( ddata );  

31.                                free( feat );  

32.                            }  

33.                        }  

34.  

35.    return features;  

36.}  

SIFT_IMG_BORDER是预定义的图像边缘;

通过和对比度阈值比较去掉低对比度的点;

而通过is_extremum来判断是否为极值点,如果是则通过极值点插值的方式获取亚像素的极值点的位置。

然后通过is_too_eage_like和所给的主曲率阈值判断是否为边缘点

*判断是否为极值点

其原理为:

通过和高斯金字塔的上一层的9个像素+本层的除了本像素自己的其他的8个像素和下一层的9个像素进行比较看是否为这26个像素中最小的一个或者是否为最大的一个,如果是则为极值点。

1.static int is_extremum( IplImage*** dog_pyr, int octv, int intvl, int r, int c

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1