本文共 3006 字,大约阅读时间需要 10 分钟。
作为一个视觉SLAM的入门学徒,我看完了高翔的书,学习了视频,也在自己的电脑上运行了一遍代码。但是感觉学习内容还是有些空洞,像是在走过场一样。于是,我决定真正从代码入手,尽管自己对编程基础较为薄弱。
特征点提取是整个程序的基础,通常作为一个封装好的函数来调用。所以我决定先从这个基础程序开始学习。
特征点提取的目的与步骤
特征点的提取目的是在每张图像中找到“区分度较高”的像素点,这里的“区分度较高”具体指的是FAST角点。FAST角点是一种在图像中能够有效地区分不同区域的点。
从代码注释来看,特征点提取的步骤基本上可以分为以下几个部分:
imread函数读取两张图像。keypoints_1和keypoints_2来存储两张图像中的特征点。代码解读与理解
接下来,我开始逐行分析代码。
#include#include #include #include using namespace std; using namespace cv;
这些是OpenCV的基本头文件包含,using namespace std; using namespace cv;使代码更简洁易读。
int main ( int argc, char** argv ){ if ( argc != 3 ) { cout << "usage: feature_extraction img1 img2" << endl; return 1; } 程序需要三个参数:两个图像文件名和一个输出窗口名。参数个数检查后,继续执行。
Mat img_1 = imread ( argv[1], CV_LOAD_IMAGE_COLOR );Mat img_2 = imread ( argv[2], CV_LOAD_IMAGE_COLOR );
使用imread函数读取两张图像,CV_LOAD_IMAGE_COLOR表示读取彩色图像。
vectorkeypoints_1, keypoints_2;Mat descriptors_1, descriptors_2;Ptr detector = ORB::create();Ptr descriptor = ORB::create();Ptr matcher = DescriptorMatcher::create ("BruteForce-Hamming");
定义了两个向量keypoints_1和keypoints_2,以及用于存储描述子的矩阵descriptors_1和descriptors_2。创建了ORB特征检测器和描述子提取器,以及匹配器。
detector->detect ( img_1, keypoints_1 );detector->detect ( img_2, keypoints_2 );
使用detect方法分别在两张图像中检测出FAST角点,并存储到keypoints_1和keypoints_2中。
descriptor->compute ( img_1, keypoints_1, descriptors_1 );descriptor->compute ( img_2, keypoints_2, descriptors_2 );
计算每个角点的BRIEF描述子,并存储到descriptors_1和descriptors_2中。
Mat outimg1;drawKeypoints( img_1, keypoints_1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );imshow("ORB特征点", outimg1); 绘制图像img_1中的特征点,并显示窗口。
vectormatches;matcher->match ( descriptors_1, descriptors_2, matches );
使用BFMatcher对描述子进行匹配,存储匹配结果。
double min_dist = 10000, max_dist = 0;for ( int i = 0; i < descriptors_1.rows; i++ ) { double dist = matches[i].distance; if ( dist < min_dist ) min_dist = dist; if ( dist > max_dist ) max_dist = dist;}printf ( "-- Max dist : %f \n", max_dist );printf ( "-- Min dist : %f \n", min_dist ); 计算特征点匹配的最小距离和最大距离,并输出结果。
std::vectorgood_matches;for ( int i = 0; i < descriptors_1.rows; i++ ) { if ( matches[i].distance <= max ( 2*min_dist, 30.0 ) ) { good_matches.push_back ( matches[i] ); }}
筛选匹配距离在一定范围内的点对,存储到good_matches中。
Mat img_match;drawMatches ( img_1, keypoints_1, img_2, keypoints_2, matches, img_match );imshow ( "所有匹配点对", img_match );imshow ( "优化后匹配点对", img_goodmatch );waitKey(0);return 0;
绘制所有匹配点对和优化后的匹配点对,并显示窗口。
代码运行与理解
通过上述代码,可以实现以下功能:
总结与展望
通过学习和分析上述代码,我对特征点提取有了更深入的理解。虽然代码基础较弱,但通过不断的学习和实践,相信自己能够逐步掌握视觉SLAM相关技术。
转载地址:http://xpaq.baihongyu.com/