opencv 中关于BOW模型的实现以及相关的函数解释
2016-08-05 19:49
513 查看
这两天在做关于图像的局部特征提取的内容,使用工具是VS2013+OpenCV。通过看论文知道一般采用SIFT+BOW来进行实现。关于SIFT特征提取的介绍很多,一般都比较复杂难懂,尤其是对我这种数学不怎么好的人。看了几天还是很朦胧。OpenCV中有对图像SIFT特征提取的函数,下面给出提取的过程:
另外函数的头文件是:#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进行实现。
同时需要将提取到的SIFT特征描述添加到trainer中
所有图像的descriptor添加完成后,进行聚类得到dictionary,也就是聚类的中心。
接下来需要得到每幅图像直方图。过程如下
对每幅图像图像进行如下操作:
得到的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 )¶
祝各位身体健康,学习进步。今天看到CSDN大神雷霄骅去世的消息,十分悲痛!天妒英才啊!!所以大家在学习和工作的时候一定要注意休息,身体是革命的本钱啊!!!
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. |
---|
相关文章推荐
- opencv 中关于BOW模型的实现以及相关的函数解释
- 关于JVM中方法调用的相关指令,以及解析(Resolution)和分派(Dispatch)的解释——重载的实现原理与重写的实现原理
- 关于轮廓的遍历,如何解释cvDrawContours函数及相关的数据结构是如何实现轮廓遍历的
- opencv中关于直方图的相关函数
- 【人脸识别】关于识别识别的一些名词解释以及函数说明
- CvCreateImage函数说明以及一些OpenCv中函数的相关说明
- 南非前总统曼德拉关于“ubuntu”的解释以及ubuntu的相关精神
- 关于OPENCV的源代码资料以及相关链接
- 关于OpenCV中利用函数cvConvert实现图像数据类型转换(8U->16S)
- 【OpenCV学习】【一】关于图像叠加以及原理解释(结合MATLAB)
- 关于函数的多态,与继承,以及相关的名词
- 关于EXCEL相关类的一些函数解释
- 关于Oracle中split函数的实现以及函数递归的举例。
- Unity学习日常问题记录九-关于Lookat与模型坐标系的相关的问题以及父子物体的刚体
- 深入理解C++对象模型-成员函数的本质以及虚函数的实现(非虚继承)
- OpenCv 关于矩阵的相关计算函数
- 关于OPENCV的源代码资料以及相关链接
- opencv中关于直方图的相关函数
- 关于OPENCV的源代码资料以及相关链接
- 单向链表的Java实现,以及相关函数。