学习OpenCV——BOW特征提取函数(特征点篇)

来源:互联网 发布:js求数组中的最大值 编辑:程序博客网 时间:2024/05/16 09:14


简单的通过特征点分类的方法:                                                                      

一、train

1.提取+/- sample的feature,每幅图提取出的sift特征个数不定(假设每个feature有128维)

2.利用聚类方法(e.g K-means)将不定数量的feature聚类为固定数量的(比如10个)words即BOW(bag of word)

(本篇文章主要完成以上的工作!)

3.normalize,并作这10个类的直方图e.g [0.1,0.2,0.7,0...0];

4.将each image的这10个word作为feature_instance 和 (手工标记的) label(+/-)进入SVM训练



二、predict

1. 提取test_img的feature(如137个)

2. 分别求each feature与10个类的距离(e.g. 128维欧氏距离),确定该feature属于哪个类

3. normalize,并作这10个类的直方图e.g [0,0.2,0.2,0.6,0...0];

4. 应用SVM_predict进行结果预测



通过OpenCV实现feature聚类 BOW                                                             

首先在此介绍一下OpenCV的特征描述符与BOW的通用函数。

主要的通用接口有:


1.特征点提取

Ptr<FeatureDetector> FeatureDetector::create(const string& detectorType)

[cpp] view plaincopyprint?
  1.     Ptr<FeatureDetector> FeatureDetector::create(const string& detectorType)  
  2. //  "FAST" – FastFeatureDetector   
  3. //  "STAR" – StarFeatureDetector   
  4. //  "SIFT" – SIFT (nonfree module)//必须使用 initModule_nonfree()初始化  
  5. //  "SURF" – SURF (nonfree module)//同上;   
  6. //  "ORB" – ORB   
  7. //  "MSER" – MSER   
  8. //  "GFTT" – GoodFeaturesToTrackDetector   
  9. //  "HARRIS" – GoodFeaturesToTrackDetector with Harris detector enabled   
  10. //  "Dense" – DenseFeatureDetector   
  11. //  "SimpleBlob" – SimpleBlobDetector   

 

根据以上接口,测试不同的特征点:

对同一幅图像进行水平翻转前后的两幅图像检测特征点检测结果,

检测到的特征点的坐标类型为:pt: int / float(与keyPoint的性质有关)

数量分别为num1, num2,

 

 "FAST" – FastFeatureDetector           pt:int (num1:615  num2:618)
 "STAR" – StarFeatureDetector           pt:int (num1:43   num2:42 )
 "SIFT" – SIFT (nonfree module)          pt:float(num1:155  num2:135)            //必须使用 initModule_nonfree()初始化
 "SURF" – SURF (nonfree module)     pt:float(num1:344  num2:342)           //同上; 
 "ORB" – ORB                                        pt:float(num1:496  num2:497)
 "MSER" – MSER                                 pt:float(num1:51   num2:45 )
 "GFTT" – GoodFeaturesToTrackDetector        pt:int (num1:744  num2:771)
 "HARRIS" – GoodFeaturesToTrackDetector with Harris detector enabled         pt:float(num1:162  num2:160)
 "Dense" – DenseFeatureDetector          pt:int (num1:3350 num2:3350)

 


2.特征描述符提取

Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)

[cpp] view plaincopyprint?
  1. //  Ptr<DescriptorExtractor> DescriptorExtractor::create(const string& descriptorExtractorType)     
  2. //  "SIFT" – SIFT   
  3. //  "SURF" – SURF   
  4. //  "ORB" – ORB   
  5. //  "BRIEF" – BriefDescriptorExtractor   

 

3.描述符匹配

Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create(const string& descriptorMatcherType)

[cpp] view plaincopyprint?
  1. //  descriptorMatcherType – Descriptor matcher type.   
  2. //  Now the following matcher types are supported:   
  3. //      BruteForce (it uses L2 )   
  4. //      BruteForce-L1   
  5. //      BruteForce-Hamming   
  6. //      BruteForce-Hamming(2)   
  7. //      FlannBased   
  8.     Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create( "BruteForce" );  

 

4.class BOWTrainer

class BOWKmeansTrainer::public BOWTrainer:Kmeans算法训练

BOWKMeansTrainer ::BOWKmeansTrainer(int clusterCount, const TermCriteria& termcrit=TermCriteria(), int attempts=3, int flags=KMEANS_PP_CENTERS)

parameter same as Kmeans


代码实现:                                                                                                                    

1.画特征点。

2.特征点Kmeans聚类,每一种颜色代表一个类别。

 

