99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀KD樹的應用(1)SIFT+KD_BBF搜索算法
KD樹的應用(1)SIFT+KD_BBF搜索算法
2014-12-03
收藏

KD樹的應用(1)SIFT+KD_BBF搜索算法

3.1、SIFT特征匹配算法    

    之前本blog內(nèi)闡述過圖像特征匹配SIFT算法,寫過五篇文章,這五篇文章分別為:

  • 九、圖像特征提取與匹配之SIFT算法      (sift算法系列五篇文章)
  • 九(續(xù))、sift算法的編譯與實現(xiàn)
  • 九(再續(xù))、教你一步一步用c語言實現(xiàn)sift算法、上
  • 九(再續(xù))、教你一步一步用c語言實現(xiàn)sift算法、下
  • 九(三續(xù)):SIFT算法的應用--目標識別之Bag-of-words模型

    不熟悉SIFT算法相關概念的可以看上述幾篇文章,這里不再做贅述。與此同時,本文此部分也作為十五個經(jīng)典算法研究系列里SIFT算法的九之四續(xù)。

    OK,我們知道,在sift算法中,給定兩幅圖片圖片,若要做特征匹配,一般會先提取出圖片中的下列相關屬性作為特征點:

  1. /** 
  2. Structure to represent an affine invariant image feature.  The fields 
  3. x, y, a, b, c represent the affine region around the feature: 
  4.  
  5. a(x-u)(x-u) + 2b(x-u)(y-v) + c(y-v)(y-v) = 1 
  6. */  
  7. struct feature  
  8. {  
  9.     double x;                      /**< x coord */  
  10.     double y;                      /**< y coord */  
  11.     double a;                      /**< Oxford-type affine region parameter */  
  12.     double b;                      /**< Oxford-type affine region parameter */  
  13.     double c;                      /**< Oxford-type affine region parameter */  
  14.     double scl;                    /**< scale of a Lowe-style feature */  
  15.     double ori;                    /**< orientation of a Lowe-style feature */  
  16.     int d;                         /**< descriptor length */  
  17.     double descr[FEATURE_MAX_D];   /**< descriptor */  
  18.     int type;                      /**< feature type, OXFD or LOWE */  
  19.     int category;                  /**< all-purpose feature category */  
  20.     struct feature* fwd_match;     /**< matching feature from forward image */  
  21.     struct feature* bck_match;     /**< matching feature from backmward image */  
  22.     struct feature* mdl_match;     /**< matching feature from model */  
  23.     CvPoint2D64f img_pt;           /**< location in image */  
  24.     CvPoint2D64f mdl_pt;           /**< location in model */  
  25.     void* feature_data;            /**< user-definable data */  
  26.     char dense;                     /*表征特征點所處稠密程度*/  
  27. };  
    而后在sift.h文件中定義兩個關鍵函數(shù),這里,我們把它們稱之為函數(shù)一,和函數(shù)二,如下所示:

函數(shù)一的聲明:

  1. extern int sift_features( IplImage* img, struct feature** feat );  

函數(shù)一的實現(xiàn):

  1. int sift_features( IplImage* img, struct feature** feat )  
  2. {  
  3.     return _sift_features( img, feat, SIFT_INTVLS, SIFT_SIGMA, SIFT_CONTR_THR,  
  4.                             SIFT_CURV_THR, SIFT_IMG_DBL, SIFT_DESCR_WIDTH,  
  5.                             SIFT_DESCR_HIST_BINS );  
  6. }  
從上述函數(shù)一的實現(xiàn)中,我們可以看到,它內(nèi)部實際上調(diào)用的是這個函數(shù):_sift_features(..),也就是下面馬上要分析的函數(shù)二。

函數(shù)二的聲明:

  1. extern 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 );  

