ORB特征点提取算法试验

前阵子推进毕设,通过各种教材、论文和博客的调研,总算对视觉SLAM有了一个比较宏观的了解,摘录归纳了许多特征提取和跟踪的算法,最后初步方案决定为对ORB-SLAM展开研究。

赶紧花时间去补习了一下C++,用了半天配置完了OpenCV3.4的环境,又用了近一整天时间快速翻完了毛星云的《OpenCV3编程入门》,跑了跑里面的例程,发现简直友好度爆炸。这每一章的内容,不管是图像滤波也好,图像分割也好,图像修复也好,哪怕是特征检测,都差不多是——输入图片>>运用对应的函数处理图片>>输出图片的过程。函数的具体原理基本不用搞懂,OpenCV全部集成好了,很容易就能跑个demo出来。

但是后面想要自己写代码,肯定要深入研究具体理论。这里先记录一份自己第一次跑出ORB特征点检测和匹配的成果。

下面是代码,主要来源:https://www.cnblogs.com/Jessica-jie/p/8622449.html。

#include
#include

#include
#include
#include

using namespace std;
using namespace cv;

int main()
{
	Mat img1 = imread("img01.jpg");
	Mat img2 = imread("img02.jpg");

	// 1. 初始化
	vector keypoints1, keypoints2;
	Mat descriptors1, descriptors2;
	Ptr orb = ORB::create();

	// 2. 提取特征点
	orb->detect(img1, keypoints1);
	orb->detect(img2, keypoints2);

	// 3. 计算特征描述符
	orb->compute(img1, keypoints1, descriptors1);
	orb->compute(img2, keypoints2, descriptors2);

	// 4. 对两幅图像的BRIEF描述符进行匹配,使用BFMatch,Hamming距离作为参考
	vector matches;
	BFMatcher bfMatcher(NORM_HAMMING);
	bfMatcher.match(descriptors1, descriptors2, matches);
	
	// 5. 展示
	Mat ShowMatches;
	drawMatches(img1, keypoints1, img2, keypoints2, matches, ShowMatches);
	imshow("matches", ShowMatches);

	waitKey(0);

	return 0;
}

下面是运行结果,采用暴力匹配:计算某一个特征点描述子与其他所有特征点描述子之间的距离,然后将得到的距离进行排序,取距离最近的一个作为匹配点。
ORB特征点提取算法试验_第1张图片
这个方法太简单粗暴了,可以采用一定原则去优化一下,比如:汉明距离小于最小距离的两倍。

在第四步后面添加如下代码:

// 匹配对筛选
double min_dist = 1000, max_dist = 0;
// 找出所有匹配之间的最大值和最小值
for (int i = 0; i < descriptors1.rows; i++)
{
    double dist = matches[i].distance;
    if (dist < min_dist) min_dist = dist;
    if (dist > max_dist) max_dist = dist;
}
// 当描述子之间的匹配不大于2倍的最小距离时,即认为该匹配是一个错误的匹配。
// 但有时描述子之间的最小距离非常小,可以设置一个经验值作为下限
vector good_matches;
for (int i = 0; i < descriptors1.rows; i++)
{
    if (matches[i].distance <= max(2 * min_dist, 30.0))
        good_matches.push_back(matches[i]);
}

然后把画出匹配的函数参数,改成筛选后的匹配(good_matches)。

drawMatches(img1, keypoints1, img2, keypoints2, good_matches, ShowMatches);

再次编译运行,发现结果好了很多:
ORB特征点提取算法试验_第2张图片

你可能感兴趣的:(视觉SLAM学习)