什么网站做学校设计,长沙网站建设 鼎誉,怎么让百度搜到网站,网站建设与维护流程图在学习完鲁鹏老师的三维重建基础后#xff0c;打算用C代码复现一下增量SFM系统#xff08;https://github.com/ldx-star/SFM#xff09;。
本项目的最终目标就是通过相机拍摄的多视角视图获取三维点云。由于资金有效#xff0c;博主使用的是相机是小米12。
先来看一下最终…在学习完鲁鹏老师的三维重建基础后打算用C代码复现一下增量SFM系统https://github.com/ldx-star/SFM。
本项目的最终目标就是通过相机拍摄的多视角视图获取三维点云。由于资金有效博主使用的是相机是小米12。
先来看一下最终效果 当然了和开源系统比起来还是差很多的。
二、项目流程
整个项目大致可以分为三步
相机标定构建共视图重建
接下来将逐步介绍这三个流程以及其实现细节。
三、实现细节
手机相机的焦距一般是固定我们在使用手机拍照时说的调焦其实是算法调焦。为什么避免这个问题在用手机拍摄标定板时需要关闭手机的自动调焦。
以小米手机为例 我们直接使用opencv提供的方法进行标定如何想了解具体实现细节与源码可以参考博文 相机标定原理
我们项目的提供的标定图最终的重投影误差为0.25并且我们拍摄图片所使用的是同一个相机所以所有相机的初始内参全部一样。
2、构建共视图
共视图就是建立图与图间的特征匹配关系。
这部分使用的事opencv的SIFT特征匹配算法详细原理见博文 SIFT特征检测
在共视图中我们定义了以下结构
struct Edge{bool flag;std::vectorcv::DMatch matches;
};
struct Node{cv::Mat img;std::vectorcv::KeyPoint keyPoints; // 特征点cv::Mat descriptors; // 特征描述符std::vectorEdge edges; // 当前图与其他图的匹配关系std::vectorint trick_id;
};
class CommonView{std::vectorNode _graph;std::vectorcv::Mat _images;std::vectorstd::liststd::pairint,int _tracks;
}std::vectorcv::Mat _images:用于存放8副原始视图。
std::vectorNode _graph:用两个视图间的匹配关系构建一个图结构
std::vectorstd::liststd::pairint,int _tracks: 用于存放track 什么是track 如图所示 i m a g e k − 1 image_{k-1} imagek−1视图中的 P ( j , k − 1 ) P_{(j,k-1)} P(j,k−1) 与$ image_{k} 视图中的 视图中的 视图中的P_{(j,k)}$ 是一对儿匹配点 i m a g e k image_{k} imagek视图中的 P ( j , k ) P_{(j,k)} P(j,k) 与 i m a g e k 1 image_{k1} imagek1视图中的 P ( j , k 1 ) P_{(j,k1)} P(j,k1)是一对儿匹配点这三个点表示的是显示同一个三维点我们将这样的点集称为一个track由三个点组成的点集就称track的值为3。为了使重建结果稳定需要将track值小于2的匹配点去掉 。一个track对应一个三维点。 std::vectorstd::liststd::pairint,int:这个结构是什么意思
std::liststd::pairint,int:表示一个track的数据结构std::pairint,int:表示的某一个视图的二维坐标pair.first表示的是视图idpair.second表示的是特征点id。
Node结构体
std::vectorcv::KeyPoint keyPoints:用于存放特征点
cv::Mat descriptors:当前视图的特征描述符
std::vectorEdge edges:当前图与其他图的匹配关系例如 edges[2]就表示当前视图与视图2的匹配关系。
std::vectorint trick_id: trick_id.size()keyPoints.size()用于表示每个特征点属于哪一个track
Edge结构体
bool flag:用一个布尔值表示两幅视图是否可以用于重建初始值设为true在两个视图进行重建后将其设为false
std::vectorcv::DMatch:表示两视图的匹配关系
3、重建
选取可用匹配点最多的两个视图得到初始的重建结果初始重建结果至关重要会直接影响到整个重建效果 初始重建步骤 计算基础矩阵博文链接:对极几何 从基础矩阵中得到相机外参博文链接运动恢复结构 三角化得到初始三维点博文链接三角化 while(存在可以重建的视图) 从剩余视图中选取与已重建点交集最多的点通过ePnP求得相机外参博文链接ePnP三角化利用已重建的三维点进行捆绑调整最小化重投影误差(博文链接:捆绑调整)这部分我们是调用Ceres库 四、结果