[cpp] view plaincopyprint?
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/calib3d/calib3d.hpp"  
  3. #include "opencv2/imgproc/imgproc.hpp"  
  4. #include "opencv2/features2d/features2d.hpp"  
  5. #include "opencv2/nonfree/nonfree.hpp"  
  6.   
  7. #include <iostream>  
  8.   
  9. using namespace cv;  
  10. using namespace std;  
  11.   
  12. #define ClusterNum 10  
  13.   
  14. void DrawAndMatchKeypoints(const Mat& Img1,const Mat& Img2,const vector<KeyPoint>& Keypoints1,  
  15.     const vector<KeyPoint>& Keypoints2,const Mat& Descriptors1,const Mat& Descriptors2)  
  16. {  
  17.     Mat keyP1,keyP2;  
  18.     drawKeypoints(Img1,Keypoints1,keyP1,Scalar::all(-1),0);  
  19.     drawKeypoints(Img2,Keypoints2,keyP2,Scalar::all(-1),0);  
  20.     putText(keyP1, "drawKeyPoints", cvPoint(10,30), FONT_HERSHEY_SIMPLEX, 1 ,Scalar :: all(-1));  
  21.     putText(keyP2, "drawKeyPoints", cvPoint(10,30), FONT_HERSHEY_SIMPLEX, 1 ,Scalar :: all(-1));  
  22.     imshow("img1 keyPoints",keyP1);  
  23.     imshow("img2 keyPoints",keyP2);  
  24.   
  25.     Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create( "BruteForce" );  
  26.     vector<DMatch> matches;  
  27.     descriptorMatcher->match( Descriptors1, Descriptors2, matches );  
  28.     Mat show;  
  29.     drawMatches(Img1,Keypoints1,Img2,Keypoints2,matches,show,Scalar::all(-1),CV_RGB(255,255,255),Mat(),4);  
  30.     putText(show, "drawMatchKeyPoints", cvPoint(10,30), FONT_HERSHEY_SIMPLEX, 1 ,Scalar :: all(-1));    
  31.     imshow("match",show);  
  32. }  
  33.   
  34. //测试OpenCV:class BOWTrainer  
  35. void BOWKeams(const Mat& img, const vector<KeyPoint>& Keypoints,   
  36.     const Mat& Descriptors, Mat& centers)  
  37. {  
  38.     //BOW的kmeans算法聚类;  
  39.     BOWKMeansTrainer bowK(ClusterNum,   
  40.         cvTermCriteria (CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 0.1),3,2);  
  41.     centers = bowK.cluster(Descriptors);  
  42.     cout<<endl<<"< cluster num: "<<centers.rows<<" >"<<endl;  
  43.       
  44.     Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create( "BruteForce" );  
  45.     vector<DMatch> matches;  
  46.     descriptorMatcher->match(Descriptors,centers,matches);//const Mat& queryDescriptors, const Mat& trainDescriptors第一个参数是待分类节点,第二个参数是聚类中心;  
  47.     Mat demoCluster;  
  48.     img.copyTo(demoCluster);  
  49.       
  50.     //为每一类keyPoint定义一种颜色  
  51.     Scalar color[]={CV_RGB(255,255,255),  
  52.      CV_RGB(255,0,0),CV_RGB(0,255,0),CV_RGB(0,0,255),  
  53.      CV_RGB(255,255,0),CV_RGB(255,0,255),CV_RGB(0,255,255),  
  54.      CV_RGB(123,123,0),CV_RGB(0,123,123),CV_RGB(123,0,123)};  
  55.   
  56.   
  57.     for (vector<DMatch>::iterator iter=matches.begin();iter!=matches.end();iter++)  
  58.     {  
  59.         cout<<"< descriptorsIdx:"<<iter->queryIdx<<"  centersIdx:"<<iter->trainIdx  
  60.             <<" distincs:"<<iter->distance<<" >"<<endl;  
  61.         Point center= Keypoints[iter->queryIdx].pt;  
  62.         circle(demoCluster,center,2,color[iter->trainIdx],-1);  
  63.     }  
  64.     putText(demoCluster, "KeyPoints Clustering: 一种颜色代表一种类型",  
  65.         cvPoint(10,30), FONT_HERSHEY_SIMPLEX, 1 ,Scalar :: all(-1));  
  66.     imshow("KeyPoints Clusrtering",demoCluster);  
  67.       
  68. }  
  69.   
  70.   
  71.   
  72.   
  73. int main()  
  74. {  
  75.     cv::initModule_nonfree();//使用SIFT/SURF create之前,必须先initModule_<modulename>();   
  76.   
  77.     cout << "< Creating detector, descriptor extractor and descriptor matcher ...";  
  78.     Ptr<FeatureDetector> detector = FeatureDetector::create( "SIFT" );  
  79.   
  80.     Ptr<DescriptorExtractor> descriptorExtractor = DescriptorExtractor::create( "SIFT" );  
  81.   
  82.     Ptr<DescriptorMatcher> descriptorMatcher = DescriptorMatcher::create( "BruteForce" );  
  83.   
  84.   
  85.   
  86.     cout << ">" << endl;  
  87.   
  88.     if( detector.empty() || descriptorExtractor.empty() )  
  89.     {  
  90.         cout << "Can not create detector or descriptor exstractor or descriptor matcher of given types" << endl;  
  91.         return -1;  
  92.     }  
  93.     cout << endl << "< Reading images..." << endl;  
  94.     Mat img1 = imread("D:/demo0.jpg");  
  95.     Mat img2 = imread("D:/demo1.jpg");  
  96.     cout<<endl<<">"<<endl;  
  97.   
  98.   
  99.     //detect keypoints;  
  100.     cout << endl << "< Extracting keypoints from images..." << endl;  
  101.     vector<KeyPoint> keypoints1,keypoints2;  
  102.     detector->detect( img1, keypoints1 );  
  103.     detector->detect( img2, keypoints2 );  
  104.     cout <<"img1:"<< keypoints1.size() << " points  img2:" <<keypoints2.size()   
  105.         << " points" << endl << ">" << endl;  
  106.       
  107.     //compute descriptors for keypoints;  
  108.     cout << "< Computing descriptors for keypoints from images..." << endl;  
  109.     Mat descriptors1,descriptors2;  
  110.     descriptorExtractor->compute( img1, keypoints1, descriptors1 );  
  111.     descriptorExtractor->compute( img2, keypoints2, descriptors2 );  
  112.   
  113.     cout<<endl<<"< Descriptoers Size: "<<descriptors2.size()<<" >"<<endl;  
  114.     cout<<endl<<"descriptor's col: "<<descriptors2.cols<<endl  
  115.         <<"descriptor's row: "<<descriptors2.rows<<endl;  
  116.     cout << ">" << endl;  
  117.   
  118.     //Draw And Match img1,img2 keypoints  
  119.     //匹配的过程是对特征点的descriptors进行match;  
  120.     DrawAndMatchKeypoints(img1,img2,keypoints1,keypoints2,descriptors1,descriptors2);  
  121.   
  122.     Mat center;  
  123.     //对img1提取特征点,并聚类  
  124.     //测试OpenCV:class BOWTrainer  
  125.     BOWKeams(img1,keypoints1,descriptors1,center);  
  126.   
  127.   
  128.     waitKey();  
  129.   
  130. }  




