opencv 中關於BOW模型的實現以及相關的函數解釋

       這兩天在做關於圖像的局部特徵提取的內容,使用工具是VS2013+OpenCV。通過看論文知道一般採用SIFT+BOW來進行實現。關於SIFT特徵提取的介紹很多,一般都比較複雜難懂,尤其是對我這種數學不怎麼好的人。看了幾天還是很朦朧。OpenCV中有對圖像SIFT特徵提取的函數,下面給出提取的過程:

     image = imread(path);
	//sift關鍵點檢測
	SiftFeatureDetector detector;
	detector.detect(image, keyPoints);
	//sift關鍵點描述,角度,強度等
	SiftDescriptorExtractor extractor;
	extractor.compute(image, keyPoints, descriptor);

      另外函數的頭文件是:#include <opencv2/nonfree/features2d.hpp>,之前的版本是放在#include "opencv2/features2d/features2d.hpp"中的。還是多注意一下吧。

實現原理:

BOW模型的處理過程:

        1.SIFT特徵提取。SIFT 特徵提取是求出圖像的關鍵點信息,包括角度,大小以及強度。關鍵點,也就是能夠代表圖像關鍵信息的部分,這也是Bag of words中單詞的組成。一個圖像通常有很多的關鍵點。

        2.聚類。我們將每幅圖像中的關鍵點信息添加到詞袋中,並定義聚類中心的數量N。然後將詞袋中的關鍵點通過Kmeans算法聚類到N個類中。同時得到這N個類的中心點組成N*128的dictionary,每個中心都可以代表這個類。

        3.求圖像的直方圖。將圖像的關鍵點信息重新放到詞包中,根據落在每個類中關鍵點的數量來得到圖像的直方圖,大小爲1*N。將每幅圖像進行處理,得到圖像在BOW模型下的特徵。

        4.圖像匹配。將測試圖像進行相同的處理,同樣也得到1*N的特徵。根據測試圖像與訓練圖像特徵之間的距離,並將距離較小的圖像作爲檢索的結果。

實現過程:

          OpenCV中已經對步驟中的過程進行了封裝,我們只需要簡單的調用就可以。上面的代碼中我們已經完成了第一步。

          第二步和第三步BOW模型的實現,我們可以採用調用函數BOWKmeansTrainer進行實現。

       int clusterNum =260;
	//clusterNum代表有多少詞
	BOWKMeansTrainer trainer(clusterNum);

          同時需要將提取到的SIFT特徵描述添加到trainer中

      //descriptor是每幅圖像的sift關鍵點描述
        trainer.add(descriptor);

        所有圖像的descriptor添加完成後,進行聚類得到dictionary,也就是聚類的中心。

      Mat dictionary = trainer.cluster();

        接下來需要得到每幅圖像直方圖。過程如下

        Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create("SIFT");
	Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");
	BOWImgDescriptorExtractor bowDE(extractor, matcher);
	bowDE.setVocabulary(dictionary);

        對每幅圖像圖像進行如下操作:

                      Mat BOWdescriptor;
			//sift關鍵點檢測
			vector<KeyPoint> keyPoints;
			SiftFeatureDetector detector;
			detector.detect(curImg, keyPoints);
			//BOWdecriptor表示每個圖像的bow碼本,即直方圖,大小爲1*clusterNum
			bowDE.compute(curImg, keyPoints, BOWdescriptor);
			//歸一化
			normalize(BOWdescriptor, BOWdescriptor, 1.0, 0.0, NORM_MINMAX);

       得到的BOWdescriptor就是每個圖像的直方圖表示,可用做圖像檢索的特徵。最簡單的方法就是求測試圖像的直方圖與訓練圖像之間的歐明距離,得到檢索圖像。不過檢索的方式不一樣,效率和質量也不同。

過程中長的姿勢:

       剛開始寫的時候,不知道怎麼求圖像的碼本,就不停的翻看OpenCV中關於函數BOWImgDescriptorExtractor::compute的解釋,剛開始看的是中文解釋,看了很久也沒有看懂,後面找到了英文的註釋,頓時就明白了。看來還是要英語好啊!!!!下面給出英語版的,中文的就算了。。。

BOWImgDescriptorExtractor::compute

Computes an image descriptor using the set visual vocabulary.

C++: void BOWImgDescriptorExtractor::compute(const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor, vector<vector<int>>* pointIdxsOfClusters=0, Mat*descriptors=0 )
Parameters:
  • image – Image, for which the descriptor is computed.
  • keypoints – Keypoints detected in the input image.
  • imgDescriptor – Computed output image descriptor.
  • pointIdxsOfClusters – Indices of keypoints that belong to the cluster. This means that pointIdxsOfClusters[i] are keypoint indices that belong to the i -th cluster (word of vocabulary) returned if it is non-zero.
  • descriptors – Descriptors of the image keypoints that are returned if they are non-zero.

        祝各位身體健康,學習進步。今天看到CSDN大神雷霄驊去世的消息,十分悲痛!天妒英才啊!!所以大家在學習和工作的時候一定要注意休息,身體是革命的本錢啊!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章