基于SIFT立体匹配

视觉(13)基于SIFT立体匹配的移动机器人自定位

主要思路如下:
1.找特征:
对上一帧拍摄的左右图像分别计算SIFT特征,保存为L1.key,R1.key。
对当前帧拍摄的左右图像分别计算SIFT特征,保存为L2.key,R2.key。
2.特征匹配:
匹配L1.key,R1.key,得到文件K1.match。
匹配L2.key,R2.key,得到文件K2.match。
匹配K1.match,K2.match,得到result.txt,这个文件每一行包含了这四张图像的同一个特征点。
3.计算位姿的相对变换

现在1,2已经写好程序(一个简陋的命令行程序),一般能得到几百个匹配的特征,但是里面有一些特征匹配是错误的。
下一步可以考虑在计算3时采用RANSAC消除掉错误匹配的影响。

转换为pgm文件
找特征点

>siftWin32.exe  0<L1.pgm 1>L1.key
Finding keypoints
2473 keypoints found.

>siftWin32.exe  0<R1.pgm 1>R1.key
Finding keypoints
2945 keypoints found.

>siftWin32.exe  0<L2.pgm 1>L2.key
Finding keypoints
2712 keypoints found.

>siftWin32.exe  0<R2.pgm 1>R2.key
Finding keypoints
3536 keypoints found.
匹配并显示(1)

>match -m1 L1.key R1.key k1.match
k1:2473,k2:2945
Found 928 matches.

>match -draw k1.match L1.pgm R1.pgm
klist:928
匹配并显示(1)

>match -m1 L2.key R2.key k2.match
k1:2712,k2:3536
Found 1032 matches.

>match -draw k2.match L2.pgm R2.pgm
klist:1032
匹配(2)

>match -m2 k1.match k2.match result.txt
k1:928,k2:1032
find 573 matches
转自:http://www.cnblogs.com/cutepig/archive/2007/07/18/822997.html
### SIFT算法在立体匹配中的应用及实现 SIFT(Scale-Invariant Feature Transform)是一种用于图像处理的特征检测和描述算法,具有尺度不变性和旋转不变性的特点[^1]。它能够有效提取图像的关键点并生成对应的描述符,在双目视觉中被广泛应用于立体匹配。 #### 特征点提取 SIFT算法的第一步是从输入图像中提取稳定的特征点。这些特征点通常位于图像的角点或其他显著区域,能够在不同的视角下保持稳定。具体来说,SIFT通过构建高斯金字塔来识别不同尺度下的关键点,并使用Hessian矩阵确定其位置和方向。 #### 描述符计算 对于每一个提取到的特征点,SIFT会为其生成一个独特的描述符向量。该描述符基于局部梯度直方图构建,可以捕捉特征点周围的纹理信息。由于这种描述方式对光照变化、几何变换等因素不敏感,因此非常适合用于立体匹配场景[^1]。 #### 特征点匹配 完成特征点及其描述符的获取之后,下一步就是寻找两幅图像之间的对应关系。这一步骤可以通过比较每一对候选特征点的距离来进行。常用的方法是最邻近距离比率测试(Nearest Neighbor Distance Ratio Test),即如果某个左视图上的特征点与右视图上最接近的一个点之间满足一定比例条件,则认为它们是一对匹配点。 以下是简化版的C++代码示例展示如何利用OpenCV库执行上述操作: ```cpp #include <opencv2/opencv.hpp> #include <vector> int main() { cv::Mat img_left = cv::imread("left_image.jpg", cv::IMREAD_GRAYSCALE); cv::Mat img_right = cv::imread("right_image.jpg", cv::IMREAD_GRAYSCALE); // 初始化SIFT对象 cv::Ptr<cv::SIFT> sift = cv::SIFT::create(); std::vector<cv::KeyPoint> keypoints_left, keypoints_right; cv::Mat descriptors_left, descriptors_right; // 提取特征点和描述子 sift->detectAndCompute(img_left, cv::noArray(), keypoints_left, descriptors_left); sift->detectAndCompute(img_right, cv::noArray(), keypoints_right, descriptors_right); // 创建BFMatcher对象 cv::BFMatcher matcher(cv::NORM_L2); // 进行KNN匹配 (k=2) std::vector<std::vector<cv::DMatch>> matches_knn; matcher.knnMatch(descriptors_left, descriptors_right, matches_knn, 2); // 应用最近邻居距离比检验筛选可靠匹配 const float ratio_thresh = 0.7f; // 阈值设定为0.7 std::vector<cv::DMatch> good_matches; for(auto& match : matches_knn){ if(match.size() >=2 && match[0].distance < ratio_thresh * match[1].distance ){ good_matches.push_back(match[0]); } } // 可选:绘制匹配结果 cv::Mat img_matches; cv::drawMatches(img_left, keypoints_left, img_right, keypoints_right, good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); cv::imshow("Good Matches", img_matches); cv::waitKey(0); return 0; } ``` 此程序片段演示了从加载图片到最终显示匹配结果的整体流程。注意实际项目可能还需要考虑更多细节如异常情况处理等[^1]。 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值