通过Qt实现DrawKeypoints:

[cpp] view plaincopyprint?
  1. void Qt_test1::on_DrawKeypoints_clicked()  
  2. {  
  3.     //initModule_nonfree();  
  4.     Ptr<FeatureDetector> detector = FeatureDetector::create( "FAST" );  
  5.     vector<KeyPoint> keypoints;  
  6.     detector->detect( src, keypoints );  
  7.   
  8.     Mat DrawKeyP;  
  9.     drawKeypoints(src,keypoints,DrawKeyP,Scalar::all(-1),0);  
  10.     putText(DrawKeyP, "drawKeyPoints", cvPoint(10,30),   
  11.         FONT_HERSHEY_SIMPLEX, 0.5 ,Scalar :: all(255));  
  12.     cvtColor(DrawKeyP, image, CV_RGB2RGBA);  
  13.     QImage img = QImage((const unsigned char*)(image.data),   
  14.         image.cols, image.rows, QImage::Format_RGB32);  
  15.     QLabel *label = new QLabel(this);  
  16.     label->move(50, 50);//图像在窗口中所处的位置;  
  17.     label->setPixmap(QPixmap::fromImage(img));  
  18.     label->resize(label->pixmap()->size());      
  19.     label->show();  
  20. }  


由于initModule_nonfree()总是出错,无法对SIFT与SURF特征点提取,

而且无法实现聚类因为运行/BOW的kmeans算法聚类:BOWKMeansTrainer bowK(ClusterNum, cvTermCriteria (CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 0.1),3,2);总是出错,不知道咋解决~~~~~(>_<)~~~~ 需要继续学习

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我母亲怀孕了我的孩子小说 母亲满足了我的要求 子与母床上大战小说 穷山村的娘和儿子全文阅读 乱辈真实故事福林 为什么我没有朋友 妈毛又多又黑 脱掉母亲的白衬衫 漫画 母亲臀部抬起配合我 跟儿子洗澡没忍住做了一次 偷摸熟睡的母H 母亲只好认命抬起右腿 晚上故意到儿子房间睡 小说母亲的短裤衩 抱着母亲的腰疯狂地耸小说 姑妈穿裙子坐在我的腿的故事上 儿子18妈 妈38片国中 顶开高贵母亲的两辨 第章母亲抬腰迎合 母亲开始抗拒慢慢变迎合我口诉 母亲开始抗拒慢慢迎合我 第章顶开高贵母亲两瓣 母亲从抗拒慢慢变的迎合我 母亲疯狂迎合我txt小说下载 来吧儿子妈要你 影视片 儿子进来今晚妈让你做个够电影 儿子今晚妈让你做人个够知音网 离婚后和儿子睡觉 儿子让妈给你留个种吧 儿子妈要你的大吉吧 没开灯把小偷当老公 女儿怀孕我给姑爷解决问题 有给儿子口的吗 儿子你的真大 儿子想怎么弄就怎么弄吧 坏儿子还能在深点吗 睡着儿子顶了进来 儿子别急妈是你的小说 儿子今晚妈让你做人个够的视频 母亲和我做完跟父亲做在线阅读 高粱地里野坑头