欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

圖像檢索之基于vlfeat實(shí)現(xiàn)SIFT特征

 更新時(shí)間:2021年12月14日 15:16:04   作者:Brook_icv  
SIFT特征的講解已經(jīng)很多了,本文就借助vlfeat對(duì)SIFT特征的提取過(guò)程做一個(gè)總結(jié)。接下來(lái)通過(guò)本文給大家介紹圖像檢索之基于vlfeat實(shí)現(xiàn)SIFT,感興趣的朋友跟隨小編一起看看吧

概述

基于內(nèi)容的圖像檢索技術(shù)是采用某種算法來(lái)提取圖像中的特征,并將特征存儲(chǔ)起來(lái),組成圖像特征數(shù)據(jù)庫(kù)。當(dāng)需要檢索圖像時(shí),采用相同的特征提取技術(shù)提取出待檢索圖像的特征,并根據(jù)某種相似性準(zhǔn)則計(jì)算得到特征數(shù)據(jù)庫(kù)中圖像與待檢索圖像的相關(guān)度,最后通過(guò)由大到小排序,得到與待檢索圖像最相關(guān)的圖像,實(shí)現(xiàn)圖像檢索。圖像檢索的結(jié)果優(yōu)劣取決于圖像特征提取的好壞,在面對(duì)海量數(shù)據(jù)檢索環(huán)境中,我們還需要考慮到圖像比對(duì)(圖像相似性考量)的過(guò)程,采用高效的算法快速找到相似圖像也至關(guān)重要。

在構(gòu)建圖像特征庫(kù)的時(shí)候,通常不會(huì)使用原始的圖像特征,這是由于Raw Feature有很多冗余信息,而且維度過(guò)高在構(gòu)建特征數(shù)據(jù)庫(kù)和匹配的時(shí)候效率較低。所以,通常要對(duì)提取到的原始特征進(jìn)行重新編碼。比較常用的三種編碼方式:

  • BoF , Bog of Feature 源于文本處理的詞袋模型(Bog,Bag of Words)
  • VLAD , Vector of Aggragate Locally Descriptor
  • FV , fisher vector

構(gòu)建圖像特征數(shù)據(jù)庫(kù),通常有以下幾個(gè)步驟:

  • 圖像預(yù)處理流程(增強(qiáng),旋轉(zhuǎn),濾波,縮放等)
  • 特征提?。ㄈ痔卣?,局部特征:SIFT,SURF,CNN等)
  • 對(duì)每張圖片提取的原始特征重新編碼(BoF,VLAD,FV)形成圖像的特征庫(kù)

圖像的特征庫(kù)構(gòu)建完成后,在檢索階段,主要涉及到特征的相似性度量準(zhǔn)則,排序,搜索

  • 提取圖像的特征,
  • 特征編碼
  • 在圖像特征庫(kù)中進(jìn)行檢索
  • 返回相似性較高的結(jié)果

SIFT特征

SIFT特征的講解已經(jīng)很多了,之前的博客也有過(guò)介紹。本文就借助vlfeat對(duì)SIFT特征的提取過(guò)程做一個(gè)總結(jié)。
一個(gè)SIFT特征有兩部分組成:關(guān)鍵點(diǎn)(keypoint)和對(duì)應(yīng)特征描述子(Descriptor)。使用SIFT detector 進(jìn)行SIFT關(guān)鍵點(diǎn)的提取,然后使用SIFT descriptor計(jì)算關(guān)鍵點(diǎn)的描述子。也可以獨(dú)立的使用SIFT detector進(jìn)行SIFT 關(guān)鍵點(diǎn)的提取,或者使用SIFT descriptor進(jìn)行別的關(guān)鍵點(diǎn)描述子的計(jì)算。

一個(gè)SIFT keypoint是一塊圓形區(qū)域并且?guī)в蟹较?,使?個(gè)參數(shù)描述該區(qū)域的幾何結(jié)構(gòu):

  • keypoint的中心位置的坐標(biāo)(x,y)
  • keypoint的scale(圓形區(qū)域的半徑r)
  • keypoint的方向(使用弧度表示的角度θ)

