1. 程式人生 > >一篇給力的Bag-of-words模型入門介紹文章~

一篇給力的Bag-of-words模型入門介紹文章~

SIFT演算法的應用

-目標識別之用Bag-of-words模型表示一幅影象

出處:http://blog.csdn.net/assiduousknight/article/details/16901427

  • 引言

上述這4篇文章對SIFT演算法的原理和C語言實現都做了詳細介紹,用SIFT做影象匹配效果不錯。現在考慮更為高層的應用,將SIFT演算法應用於目標識別:發現影象中包含的物體類別,這是計算機視覺領域最基本也是最重要的任務之一。

且原經典演算法研究系列可能將改名為演算法珠璣--經典演算法的通俗演義。改名考慮到三點:1、不求面面俱到所有演算法,所以掏煉,謂之“珠璣”;2、突出本部落格內演算法內容的特色-通俗易懂、簡明直白,謂之“通俗”;3、側重經典演算法的研究與實現,以及實際應用,謂之“演義”。

下面我們來介紹有關SIFT演算法的目標識別的應用--Bag-of-words模型

  • Bag-of-words模型簡介

Bag-of-words模型是資訊檢索領域常用的文件表示方法。在資訊檢索中,BOW模型假定對於一個文件,忽略它的單詞順序和語法、句法等要素,將其僅僅看作是若干個詞彙的集合,文件中每個單詞的出現都是獨立的,不依賴於其它單詞是否出現。也就是說,文件中任意一個位置出現的任何單詞,都不受該文件語意影響而獨立選擇的。例如有如下兩個文件:

     1:Bob likes to play basketball, Jim likes too.

     2:Bob also likes to play football games.

基於這兩個文字文件,構造一個詞典:

     Dictionary = {1:”Bob, 2. like, 3. to, 4. play, 5. basketball, 6. also, 7. football, 8. games, 9. Jim, 10. too}

這個詞典一共包含10個不同的單詞,利用詞典的索引號,上面兩個文件每一個都可以用一個10維向量表示(用整數數字0~n(n為正整數)表示某個單詞在文件中出現的次數)

     1:[1, 2, 1, 1, 1, 0, 0, 0, 1, 1]

     2:[1, 1, 1, 1 ,0, 1, 1, 1, 0, 0]

向量中每個元素表示詞典中相關元素在文件中出現的次數(下文中,將用單詞的直方圖表示)。不過,在構造文件向量的過程中可以看到,我們並沒有表達單詞在原來句子中出現的次序(這是本Bag-of-words模型的缺點之一,不過瑕不掩瑜甚至在此處無關緊要)。

  • Bag-of-words模型的應用

Bag-of-words模型的適用場合

現在想象在一個巨大的文件集合D,裡面一共有M個文件,而文件裡面的所有單詞提取出來後,一起構成一個包含N個單詞的詞典,利用Bag-of-words模型,每個文件都可以被表示成為一個N維向量,計算機非常擅長於處理數值向量。這樣,就可以利用計算機來完成海量文件的分類過程。

考慮將Bag-of-words模型應用於影象表示。為了表示一幅影象,我們可以將影象看作文件,即若干個“視覺詞彙”的集合,同樣的,視覺詞彙相互之間沒有順序。

  圖1 將Bag-of-words模型應用於影象表示

由於影象中的詞彙不像文字文件中的那樣是現成的,我們需要首先從影象中提取出相互獨立的視覺詞彙,這通常需要經過三個步驟:(1)特徵檢測,(2)特徵表示,(3)單詞本的生成,請看下圖2:

圖2 從影象中提取出相互獨立的視覺詞彙

通過觀察會發現,同一類目標的不同例項之間雖然存在差異,但我們仍然可以找到它們之間的一些共同的地方,比如說人臉,雖然說不同人的臉差別比較大,但眼睛,嘴,鼻子等一些比較細小的部位,卻觀察不到太大差別,我們可以把這些不同例項之間共同的部位提取出來,作為識別這一類目標的視覺詞彙。

SIFT演算法是提取影象中區域性不變特徵的應用最廣泛的演算法,因此我們可以用SIFT演算法從影象中提取不變特徵點,作為視覺詞彙,並構造單詞表,用單詞表中的單詞表示一幅影象。

Bag-of-words模型應用三步

接下來,我們通過上述影象展示如何通過Bag-of-words模型,將影象表示成數值向量。現在有三個目標類,分別是人臉、自行車和吉他

Bag-of-words模型的第一步是利用SIFT演算法,從每類影象中提取視覺詞彙,將所有的視覺詞彙集合在一起,如下圖3所示:

 

                 圖從每類影象中提取視覺詞彙

