计算机视觉之三维重建-SFM系统


北邮三维重建课笔记

1.PnP问题

在这里插入图片描述
PnP问题:就是利用其中两个相机算出三维点坐标,再利用三维点坐标和第三个相机的像平面坐标求出第三个相机的外参数。(这样计算的速度快一点。)
在这里插入图片描述
在这里插入图片描述
P3P求摄像机位姿。

2. RANSAC拟合

在这里插入图片描述

思路:1.随机抽取两个点算出直线方程
2.算出其余点到这个直线的距离
3.设置阈值,计算点到直线距离小于阈值的点个数
4.进行下一次迭代,回到1,最后看哪条直线周围的点最多(这里要考虑一个需要迭代多少次的问题。)
最后周围点最多的那条直线就是我们需要的直线。
在这里插入图片描述
在这里插入图片描述
迭代次数选择。(主要是求F矩阵用的)

3.本质矩阵与单应矩阵

在这里插入图片描述

4.sift特征提取

在这里插入图片描述

*2视图欧式结构恢复求解流程

在这里插入图片描述
1.使用sift特征提取,提取图像所有匹配点
2.随机均匀采样8对点求基础矩阵F,然后使用RANSAC判断其最好的F
3.求本质矩阵E,再分解出R,T再求出M2
4.最后算出三维点坐标

*openMVG系统

在这里插入图片描述
与SLAM系统一样,都是以第一个摄像机坐标系为世界坐标系,其余相机都是相对它的旋转、平移。
在这里插入图片描述
预处理工作:由于并不知道所拍摄的对象是否直接是平面,所以每次计算需要1)计算基础矩阵F 2)计算单应矩阵H
在这里插入图片描述

Tracks

在这里插入图片描述
图中绿线表示只在两个图像中有对应点,红线表示在三个图像中有对应点,每条线代表一个track,track中记录了这条线的信息(例如绿色类似(2,点的坐标),红色类似(3,点的坐标))OpenMVG中的计算会把绿色的track剔除掉。

联通图

在这里插入图片描述
如果两幅图像中的对应点的个数大于100就连接起来,连接起来的联通图称做G。联通图G的每一条连线称作e

计算流程

(这里的t和G都是可以用数据结构表示的,例如字典、数组)
1.计算对应点的轨迹(tracks) t
2.计算联通图G
3.从G中选取一条边e ==> G[0]、G[1]= e 0 、 e 1 、 . . . . e_0、e_1、.... e0e1....
4.利用e这条边所对应的两个图像估计本质矩阵E
5.分解E,得到这两张图所对应的位姿(外参数)
6.用e就能完成重建,但e只能看到局部,所以选择t∩e的点去重建
(举例:假设e只包含了两幅图100个对应点的信息,而track包含了3幅图,30个对应点的信息,我们只选择共有的30个对应点去重建)
7.删除G中的已重建的边e
8.如果G中还有边e:
1)选取一条满足track(e)∩{已重建3D点}最大的边e
(迭代选择e,这个e和track的交集要与已经重建的三维点交集最大)
2)利用PnP方法估计摄像机位姿(外参数)
(新选择的e中两幅图像中的对应点有部分已经重建,利用已经重建的对应点计算出新的相机位姿参数)
3)三角化新的tracks
(利用未重建的对应点重建出新的三维点)
4)删除G中的这条边
5)执行Bundle Adjustment
9.结束

  • 8
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SFM(Structure from Motion,运动结构恢复)是一种通过多张图像进行三维重建的技术,可以实现对现实场景的三维建模。Python中有许多强大的计算机视觉库可以用来实现SFM,比如OpenCV和Scikit-learn等。 基本流程如下: 1. 读取图像序列 2. 提取关键点和特征描述子 3. 匹配关键点和计算相机运动(相机位置和姿态) 4. 三角剖分重建三维点云 5. 优化相机参数和三维点云 以下是一个简单的Python实现示例: ``` python import cv2 import numpy as np # 读取图像序列 img1 = cv2.imread('img1.png') img2 = cv2.imread('img2.png') img3 = cv2.imread('img3.png') imgs = [img1, img2, img3] # 提取关键点和特征描述子 sift = cv2.xfeatures2d.SIFT_create() kp_list, des_list = [], [] for img in imgs: kp, des = sift.detectAndCompute(img, None) kp_list.append(kp) des_list.append(des) # 匹配关键点和计算相机运动 matches_list, M_list = [], [] matcher = cv2.BFMatcher() for i in range(len(imgs)-1): matches = matcher.knnMatch(des_list[i], des_list[i+1], k=2) good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) matches_list.append(good_matches) M, mask = cv2.findHomography(kp_list[i+1], kp_list[i], cv2.RANSAC, 5.0) M_list.append(M) # 三角剖分重建三维点云 points3D = [] for i, matches in enumerate(matches_list): src_pts = np.float32([kp_list[i+1][m.queryIdx].pt for m in matches]).reshape(-1,1,2) dst_pts = np.float32([kp_list[i][m.trainIdx].pt for m in matches]).reshape(-1,1,2) proj_mat1 = np.hstack((np.eye(3), np.zeros((3,1)))) proj_mat2 = np.hstack((M_list[i], np.zeros((3,1)))) points4D = cv2.triangulatePoints(proj_mat1, proj_mat2, src_pts, dst_pts) points4D /= points4D[3] points3D.append(points4D[:3].T) # 优化相机参数和三维点云 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) ret, K, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(points3D, kp_list, img1.shape[::-1], None, None) points3D_optimized = cv2.undistortPoints(np.array(points3D).reshape(-1,1,3), K, dist_coeffs).reshape(-1,3) # 输出结果 print(points3D_optimized) ``` 需要注意的是,这只是一个简单的实现示例,实际上SFM还有很多需要优化的地方。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值