前边1-10章不说,照着一路敲代码就可以,重点说一下11章
非常不幸地,类似surf,flann这类重要的特征匹配算法,Opencv开发者在Opencv3.0版本之后残忍地将它们从Opencv官方库移除了。
所以,我推荐那本书里,作者在这一部分,也就是第十一章,全部用的Opencv2.0代码。
对于一个间歇性强迫症患者来说,Opencv这问题赶上犯病的时候,是非常不幸的,因为钻牛角尖... 
闲话不说,花了一天时间解决这问题,现给出答案:
Opencv的surf, sift这些算法,在Opencv3.0版本后,全部从Opencv库中移除,归类于一个叫做Opencv_contrib的库里边,这个东西可以自行百度下载。
这个库有个问题,就是到目前为止,我用来看,只支持Opencv3.1版本而不支持3.0,所以,为了能够用上它,我们得把Opencv升到3.1.
整个过程自行百度,请。下载好的Opencv3.1最好找个空间大一点儿地方解压,因为整套库解压完毕可能会有15G左右的大小。
完成这个过程之后,下载cmake,用法百度,将Opencv3.1和opencv_contrib联合生成一个vs工程。
这里注意,1,cmake在一次配置之后(configrate),出现的红色列表里只用把OPENCV_EXTRA_MODULE这一项的值设置成opencv_contrib里边module文件夹路径就可以,剩下的东西不需要修改,比方说WITH_TBB(这个至少我没有引用,没有感觉出有什么不同),BUILD_OPENCV_WORLD之类,不要管它。
之后再进行一次或者几次配置,直到红色列表全部变成白色,点configrate旁边的生成(generate),(注意前边build目录最好单独设置,不要直接选择opencv3.1目录下的build目录),生成目录就会出现一个庞大的opencv工程,点集opencv.sln文件,进入工程。
如果前边,配置的时候,系统位数和vs版本没有错误,那么在这里vs可以非常顺利打开Opencv.sln文件,右击右边栏资源管理器里边项目名——>重新生成——>等待生成完毕——>右击cmaketarget里边,install项——>仅用于项目——>仅生成install,等待完成,然后关掉vs
ps:这里只给出来debug的过程,release模式跟debug相同,就不废话了。
重新开始新项目,之后无非就是修改系统Path路径,修改vs属性里边包含目录,库目录,依赖文件列表。重新注销系统,再进入,配置完成了!

上一段代码,可以测试
 

  /***********************************************************************************  

 

      *  @COPYRIGHT NOTICE  

 

      *  @Copyright (c) 2016, LiZichuan 

 

      *  @All rights reserved  

 

    

 

      文件名  : 1,SURF实验函数.cpp  

 
: ver 1.0  

 

    

 
: Zichuan  

 

      日期    : 2016/3/17 18:11  

 

      简介    : SURF实验函数  

 

  ***********************************************************************************/  

 
 
 
 

  /*****************************************************************************  

 
:头文件、命名空间包含部分 

 
: 

 

  *****************************************************************************/   

 

  #include "stdafx.h" 

 

  #include "stdio.h" 

 

  #include "opencv2/core.hpp" 

 

  #include "opencv2/core/utility.hpp" 

 

  #include "opencv2/core/ocl.hpp" 

 

  #include "opencv2/imgcodecs.hpp" 

 

  #include "opencv2/highgui.hpp" 

 

  #include "opencv2/features2d.hpp" 

 

  #include "opencv2/calib3d.hpp" 

 

  #include "opencv2/imgproc.hpp" 

 

  #include "opencv2/flann.hpp" 

 

  #include "opencv2/xfeatures2d.hpp" 

 

  #include "opencv2/ml.hpp" 

 

  #include "iostream" 

 
 
 
 

  using namespace cv; 

 

  using namespace std; 

 

  using namespace cv::xfeatures2d; 

 

  using namespace cv::ml; 

 
 
 
 
 
 
 

  /*****************************************************************************  

 
:main()函数 

 
: 

 
:Zichuan 

 
:2016/3/17 18:23  

 

  *****************************************************************************/   

 

  int _tmain(int argc, _TCHAR* argv[]) 

 

 
//小实验,检测OpenCV_contrib库是否好用 

 
//1,读取灰度图像 

 
Mat a = imread("素材1.jpg", IMREAD_GRAYSCALE); 

 
Mat b = imread("素材2.jpg", IMREAD_GRAYSCALE); 

 
 
 
 
//2,SURF算法匹配参数准备 

 
Ptr<SURF> surf; 

 
surf = SURF::create(800); 

 
 
 
 
BFMatcher matcher; 

 
Mat c, d; 

 
vector<KeyPoint> key1, key2; 

 
vector<DMatch> matches; 

 

       
 
 //3,特征检测 
  
surf->detectAndCompute(a, Mat(), key1, c); 

 
surf->detectAndCompute(b, Mat(), key2, d); 

 
 
 
 
//4,匹配 

 
matcher.match(c, d, matches); 

 
//筛选匹配点 

 
sort(matches.begin(), matches.end()); 

 
vector<DMatch> good_matches; 

 
int ptsPairs = min(50, (int)(matches.size() * 0.15)); 

 
cout << ptsPairs << endl; 

 
for (int i = 0; i < ptsPairs; i ++) 

 
{ 

 
good_matches.push_back(matches[i]); 

 
} 

 
Mat outimg; 
 

 //5,显示匹配结果  
drawMatches(a, key1, b, key2, good_matches, outimg, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 

 
 
 
 
std::vector<Point2f> obj; 

 
std::vector<Point2f> scene; 

 

 
for (size_t i = 0; i < good_matches.size(); i ++) 

 
{ 

 
obj.push_back(key1[good_matches[i].queryIdx].pt); 

 
scene.push_back(key2[good_matches[i].trainIdx].pt); 

 
} 

 
 
 
 
std::vector<Point2f> obj_corners(4); 

 
obj_corners[0] = Point(0, 0); 

 
obj_corners[1] = Point(a.cols, 0); 

 
obj_corners[2] = Point(a.cols, a.rows); 

 
obj_corners[3] = Point(0, a.rows); 

 
std::vector<Point2f> scene_corners(4); 

 
 
 
 
Mat H = findHomography(obj, scene, RANSAC); 

 
 
 
 
perspectiveTransform(obj_corners, scene_corners, H); 

 
 
 
 
line(outimg, scene_corners[0] + Point2f((float)a.cols, 0), scene_corners[1] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA); 

 
line(outimg, scene_corners[1] + Point2f((float)a.cols, 0), scene_corners[2] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA); 

 
line(outimg, scene_corners[2] + Point2f((float)a.cols, 0), scene_corners[3] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA); 

 
line(outimg, scene_corners[3] + Point2f((float)a.cols, 0), scene_corners[0] + Point2f((float)a.cols, 0), Scalar(0, 255, 0), 2, LINE_AA); 

 

 
imshow("匹配结果", outimg); 

 
 
 
 
waitKey(0); 

 
return 0; 

 
}


 附一个链接,讲得也很详细。