第二步是利用K-Means演算法構造單詞表K-Means演算法是一種基於樣本間相似性度量的間接聚類方法,此演算法以K為引數,把N個物件分為K個簇,以使簇內具有較高的相似度,而簇間相似度較低。SIFT提取的視覺詞彙向量之間根據距離的遠近,可以利用K-Means演算法將詞義相近的詞彙合併,作為單詞表中的基礎詞彙,假定我們將K設為4,那麼單詞表的構造過程如下圖4所示:

                 圖利用K-Means演算法構造單詞表

第三步是利用單詞表的中詞彙表示影象。利用SIFT演算法,可以從每幅影象中提取很多個特徵點,這些特徵點都可以用單詞表中的單詞近似代替,通過統計單詞表中每個單詞在影象中出現的次數,可以將影象表示成為一個K=4維數值向量。請看下圖5:

                 圖5 每幅影象的直方圖表示 

上圖5中,我們從人臉、自行車和吉他三個目標類影象中提取出的不同視覺詞彙,而構造的詞彙表中,會把詞義相近的視覺詞彙合併為同一類,經過合併,詞彙表中只包含了四個視覺單詞,分別按索引值標記為1234。通過觀察可以看到,它們分別屬於自行車、人臉、吉他、人臉類。統計這些詞彙在不同目標類中出現的次數可以得到每幅影象的直方圖表示我們假定存在誤差,實際情況亦不外如此

人臉:  [3,30,3,20]
自行車:[20,3,3,2]
吉他:  [8,12,32,7]

其實這個過程非常簡單,就是針對人臉、自行車和吉他這三個文件,抽取出相似的部分(或者詞義相近的視覺詞彙合併為同一類),構造一個詞典,詞典中包含4個視覺單詞,即Dictionary = {1:”自行車”, 2. “人臉”, 3. “吉他”, 4. “人臉類},最終人臉、自行車和吉他三個文件皆可以用一個4維向量表示,最後根據三個文件相應部分出現的次數畫成了上面對應的直方圖

需要說明的是,以上過程只是針對三個目標類非常簡單的一個示例,實際應用中,為了達到較好的效果,單詞表中的詞彙數量K往往非常龐大,並且目標類數目越多,對應的K值也越大,一般情況下,K的取值在幾百到上千,在這裡取K4僅僅是為了方便說明。

下面,我們再來總結一下如何利用Bag-of-words模型將一幅影象表示成為數值向量:

  • 第一步:利用SIFT演算法從不同類別的影象中提取視覺詞彙向量,這些向量代表的是影象中區域性不變的特徵點;
  • 第二步:將所有特徵點向量集合到一塊,利用K-Means演算法合併詞義相近的視覺詞彙,構造一個包含K個詞彙的單詞表;
  • 第三步:統計單詞表中每個單詞在影象中出現的次數,從而將影象表示成為一個K維數值向量。

下面我們按照以上步驟,用C++一步步實現上述過程。 

  • C++逐步實現Bag-of-words模型表示一幅影象

在具體編碼之前,我們需要事先搭配開發環境。

一. 搭建開發環境

使用的開發平臺是windows xp sp3 + vs2010windows xp sp3 + 

2. 由於sift-latest_win.zip 要求的opencv版本是2.0以上,也下載最新版本 OpenCV-2.2.0-win32-vs2010.exe,執行安裝程式將opencv安裝在本地某路徑下。例如,我安裝在D盤根目錄下。

3. 執行vs2010,建立一個空的控制檯應用程式,取名bow。

4. 配置opencv環境。在vs2010下選擇project選單下的bow property子選單,調出bow property pages對話方塊,需要配置的地方有三處:在vc++ Directory選項裡需要配置Include DirectoriesLibrary Directories,在Linker選項卡的Input選項裡需要配置Additional Dependencies。

至此,開發環境全部搭建並配置完畢。

二.建立c++CSIFTDiscriptor

    為了方便使用,我們將SIFT庫用C++CSIFTDiscriptor封裝,該類可以計算並獲取指定影象的特徵點向量集合。類的聲名在SIFTDiscriptor.h檔案中,內容如下:

  1. #ifndef _SIFT_DISCRIPTOR_H_
  2. #define _SIFT_DISCRIPTOR_H_
  3. #include <string>
  4. #include <highgui.h>
  5. #include <cv.h>
  6. extern"C"
  7. {     
  8. #include "../sift/sift.h"   
  9. #include "../sift/imgfeatures.h"    
  10. #include "../sift/utils.h"  
  11. };  
  12. class CSIFTDiscriptor  
  13. {     
  14. public:   
  15.     int GetInterestPointNumber()          
  16.     {         
  17.         return m_nInterestPointNumber;    
  18.     }     
  19.     struct feature *GetFeatureArray()         
  20.     {         
  21.         return m_pFeatureArray;       
  22.     }  
  23.     public :          
  24.         void SetImgName(const std::string &strImgName)        
  25.         {         
  26.             m_strInputImgName = strImgName;       
  27.         }     
  28.         int CalculateSIFT();  
  29.     public:   
  30.         CSIFTDiscriptor(const std::string &strImgName);   
  31.         CSIFTDiscriptor()         
  32.         {         
  33.             m_nInterestPointNumber = 0;  
  34.             m_pFeatureArray = NULL;       
  35.         }     
  36.         ~CSIFTDiscriptor();  
  37.     private:          
  38.         std::string m_strInputImgName;    
  39.         int m_nInterestPointNumber;   
  40.         feature *m_pFeatureArray;     
  41. };  
  42. #endif

