Structure From Motion 笔记

OpenMVG三维重建实践与优化策略
本文记录了使用OpenMVG库进行三维重建的过程,包括特征点提取、匹配、摄像机矩阵优化、MVS网格构建以及纹理映射。讨论了可能的改进方法,如特征点算法优化和RANSAC后的再提取。提到了相关工具如assimp库和3D模型查看器open3mod,以及MVE库的全面功能。

期末的大作业使用OpenMVG库进行三维重建,笔记如下:

整体过程:
1. 对多张图片提取特征点(SIFT SURF)
2. 匹配特征点,使用RANSAC算法消除干扰
3. 对于可匹配特征点使用矩阵优化求解库(ceres-solver Osi-Clp SoPlex GLPK)求解摄像机矩阵和位置矩阵(Fundamental Matrix & Essential Matrix),推算出每个摄像机位置和特征点位置

4.应用MVS(Multiple View Stereo-vision)库建立三维的网格Mesh,
PMVS稠密点云

5.将二维图片纹理映射至三维场景,如MVS推荐的FSSR(Floating Scale Surface Reconstruction)库或MVS-texturing
CMPMVS库(非开源

### 结构从运动(SfM)算法及其在计算机视觉中的应用 #### SfM 技术概述 结构从运动 (Structure from Motion, SfM) 是一种通过分析一系列图像来重建三维场景的技术。该方法利用多视角几何原理,能够从未校准的二维图像序列中恢复相机参数以及场景的三维结构[^1]。 #### 基本流程 SfM 的基本处理过程通常分为以下几个阶段: - **特征提取**:检测并描述每张图片的关键点,常用的有 SIFT 或者 ORB 特征。 - **匹配对应关系**:寻找不同视图间相同位置上的特征点配对,建立图像间的关联性。 - **初始估计**:基于两幅或多幅图像之间的特征点匹配结果计算基础矩阵或本质矩阵,并由此推导出相对姿态变换。 - **全局优化**:采用束调整法(Bundle Adjustment),最小化重投影误差以获得更精确的姿态和3D坐标。 - **密集重建**:扩展稀疏模型至稠密表面表示形式,比如使用光度一致性约束进行立体匹配或者多视角立体(MVS)。 #### 实现示例 下面给出一段简单的 Python 代码片段用于展示如何构建一个最简化版本的 SfM 流程: ```python import numpy as np from skimage import feature from scipy.spatial.distance import cdist from cv2 import findEssentialMat, recoverPose def extract_features(images): """ 提取图像特征 """ keypoints = [] descriptors = [] for img in images: kp, des = feature.sift.detectAndCompute(img, None) keypoints.append(kp) descriptors.append(des) return keypoints, descriptors def match_features(descs_1, descs_2): """ 匹配两个集合内的特征向量 """ distances = cdist(descs_1, descs_2, 'euclidean') matches_idx = np.argmin(distances, axis=1).reshape(-1, 1) return matches_idx def compute_pose(points1, points2, K): """ 计算摄像机位姿 """ E, _ = findEssentialMat(points1, points2, K) _, R, t, mask = recoverPose(E, points1, points2, K) return R, t, mask.flatten().astype(bool) if __name__ == "__main__": # 加载输入图像列表... # 定义内参矩阵K... kps, descs = extract_features([img1, img2]) matched_points = match_features(descs[0], descs[1]) pts1 = np.array([kps[0][i].pt for i in range(len(matched_points))])[matched_points[:, 0]] pts2 = np.array([kps[1][j].pt for j in range(len(matched_points))])[matched_points[:, 1]] rotation_matrix, translation_vector, valid_matches_mask = compute_pose(pts1, pts2, K) ``` 此段伪代码仅作为概念验证用途,在实际项目开发过程中还需要考虑更多细节问题如鲁棒性的提升、异常情况处理等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值