opencv 中關於BOW模型的實現以及相關的函式解釋
另外函式的標頭檔案是:#include <opencv2/nonfree/features2d.hpp>,之前的版本是放在#include "opencv2/features2d/features2d.hpp"中的。還是多注意一下吧。image = imread(path); //sift關鍵點檢測 SiftFeatureDetector detector; detector.detect(image, keyPoints); //sift關鍵點描述,角度,強度等 SiftDescriptorExtractor extractor; extractor.compute(image, keyPoints, descriptor);
實現原理:
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大神雷霄驊去世的訊息,十分悲痛!天妒英才啊!!所以大家在學習和工作的時候一定要注意休息,身體是革命的本錢啊!!!