成員函式實現在SIFTDiscriptor.cpp檔案中,其中,CalculateSIFT函式完成特徵點的提取和計算,其主要內部流程如下:

1) 呼叫OpenCV函式cvLoadImage載入輸入影象;

2) 為了統一輸入影象的尺寸,CalculateSIFT函式的第二步是調整輸入影象的尺寸,這通過呼叫cvResize函式實現;

3) 如果輸入影象是彩色影象,我們需要首先將其轉化成灰度圖,這通過呼叫cvCvtColor函式實現;

4) 呼叫SIFT庫函式sift_feature獲取輸入影象的特徵點向量集合和特徵點個數。

  1. #include "SIFTDiscriptor.h"
  2. int CSIFTDiscriptor::CalculateSIFT()  
  3. {  
  4.     IplImage *pInputImg = cvLoadImage(m_strInputImgName.c_str());  
  5.     if (!pInputImg)  
  6.     {  
  7.         return -1;  
  8.     }  
  9.     int nImgWidth = 320;    //訓練用標準影象大小
  10.     double dbScaleFactor = pInputImg->width / 300.0;    //縮放因子
  11.     IplImage *pTmpImg = cvCreateImage(cvSize(pInputImg->width / dbScaleFactor, pInputImg->height / dbScaleFactor),  
  12.         pInputImg->depth, pInputImg->nChannels);  
  13.     cvResize(pInputImg, pTmpImg);    //縮放
  14.     cvReleaseImage(&pInputImg);  
  15.     if (pTmpImg->nChannels != 1)    //非灰度圖
  16.     {  
  17.         IplImage *pGrayImg = cvCreateImage(cvSize(pTmpImg->width, pTmpImg->height),  
  18.             pTmpImg->depth, 1);  
  19.         cvCvtColor(pTmpImg, pGrayImg, CV_RGB2GRAY);  
  20.         m_nInterestPointNumber = sift_features(pGrayImg, &m_pFeatureArray);  
  21.         cvReleaseImage(&pGrayImg);  
  22.     }  
  23. 相關推薦

    Bag-of-words模型入門介紹文章~

    SIFT演算法的應用 -目標識別之用Bag-of-words模型表示一幅影象 出處:http://blog.csdn.net/assiduousknight/article/details/16901427 引言

    Bag-of-words模型入門介紹文章

    引言  上述這4篇文章對SIFT演算法的原理和C語言實現都做了詳細介紹,用SIFT做影象匹配效果不錯。現在考慮更為高層的應用,將SIFT演算法應用於目標識別:發現影象中包含的物體類別,這是計算機視覺領域最基本也是最重要的任務之一。  且原經典演算法研究系列可能將

    通俗理解Bag-of-words模型入門

    總括 Bag-of-words模型是資訊檢索領域常用的文件表示方法。 在資訊檢索中,BOW模型假定對於一個文件,忽略它的單詞順序和語法、句法等要素,將其僅僅看作是若干個詞彙的集合,文件中每個單詞的出現都是獨立的,不依賴 於其它單詞是否出現。(是不關順序的)

    Bag of words模型

    視覺 ron 句法 mil soft ont words mage size 因為在使用SIFT特征作圖像分類時,一張圖像通常有很多keypoints,一個keypoints有一個128維的特征向量,而若直接將這些特征向量只做簡單的串聯就輸入分類器中,是不對的。我們需要一個

    Bag-of-words模型-可用於計算文字及圖片相似度

    引言上述這4篇文章對SIFT演算法的原理和C語言實現都做了詳細介紹,用SIFT做影象匹配效果不錯。現在考慮更為高層的應用,將SIFT演算法應用於目標識別:發現影象中包含的物體類別,這是計算機視覺領域最基本也是最重要的任務之一。且原經典演算法研究系列可能將改名為演算法珠璣--經

    個人感覺比較好的lua入門文章

    Lua是一個嵌入式的指令碼語言,它不僅可以單獨使用還能與其它語言混合呼叫。Lua與其它指令碼語言相比,其突出優勢在於: 1.  可擴充套件性。Lua的擴充套件性非常卓越,以至於很多人把Lua用作搭建領域語言的工具(注:比如遊戲指令碼)。Lua被設計為易於擴充套件的,可以通過Lua程式碼或者 C程式碼擴充套件

    機器學習---文本特征提取之詞袋模型(Machine Learning Text Feature Extraction Bag of Words

    from 就是 mat 關聯關系 關系 們的 維度 進行 class 假設有一段文本:"I have a cat, his name is Huzihu. Huzihu is really cute and friendly. We are good friends." 那

    Bow詞袋模型原理與例項(bag of words

    The bag-of-words model is a simplifying assumption used in natural language processing and information retrieval. In this model, a text (s

    自然語言處理之Bag-of-words,TF-IDF模型

    轉自:https://blog.csdn.net/m0_37744293/article/details/78881231 Bag-of-words,TF-IDF模型 Bag-of-words model (BoW model)忽略文字的語法和語序,用一組無序的單詞(words)來表達一段文

    迴環檢測中的詞袋模型bag of words

    將會從以下四個方面進行展開 關於詞袋模型的基本理解 演算法簡介 開原始碼庫DBoW2庫的簡單介紹 關於DBoW的一些總結 關於詞袋模型的基本理解 BoW基本簡介 Bag of words模型最初被用在文字分類中,將文件表示成特徵向量。它的基本思想是假定對於一個文字,

    Bag-of-words 詞袋模型基本原理

    Bag-of-words詞袋模型最初被用在資訊檢索領域,對於一篇文件來說,假定不考慮文件內的詞的順序關係和語法,只考慮該文件是否出現過這個單詞。假設有5類主題,我們的任務是來了一篇文件,判斷它屬於哪個主題。在訓練集中,我們有若干篇文件,它們的主題型別是已知的。我們從中選出一些

    BoW詞袋模型Bag of Words cpp實現(stable version 0.01)

    致謝:基礎框架來源BoW,開發版本在此基礎上進行,已在Ubuntu、OS X上測試通過,Windows需要支援c++11的編譯器(VS2012及其以上)。 使用 程式碼下載地址:bag-of-words-stable-version,這個是穩定版,上層目錄裡的開發

    詞袋模型Bag-of-words model)

    Bag-of-words model (BoW model) 最早出現在NLP和IR領域. 該模型忽略掉文字的語法和語序, 用一組無序的單詞(words)來表達一段文字或一個文件. 近年來, BoW模型被廣泛應用於計算機視覺中. 與應用於文字的BoW類比, 影象

    Bag of words model (詞袋模型)

       The bag-of-words model is a simplifying assumption used in natural language processing and information retrieval. In this model, a text

    視覺SLAM之詞袋(bag of words模型淺析

    第一步:利用SIFT演算法從不同類別的影象中提取視覺詞彙向量,這些向量代表的是影象中區域性不變的特徵點;第二步:將所有特徵點向量集合到一塊,利用K-Means演算法合併詞義相近的視覺詞彙,構造一個包含K個詞彙的單詞表;第三步:統計單詞表中每個單詞在影象中出現的次數,從而將影象表示成為一個K維數值向量。本文轉自

    Bag of Words(詞袋模型

    詞袋模型的提出是為了解決文件分類,主要應用在 NLP(Natural Language Process), IR(Information Retrival),CV(Computer Vision)等領域。本文以計算機視覺領域為例進行講解。 模型假設 一個

    基於BoW模型的場景識別 Scene recognition with bag of words

    An example of a typical bag of words classification pipeline. Figure by Chatfield et al. Brief Due date: October 30th, 11:59pmStar

    Bag of visual words(Bag of Words(BOW)模型)

    Original url: https://www.douban.com/note/310140053/ BOW (bag of words) 模型簡介Bag of words模型最初被用在文字分類中,將文件表示成特徵向量。它的基本思想是假定對於一個文字,忽略其詞序和語法、

    視覺SLAM之詞袋(bag of words模型與K-means聚類演算法淺析(1)

    第一步:利用SIFT演算法從不同類別的影象中提取視覺詞彙向量,這些向量代表的是影象中區域性不變的特徵點; 第二步:將所有特徵點向量集合到一塊,利用K-Means演算法合併詞義相近的視覺詞彙,構造一個包含K個詞彙的單詞表; 第三步:統計單詞表中每個單詞在影象中出現的次數,從而將影象表示成為一個K維數值向量。

    【機器學習 Opencv】Opencv之Bag of Word模型

          上圖是一張新圖對映到詞典時得到的直方圖,可以看出,這張圖片相對於圖2的情況而言,更接近類別1,所以通過分類器,理想的狀態時判斷為1。但是我們都知道,理想狀態出現的可能性太小,所以BOW難免會有出錯的時候,通過閱讀幾篇論文,發現BOW的識別率大概在60%-80%之間,當然了一方面是資料量巨大的問題