一個(gè)SIFT關(guān)鍵點(diǎn)由4個(gè)參數(shù)確定:

  • 高斯尺度的組數(shù)o=log2min(m,n)?3=log2(512)?3=6
  • 構(gòu)建第0組,將原圖像進(jìn)行上采樣,寬和高增加一倍得到圖像I0。
  • 第0層I0?G(x,y,σ0)
  • 第1層I0?G(x,y,kσ0)
  • 第2層I0?G(x,y,k2σ0)
  • 構(gòu)建第1組,將I0進(jìn)行降采樣,得到圖像I1
  • 第0層I1?G(x,y,2σ0)
  • 第1層I1?G(x,y,2kσ0)
  • 第2層I1?G(x,y,2k2σ0)
  • ...
  • 構(gòu)建第o組,第s層 Io?G(x,y,2oksσ)

在Lowe的算法實(shí)現(xiàn)中\(zhòng)(\sigma_0 = 1.6,o_min = -1\)。\(o_min = -1\)表示金字塔的第0組是原圖像上采樣得到的,寬和高加一倍。

DoG 極值點(diǎn)檢測(cè)

高斯圖像金字塔構(gòu)建完成后,將同一組的相鄰兩層相減就得到了\(DoG\)金字塔。

每組的層數(shù)\(S = 3\),也就是說(shuō)每組可以得到兩層的\(DoG\)圖像,以第一組為例:其尺度為\(\sigma,k\sigma\),只有兩項(xiàng)是無(wú)法求取極值的,需要左右兩邊都有尺度。由于無(wú)法比較取得極值,那么我們就需要繼續(xù)對(duì)每組的圖像進(jìn)行高斯模糊,使得尺度形成\(\sigma,k\sigma,k^2\sigma,k^3\sigma,k^4\sigma\)這樣就可以選擇中間的三項(xiàng)\(k\sigma,k^2\sigma,k^3\sigma\)

檢測(cè)關(guān)鍵點(diǎn),就是在\(DoG\)的圖像空間中尋找極值點(diǎn),每個(gè)像素點(diǎn)要和其圖像域(同一尺度空間)和尺度域(相鄰的尺度空間)的所有相鄰點(diǎn)進(jìn)行比較,當(dāng)其大于(或者小于)所有相鄰點(diǎn)時(shí),改點(diǎn)就是極值點(diǎn)。如圖所示,中間的檢測(cè)點(diǎn)要和其所在圖像的\(3 \times 3\)鄰域8個(gè)像素點(diǎn),以及其相鄰的上下兩層的\(3\times 3\)領(lǐng)域18個(gè)像素點(diǎn),共26個(gè)像素點(diǎn)進(jìn)行比較。

刪除不好的極值點(diǎn)

刪除兩類極值點(diǎn)

  • 在對(duì)比度比較低低的區(qū)域檢測(cè)到的極值點(diǎn)
  • 在圖像的邊緣部分檢測(cè)到的極值點(diǎn)

確定關(guān)鍵點(diǎn)的方向

統(tǒng)計(jì)關(guān)鍵點(diǎn)鄰域像素的梯度方向分布來(lái)確定關(guān)鍵點(diǎn)的方向。具體步驟如下:

  • 計(jì)算以特征點(diǎn)為中心,以\(3 \times1.5 \sigma\)為半徑的區(qū)域圖像的幅角和幅值,每個(gè)像點(diǎn)\(L(x,y)\)的梯度的模\(m(x,y)\)以及方向\(\theta(x,y)\)可通過(guò)下面公式求得

  • 統(tǒng)計(jì)像素點(diǎn)的幅角和幅值的直方圖,梯度方向的直方圖的橫軸是梯度方向的角度(梯度方向的范圍是0到360度,直方圖每36度一個(gè)柱共10個(gè)柱,或者沒(méi)45度一個(gè)柱共8個(gè)柱),縱軸是梯度方向?qū)?yīng)梯度幅值的累加,在直方圖的峰值就是特征點(diǎn)的主方向。在梯度直方圖中,當(dāng)存在一個(gè)相當(dāng)于主峰值80%能量的柱值時(shí),則可以將這個(gè)方向認(rèn)為是該特征點(diǎn)輔助方向。所以,一個(gè)特征點(diǎn)可能檢測(cè)到多個(gè)方向(也可以理解為,一個(gè)特征點(diǎn)可能產(chǎn)生多個(gè)坐標(biāo)、尺度相同,但是方向不同的特征點(diǎn))。