函數(shù)二的實現(xiàn):

  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,n0 = 0,n1 = 0,n2 = 0,n3 = 0,n4 = 0;  
  10.     int start;  
  11.   
  12.     /* check arguments */  
  13.     if( ! img )  
  14.         fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );  
  15.   
  16.     if( ! feat )  
  17.         fatal_error( "NULL pointer error, %s, line %d",  __FILE__, __LINE__ );  
  18.   
  19.     /* build scale space pyramid; smallest dimension of top level is ~4 pixels */  
  20.     start=GetTickCount();  
  21.     init_img = create_init_img( img, img_dbl, sigma );  
  22.     octvs = log( (float)(MIN( init_img->width, init_img->height )) ) / log((float)(2.0)) -5;  
  23.     gauss_pyr = build_gauss_pyr( init_img, octvs, intvls, sigma );  
  24.     dog_pyr = build_dog_pyr( gauss_pyr, octvs, intvls );  
  25.     fprintf( stderr, " creat the pyramid use %d\n",GetTickCount()-start);  
  26.   
  27.     storage = cvCreateMemStorage( 0 );    //創(chuàng)建存儲內(nèi)存,0為默認64k  
  28.     start=GetTickCount();  
  29.     features = scale_space_extrema( dog_pyr, octvs, intvls, contr_thr,  
  30.         curv_thr, storage );  //在DOG空間尋找極值點,確定關鍵點位置  
  31.     fprintf( stderr, " find the extrum points in DOG use %d\n",GetTickCount()-start);  
  32.   
  33.     calc_feature_scales( features, sigma, intvls ); //計算關鍵點的尺度  
  34.   
  35.     if( img_dbl )  
  36.         adjust_for_img_dbl( features );  //如果原始空間圖擴大,特征點坐標就縮小  
  37.     start=GetTickCount();  
  38.     calc_feature_oris( features, gauss_pyr );  //在gaussian空間計算關鍵點的主方向和幅值  
  39.     fprintf( stderr, " get the main oritation use %d\n",GetTickCount()-start);  
  40.   
  41.     start=GetTickCount();  
  42.     compute_descriptors( features, gauss_pyr, descr_width, descr_hist_bins ); //建立關鍵點描述器  
  43.     fprintf( stderr, " compute the descriptors use %d\n",GetTickCount()-start);  
  44.   
  45.     /* sort features by decreasing scale and move from CvSeq to array */  
  46.     //start=GetTickCount();  
  47.     //cvSeqSort( features, (CvCmpFunc)feature_cmp, NULL ); //?????  
  48.     n = features->total;  
  49.     *feat = (feature*)(calloc( n, sizeof(struct feature) ));  
  50.     *feat = (feature*)(cvCvtSeqToArray( features, *feat, CV_WHOLE_SEQ )); //整條鏈表放在feat指向的內(nèi)存  
  51.   
  52.     for( i = 0; i < n; i++ )  
  53.     {  
  54.         free( (*feat)[i].feature_data );  
  55.         (*feat)[i].feature_data = NULL;  //釋放ddata(r,c,octv,intvl,xi,scl_octv)  
  56.         if((*feat)[i].dense == 4) ++n4;  
  57.         else if((*feat)[i].dense == 3) ++n3;  
  58.         else if((*feat)[i].dense == 2) ++n2;  
  59.         else if((*feat)[i].dense == 1) ++n1;  
  60.         else                         ++n0;  
  61.     }  
  62.   
  63.     //fprintf( stderr, " move features from sequce to array use %d\n",GetTickCount()-start);  
  64.     //start=GetTickCount();  
  65.     fprintf( stderr, "In the total feature points the extent4 points is %d\n",n4);  
  66.     fprintf( stderr, "In the total feature points the extent3 points is %d\n",n3);  
  67.     fprintf( stderr, "In the total feature points the extent2 points is %d\n",n2);  
  68.     fprintf( stderr, "In the total feature points the extent1 points is %d\n",n1);  
  69.     fprintf( stderr, "In the total feature points the extent0 points is %d\n",n0);  
  70.     cvReleaseMemStorage( &storage );  
  71.     cvReleaseImage( &init_img );  
  72.     release_pyr( &gauss_pyr, octvs, intvls + 3 );  
  73.     release_pyr( &dog_pyr, octvs, intvls + 2 );  
  74.     //fprintf( stderr, " free the pyramid use %d\n",GetTickCount()-start);  
  75.     return n;  
  76. }  
    說明:上面的函數(shù)二,包含了SIFT算法中幾乎所有函數(shù),是SIFT算法的核心。本文不打算一一分析上面所有函數(shù),只會抽取其中涉及到BBF查詢機制相關的函數(shù)。

數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }