CBIR BoW概念和使用

2021-07-11 21:20:52 字數 1732 閱讀 4189

**:

以前自己看過關於cbir的一些知識,也就是相似的檢索。比如我的庫有n張,現在我拿出一張到n張中去檢索,目標是找到和當前最相似的(具備很多相同的特徵)。最近隨著幾個月每天加班的web專案完成後,又有時間回過頭來思考了一下這個問題。

在庫比較小的情況下,可以採取迴圈遍歷所有特徵,每乙個都和目標進行匹配,找出幾個匹配最好的。之前某個專案就採取了這樣的辦法。當時為了增大匹配速度,對於特徵點的特徵向量,建立了較為有效的索引機制,通過索引大約可以規避掉95%以上無效匹配。對於小的庫(小於幾百)這樣也就足夠了。

當庫進一步增大,就必須考慮更加具有效率的方式了。首先從opencv的標準函式入手,也就是bowkmeanstrainer。

首先學習一下bow的概念。對於任意影象來說。都是由多個特徵組成的。我們可以把組成它的這些特徵放到乙個bag裡面去。如上圖。也就是把一幅圖模擬為多個它所具備的特徵的集合。

現在假設我們有n張,我們從n張中提取所有的特徵出來,由於n張圖的特徵非常多,如果把n張圖的特徵都裝入乙個袋子裡面去。這個袋子就太大了,實際上它是乙個詞典。也就是說這個詞典包含了所有n張圖的特徵。

基於以上知識,然後再考慮一下如何查詢相似匹配的問題。如果每張圖都可以用乙個裝滿特徵的bag來表示,那麼比較兩幅圖的相似程度,可以直接比較這兩個bag的相似程度。

如上圖對於每乙個bag,我們根據它裝的是詞典裡面的哪些特徵詞,可以計算出它所包含的特徵分布圖。對於不同的bag,顯然特徵分布圖越接近,就代表兩個bag之間的相似程度越大。

在沒有使用bow之前,我們假設每張有300個特徵,比較兩幅圖的相似程度,實際上是用a圖的300特徵和b圖的300特徵比較。這麼大的數量造成了匹配的複雜程度非常高。如果基於bow,考慮一下只比較兩個bag的相似程度。每乙個bag用特徵分布的直方圖表示,在opencv中表示為乙個matrix,比較兩個matrix的相似度,只要一句話就解決了。這樣可以大大提高查詢的效率。

實際上基於這個bag,可以繼續使用svm等等進行訓練歸類等等。由於我的目標和這個稍微差距,所以就不討論這些問題了。

對於該系統的實現,第乙個部分是計算詞典。也就是全部圖的特徵集合。

dictionary=bowtrainer.cluster(featuresunclustered);
第二部分是計算每幅圖的特徵詞在詞典中的分布

cv::bowimgdescriptorextractor bowde(matcher);

bowde.compute(descriptors,bowdescriptor);

第三部分是比較兩幅圖的相似程度時,直接匹配:

for(int i = 0; i < m_samples.size(); i++)
最後匹配的score排序一下,選幾個最好的出來。

**部分參考:bag-of-features descriptor on sift features with opencv (bof-sift)

後記:bow的速度比起迴圈遍歷特徵還是強很多很多的。畢竟對於n張,只需要n次匹配再排序。不過我在實驗中發現對於實際中攝像頭拍到的有些圖存在錯誤率太高的問題(一定是開啟的方式不對)。對於如何提高成功率,如果有過這方面經驗的前輩們請多多指教。

Python模組概念和基本使用

python是由一系列的模組組成的,每個模組就是乙個py為字尾的檔案,同時模組也是乙個命名空間,從而避免了變數名稱衝突的問題。模組我們就可以理解為lib庫,如果需要使用某個模組中的函式或物件,則要匯入這個模組才可以使用,除了系統預設的模組不需要匯入外。匯入直接使用如下語法 import 模組名稱 不...

flume的概念和基本使用

flume是乙個分布式的 可靠的 可用的以及高效的對大量資料日誌進行收集 聚集 移動資訊的服務。flume是乙個可容錯的 健壯的並且非常簡單的流式資料框架,他只需要簡單配置source channel以及sink後,編寫一條命令就可實時採集資料。agent的三個組成部分為 source channe...

智慧型指標概念和使用

目錄結構 一 通過案例引入智慧型指標 二 智慧型指標的作用 三 設計輔助類實現智慧型指標作用 四 設計類模板實現智慧型指標作用 五 使用stl和boost提供的標準智慧型指標類模板處理問題 一 通過案例引入智慧型指標 有如下的程式 include using namespace std class ...