得到特征點(diǎn)的主方向后,對(duì)于每個(gè)特征點(diǎn)可以得到三個(gè)信息\(k(x,y,r,\theta)\),即位置、尺度和方向。由此可以確定一個(gè)SIFT特征區(qū)域,一個(gè)SIFT特征區(qū)域由三個(gè)值表示,中心表示特征點(diǎn)位置,半徑表示關(guān)鍵點(diǎn)的尺度,箭頭表示主方向。
具有多個(gè)方向的關(guān)鍵點(diǎn)可以被復(fù)制成多份,然后將方向值分別賦給復(fù)制后的特征點(diǎn),一個(gè)特征點(diǎn)就產(chǎn)生了多個(gè)坐標(biāo)、尺度相等,但是方向不同的特征點(diǎn)。

計(jì)算關(guān)鍵點(diǎn)描述子

在檢測(cè)部分已經(jīng)得到了SIFT關(guān)鍵點(diǎn)的位置,尺度和方向信息,生成關(guān)鍵點(diǎn)的描述子,就是使用一個(gè)向量來(lái)描述關(guān)鍵點(diǎn)及其鄰域像素的信息。
由以下步驟生成描述子:

  • 為了保證旋轉(zhuǎn)不變性,將關(guān)鍵點(diǎn)為中心的鄰域像素的坐標(biāo)軸進(jìn)行旋轉(zhuǎn),將\(x\)軸旋轉(zhuǎn)至關(guān)鍵點(diǎn)主方向,如下圖:

  • 分塊計(jì)算鄰域內(nèi)像素的梯度方向直方圖,以關(guān)鍵點(diǎn)為中心的\(16\times16\)的區(qū)域內(nèi),劃分\(4\times4\)個(gè)塊,分別計(jì)算每個(gè)塊的梯度直方圖,如下圖:

每個(gè)塊的梯度直方方向直方圖的計(jì)算方式,和求關(guān)鍵點(diǎn)主方向時(shí)類似:此時(shí)每個(gè)區(qū)域的梯度直方圖在0-360之間劃分為8個(gè)方向區(qū)間,每個(gè)區(qū)間為45度,即每個(gè)種子點(diǎn)有8個(gè)方向的梯度強(qiáng)度信息,最后將得到的\(4\times4\times8=128\)維的特征向量。

  • 為了去除光照變化的影響,需對(duì)上述生成的特征向量進(jìn)行歸一化處理。在歸一化處理后,在128維的單位向量中,對(duì)大于0.2的要進(jìn)行截?cái)嗵幚?,即大?.2的值只取0.2,然后重新進(jìn)行一次歸一化處理,其目的是為了提高鑒別性。0.2 是實(shí)驗(yàn)得出的經(jīng)驗(yàn)值。

vlfeat實(shí)現(xiàn)的sift特征提取

vlfeat是一個(gè)開源的輕量級(jí)的計(jì)算機(jī)視覺(jué)庫(kù),主要實(shí)現(xiàn)圖像局部特征的提取和匹配以及一些常用的聚類算法。其對(duì)sift特征提取的各個(gè)步驟進(jìn)行了封裝,使用的方法如下:

1.調(diào)用vl_sift_new初始化VlSiftFilt,設(shè)置sift提取時(shí)參數(shù)信息,如:圖像的大小,Octave的個(gè)數(shù),每個(gè)Octave的中的層數(shù),起始的Octave的index. 各個(gè)參數(shù)的具體含義可以參考上面sift特征提取的方法。

