一起动手做第三讲
高大神博客原文https://www.cnblogs.com/gaoxiang12/p/4659805.html
第三讲介绍了怎样进行图像配准,主要分为四步:
第一步.特征点的提取,虽然各种特征点有所区别,不过这一步大致都为两个过 程:根据图像提取关键点(KeyPoint)和根据关键点计算描述子(descriptor);
这一步我使用到的是opencv3.3.0(ubuntu16),其中创建ORB关键点的方式有所不同,定义了detector和descriptor之后(这个与源代码一致),只用修改创建实体的过程即可,如下两行代码
https://docs.opencv.org/3.3.0/db/d95/classcv_1_1ORB.html(ORB关键点的创建函数说明)
detector =cv::ORB::create();
descriptor=cv::ORB::create();
第二步.根据描述子进行特征匹配,计算描述子距离的方法也有多种,相应的opencv中有函数库进行计算;
第三步.匹配好的特征点会有着下面这种结构
vector<cv::DMatch> matches;
cv::BFMatcher matcher;
matcher.match(desp1,desp2,matches);
根据这几行代码计算得到的DMatch结构的mattches的每一个元素都对应这来自两幅图像的两个特征点和一个描述这两个特征点匹配程度(distance)的成员变量distance,得到的matches可能会很多,经常会删除比最小距离大多少倍的匹配。
第四步.求解PnP。上一步中代码中用的临界点是10倍的最小距离,如果按照原文的4倍最小距离则会报如下错误
OpenCV Error: Assertion failed (npoints >= 4 && npoints == std::max(ipoints.checkVector(2, 5), ipoints.checkVector(2, 6))) in solvePnPRansac, file /tmp/binarydeb/ros-kinetic-opencv3-3.3.1/modules/calib3d/src/solvepnp.cpp, line 253
猜测原因是得到的匹配点太少了,good matches = 5,里面有重合的自由度,导致没有充足的constraints来求解PnP吧(只是猜测,换成更大的距离就不会出现这个错误,顺利得到R和T)