没日没夜的改论文生活终于要告一段落了,比起改论文,学OpenCV就是一件幸福的事情。OpenCV的发展越来越完善了,已经可以直接使用BOW函数来进行对象分类了。

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

一、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)

  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)

  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)

  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聚类,每一种颜色代表一个类别。

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

通过Qt实现DrawKeypoints:

  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. Mat DrawKeyP;
  8. drawKeypoints(src,keypoints,DrawKeyP,Scalar::all(-1),0);
  9. putText(DrawKeyP, "drawKeyPoints", cvPoint(10,30),
  10. FONT_HERSHEY_SIMPLEX, 0.5 ,Scalar :: all(255));
  11. cvtColor(DrawKeyP, image, CV_RGB2RGBA);
  12. QImage img = QImage((const unsigned char*)(image.data),
  13. image.cols, image.rows, QImage::Format_RGB32);
  14. QLabel *label = new QLabel(this);
  15. label->move(50, 50);//图像在窗口中所处的位置;
  16. label->setPixmap(QPixmap::fromImage(img));
  17. label->resize(label->pixmap()->size());
  18. label->show();
  19. }

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

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

from: http://blog.csdn.net/yangtrees/article/details/8456237

学习OpenCV——BOW特征提取函数(特征点篇)的更多相关文章

  1. 学习OpenCV——粒子滤波(网上两篇文章总结)

    粒子滤波的理论实在是太美妙了,用一组不同权重的随机状态来逼近复杂的概率密度函数.其再非线性.非高斯系统中具有优良的特性.opencv给出了一个实现,但是没有给出范例,学习过程中发现网络上也找不到.le ...

  2. OpenCV特征点检测——Surf(特征点篇)&flann

    学习OpenCV--Surf(特征点篇)&flann 分类: OpenCV特征篇计算机视觉 2012-04-20 21:55 19887人阅读评论(20)收藏举报 检测特征 Surf(Spee ...

  3. OpenCV计算机视觉学习(13)——图像特征点检测(Harris角点检测,sift算法)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 前言 ...

  4. opencv学习之显示图像-imshow函数

    序 上一篇opencv学习之读取图像-imread函数介绍完opencv读取图片函数imread,这次来介绍与它对应的图像显示函数imshow. imshow函数 imshow函数功能 imshow的 ...

  5. 【学习opencv第六篇】图像的反转操作

    考试终于完了,现在终于有时间可以继续学习这个了.写这篇博客主要是因为以前一直搞不清楚图像数据到底是怎么存储的,以及这个step到底是什么,后来查了一下才知道原来step就是数据行的长度.. #incl ...

  6. 【学习opencv第七篇】图像的阈值化

    图像阈值化的基本思想是,给定一个数组和一个阈值,然后根据数组中每个元素是低于还是高于阈值而进行一些处理. cvThreshold()函数如下: double cvThreshold( CvArr* s ...

  7. OpenCV 学习笔记03 findContours函数

    opencv-python   4.0.1 1 函数释义 词义:发现轮廓! 从二进制图像中查找轮廓(Finds contours in a binary image):轮廓是形状分析和物体检测和识别的 ...

  8. <学习opencv>opencv函数

    /*=========================================================================*/ // openCV中的函数 /*====== ...

  9. 【opencv学习笔记】SetImageROI函数设置ROI区域的作用及用法

    虽然先前知道ROI区域是感兴趣区域,但是真正看到调用了OpenCV的cvSetImageROI函数时,并不知道它的作用,所以还是单独写了一段代码对这个函数进行探究.   OpenCVchm文档中对cv ...

随机推荐

  1. HTML5_嵌套移动APP端的H5页面meta标签

    <meta charset="utf-8"> <meta content="width=device-width, initial-scale=1.0, ...

  2. win7 64位DCOM配置(关于导出excel 配置计算机组件服务)(转)

    http://blog.sina.com.cn/s/blog_9323b3a50101qrxm.html [解决方案1] 1:在服务器上安装office的Excel软件. 2:在"开始&qu ...

  3. GO语言练习:channel 工程实例

    1.工程代码 2.编译及运行 1.工程目录结构 $ tree cgss cgss ├── cgss.go └── src ├── cg │   ├── centerclient.go │   ├── ...

  4. 转自大楚网:微软SAPI:让你的软件能说会道

    [IT168专稿]“没声音,再好的戏也出不来.”这虽然是一句广告,但是也说出了一个道理,我们所开发的软件,特别是一些多媒体软件,要是能够发 出声音,能说会道,将为我们的软件增添不少光彩.同时,我们面临 ...

  5. java分享第一天(java环境及原理)

    1 JDK的安装目录中:环境变量中增加JAVA_HOME变量:JDK安装目录:在path中添加JDK的bin目录 2 java执行的顺序是: 1 用java编译器javac   XXX.java   ...

  6. jquery js javascript select 无限级 插件 优化foxidea版

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 关于 微软必应词典客户端(pc) 的案例分析

    第一部分 调研,评测 ●评测 bug one 在词典界面中搜完单词后,将鼠标移到英文例句上的单词时,会显示对应的中文翻译,而当移到短语时则不对应中文翻译. bug two 用orc强力取词,查询如上图 ...

  8. android中versionCode&versionName

    原文来自:http://blog.csdn.net/wh_19910525/article/details/8660416 ,略有修改 一.概述 Android的版本可以在androidmainfes ...

  9. CWnd与HWND的简单辨析

    今天在写一个小的网络应用,需要用到HWND类型的一个参数.而程序中有的“窗口操作句柄”只有一个CWnd类型的指针.这俩不都是“窗口句柄”么?而且反正都是地址直接转换使用如何?结果出现了调用失效的情况. ...

  10. intellij idea 插件 ideaVim

    像Eclipse一样,idea这个公认最好的javaIDE也有Vim插件. 安装方法 File>Settings>Plugins>Install JetBrains plugin.. ...