2.設(shè)置剔除不穩(wěn)定關(guān)鍵點(diǎn)的閾值。在上面提到,sift在進(jìn)行極值檢查后,要剔除兩類不穩(wěn)定的極值點(diǎn):1.對(duì)比度較低區(qū)域的極值點(diǎn);2.邊緣部分的極值點(diǎn)。 可以調(diào)用

  • vl_sift_set_peak_thresh設(shè)置接受極值點(diǎn)是一個(gè)關(guān)鍵點(diǎn)的最小對(duì)比度。 該值越小,提取到的關(guān)鍵點(diǎn)就越多。
  • y vl_sift_set_edge_thresh()設(shè)置一個(gè)極值點(diǎn)是在邊緣上的閾值。 該值越小,提取到的關(guān)鍵點(diǎn)就越多。

這兩個(gè)參數(shù)對(duì)最終提取到的特征點(diǎn)個(gè)數(shù)有很大的影響。

3.初始化工作完成后,可以循環(huán)的對(duì)尺度空間的每個(gè)Octave進(jìn)行處理了

  • 調(diào)用 vl_sift_process_first_octave()vl_sift_process_next_octave()來(lái)計(jì)算下一個(gè)DoG尺度空間。
  • 調(diào)用vl_sift_detect進(jìn)行關(guān)鍵點(diǎn)提取
  • 對(duì)每一個(gè)提取到的關(guān)鍵點(diǎn)

vl_sift_calc_keypoint_orientations計(jì)算關(guān)鍵點(diǎn)的方向,可能多于一個(gè)

l_sift_calc_keypoint_descriptor計(jì)算每個(gè)方向的特征描述子。

4.vl_sift_delete釋放資源。

具體代碼如下:

// 初始化
    const string file = "../0.jpg";
    Mat img = imread(file,IMREAD_GRAYSCALE);
    Mat color_img = imread(file);
    Mat float_img;
    img.convertTo(float_img,CV_32F);

    int rows = img.rows;
    int cols = img.cols;
    VlSiftFilt* vl_sift =  vl_sift_new(cols,rows,4,3,0);
    vl_sift_set_peak_thresh(vl_sift,0.04);
    vl_sift_set_edge_thresh(vl_sift,10);

    vl_sift_pix *data = (vl_sift_pix*)(float_img.data);


    vector<VlSiftKeypoint> kpts;
    vector<float*> descriptors;

    vl_sift_extract(vl_sift,data,kpts,descriptors);
    
/*
    Extract sift using vlfeat
    parameters:
        vl_sfit, VlSiftFilt* 
        data , image pixel data ,to be convert to float
        kpts, keypoint list
        descriptors, descriptor. Need to free the memory after using.
*/
void vl_sift_extract(VlSiftFilt *vl_sift, vl_sift_pix* data,
                    vector<VlSiftKeypoint> &kpts,vector<float*> &descriptors) {
    
    // Detect keypoint and compute descriptor in each octave
    if(vl_sift_process_first_octave(vl_sift,data) != VL_ERR_EOF){
        while(true){
            vl_sift_detect(vl_sift);

            VlSiftKeypoint* pKpts = vl_sift->keys;
            for(int i = 0; i < vl_sift->nkeys; i ++) {

                double angles[4];
                // 計(jì)算特征點(diǎn)的方向,包括主方向和輔方向,最多4個(gè)
                int angleCount = vl_sift_calc_keypoint_orientations(vl_sift,angles,pKpts);

                // 對(duì)于方向多于一個(gè)的特征點(diǎn),每個(gè)方向分別計(jì)算特征描述符
                // 并且將特征點(diǎn)復(fù)制多個(gè)
                for(int i = 0 ; i < angleCount; i ++){
                    float *des = new float[128];
                    vl_sift_calc_keypoint_descriptor(vl_sift,des,pKpts,angles[0]);
                    descriptors.push_back(des);
                    kpts.push_back(*pKpts);
                }
                pKpts ++;
            }    
            // Process next octave
            if(vl_sift_process_next_octave(vl_sift) == VL_ERR_EOF) {
                break ;
            }
        }
    }
}

vlfeat中sift提取接受的是float類型的數(shù)據(jù),所以要先將讀到的數(shù)據(jù)圖像轉(zhuǎn)換為float
和OpenCV中的sift提取的對(duì)比結(jié)果如下:

  1. vlfeat提取的特征點(diǎn)是用綠色畫出來(lái)的,共有1961個(gè)特征點(diǎn)。
  2. OpenCV的是藍(lán)色,有4617個(gè)特征點(diǎn)。

Summary

幾年前寫過(guò)一篇關(guān)于SIFT的文章,SIFT特征詳解 當(dāng)時(shí)多是從理論上?,F(xiàn)在在做圖像檢索的時(shí)候,發(fā)現(xiàn)還是有很多東西理解的不是很清晰,比如:關(guān)鍵點(diǎn)的多個(gè)方向,不穩(wěn)定極值點(diǎn)的剔除以及梯度方向直方圖計(jì)算等等。

正在做一個(gè)圖像檢索的項(xiàng)目,陸續(xù)將項(xiàng)目的中學(xué)到一些知識(shí)總結(jié)下來(lái),下一篇是關(guān)于均值聚類的,對(duì)提取到的圖像特征進(jìn)行聚類生成視覺(jué)特征(Visul Feature)

到此這篇關(guān)于圖像檢索之基于vlfeat實(shí)現(xiàn)SIFT的文章就介紹到這了,更多相關(guān)圖像檢索vlfeat內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python中threading模塊的Lock和RLock區(qū)別詳解

    Python中threading模塊的Lock和RLock區(qū)別詳解

    這篇文章主要介紹了Python中threading模塊的Lock和RLock區(qū)別詳解,Lock鎖是Python的原始鎖,在鎖定時(shí)不屬于任何一個(gè)線程,在調(diào)用了 lock.acquire() 方法后,進(jìn)入鎖定狀態(tài),lock.release()方法可以解鎖,底層是通過(guò)一個(gè)函數(shù)來(lái)實(shí)現(xiàn)的,需要的朋友可以參考下
    2023-09-09
  • 使用numpy nonzero 找出非0元素

    使用numpy nonzero 找出非0元素

    這篇文章主要介紹了使用numpy nonzero 找出非0元素的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • python手寫均值濾波

    python手寫均值濾波

    這篇文章主要為大家詳細(xì)介紹了python手寫均值濾波的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • Python格式化輸出之format用法詳解

    Python格式化輸出之format用法詳解

    Python中格式化字符串目前有兩種陣營(yíng):%和format,這篇文章主要給大家介紹了關(guān)于Python格式化輸出之format用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-01-01
  • Python導(dǎo)入引用其他文件的函數(shù)實(shí)戰(zhàn)案例(推薦!)

    Python導(dǎo)入引用其他文件的函數(shù)實(shí)戰(zhàn)案例(推薦!)

    這篇文章主要給大家介紹了關(guān)于Python導(dǎo)入引用其他文件的函數(shù)的相關(guān)資料,文中通過(guò)代碼以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Python學(xué)習(xí)之yaml文件的讀取詳解

    Python學(xué)習(xí)之yaml文件的讀取詳解

    yaml其實(shí)也類似于 json、txt ,它們都屬于一種文本格式。在我們的實(shí)際工作中, yaml 文件經(jīng)常作為服務(wù)期配置文件來(lái)使用。本文將為大家介紹一些Python讀取yaml文件的方法,需要的可以參考一下
    2022-03-03
  • NumPy 矩陣乘法的實(shí)現(xiàn)示例

    NumPy 矩陣乘法的實(shí)現(xiàn)示例

    這篇文章主要介紹了NumPy 矩陣乘法的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • python 數(shù)據(jù)類(dataclass)的具體使用

    python 數(shù)據(jù)類(dataclass)的具體使用

    本文主要介紹了python 數(shù)據(jù)類(dataclass)的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 使用Python將圖片轉(zhuǎn)正方形的兩種方法實(shí)例代碼詳解

    使用Python將圖片轉(zhuǎn)正方形的兩種方法實(shí)例代碼詳解

    這篇文章主要介紹了使用Python將圖片轉(zhuǎn)正方形的兩種方法,本文通過(guò)實(shí)例代碼給大家給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • python __init__與 __new__的區(qū)別

    python __init__與 __new__的區(qū)別

    本文主要介紹了python __init__與 __new__的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02

最新評(píng)論