三维重建中重投影

MVSNet为什么要进行重投影?

将参考图像通过深度估计和变换矩阵投影到每个源视图上,再和参考视图进行对比计算-----光度一致性损失
但是在重投影的过程中,可能会因为源图像对应像素被遮挡或者超出源图像边界导致某些像素重投影失败

将参考点云在源视角下进行投影,然后再回投到参考视角的过程
图解:
在这里插入图片描述

1. 输入输出

输入:

depth_ref:参考视角的深度图(源视角投影到参考视角之前的深度图)

intrinsics_ref:参考视角的相机内参

extrinsics_ref:参考视角的相机外参

depth_src:源视角的深度图

intrinsics_src:源视角的相机内参

extrinsics_src:源视角的相机外参

输出:

depth_reprojected:重映射的深度

x_reprojected, y_reprojected:重映射后的参考视角下的像素坐标

x_src, y_src:参考视角映射到源视角下的像素坐标

2. 过程

分两步:

step1.将参考视角的像素投影到源视角上得到源视角的点

​ 1/得到参考视角下各个像素的坐标x_ref, y_ref
​ 2/像素坐标->参考视角的三维点云坐标xyz_ref
​ 3/参考视角的三维点云坐标 映射 -> 源视角下的三维点云坐标xyz_src
​ 4/源视角下的三维点云坐标 -> 源视角下的三维像素坐标K_xyz_src
​ 源视角三维像素坐标 -> 源视角二维像素坐标xy_src

step2.使用源视角的深度估计(sampled_depth_src)来重新投影源视角的点,得到重投影后的参考视角的点

​ 1/找到上一步映射到源视角下的的像素坐标x_src,y_src
​ 2/将源视角下的深度图根据源视角像素坐标重新采样得到源视角下的深度估计 sampled_depth_src
​ 3/将源视角下的像素坐标 -> 源视角下的三维点云坐标xyz_src
​ 4/源视角下的三维点云坐标 重映射 ->参考视角下的点云坐标 xyz_reprojected
​ 5/参考视角下的点云坐标的第三维度 ->深度, 前两个维度-> 点云坐标
​ 【参考视角下】点云坐标 -> 像素坐标 -> 归一化x_reprojected, y_reprojected

3. code

def reproject_with_depth(depth_ref, intrinsics_ref, extrinsics_ref, depth_src, intrinsics_src, extrinsics_src):
    width, height = depth_ref.shape[1], depth_ref.shape[0] # 参考视角深度图的宽和高
    ## step1. project reference pixels to the source view 
    # 参考视角的x,y
    x_ref, y_ref = np.meshgrid(np.arange(0, width), np.arange(0, height)) # 二维矩阵
    x_ref, y_ref = x_ref.reshape([-1]), y_ref.reshape([-1]) # 压缩为一维
    
    # reference 3D space 参考视角的3D空间
    # 将(参考视角下的像素坐标和深度值)通过(相机内参的逆)转换为参考视角下的三维点云坐标(xyz_ref),xyz_ref是一个3行N列的矩阵,每一列对应一个像素的三维空间坐标(x, y, depth)。
    xyz_ref = np.matmul(np.linalg.inv(intrinsics_ref),
                        np.vstack((x_ref, y_ref, np.ones_like(x_ref))) * depth_ref.reshape([-1]))
    
    # source 3D space 源视角的3D空间
    # 将参考视角下的三维点云坐标(xyz_ref)映射到源视角下的坐标系,得到源视角下的三维点云坐标(xyz_src)
    xyz_src = np.matmul(np.matmul(extrinsics_src, np.linalg.inv(extrinsics_ref)),
                        np.vstack((xyz_ref, np.ones_like(x_ref))))[:3] 
    
    # source view x, y 源视角的x, y
    # 将源视角下的三维点云坐标xyz_src乘以源视角的相机内参intrinsics_src,得到在源视角下的像素坐标K_xyz_src(x, y, depth)
    K_xyz_src = np.matmul(intrinsics_src, xyz_src) # 源视角下的像素坐标
    xy_src = K_xyz_src[:2] / K_xyz_src[2:3] # 对源视角下的像素坐标前两维度/第三维度(深度)->源视角下的归一化的像素坐标(x/depth, y/depth, depth)

    ## step2. reproject the source view points with source view depth estimation
    # 取前两维得到源视角下的像素坐标
    x_src = xy_src[0].reshape([height, width]).astype(np.float32)
    y_src = xy_src[1].reshape([height, width]).astype(np.float32)
    # 将源视角下的深度图depth_src根据映射后的源视角下的像素坐标x_src和y_src进行重新采样,得到重采样后的深度图
    # 目的:为了使源视图深度值与新的目标像素位置对应起来
    sampled_depth_src = cv2.remap(depth_src, x_src, y_src, interpolation=cv2.INTER_LINEAR) 

    # source 3D space 源视角的3D空间
    # NOTE:这里使用采样得到的源视角深度【sampled_depth_src】来进行重投影
    # 将源视角下的像素坐标转化为源视角下的三维点云坐标
    xyz_src = np.matmul(np.linalg.inv(intrinsics_src),
                        np.vstack((xy_src, np.ones_like(x_ref))) * sampled_depth_src.reshape([-1]))
    
    # reference 3D space-参考视角的3D空间
    # 将源视角下的三维点云坐标重映射回参考视角,得到参考视角点云坐标
    xyz_reprojected = np.matmul(np.matmul(extrinsics_ref, np.linalg.inv(extrinsics_src)),
                                np.vstack((xyz_src, np.ones_like(x_ref))))[:3]
    
    # source view x, y, depth-源视角的 x, y, 深度
    depth_reprojected = xyz_reprojected[2].reshape([height, width]).astype(np.float32) # 将参考视角点云坐标的第三行提取出来得到重映射的深度
    # 将参考视角下的三维点云坐标乘以参考视角的相机内参,得到在参考视角下的像素坐标
    K_xyz_reprojected = np.matmul(intrinsics_ref, xyz_reprojected) # 重映射参考视角的像素坐标

    xy_reprojected = K_xyz_reprojected[:2] / K_xyz_reprojected[2:3] # 归一化处理,将前两个维度【像素坐标】除以第三个维度【深度】,xy_reprojected保存了在参考视角下归一化的像素坐标
    x_reprojected = xy_reprojected[0].reshape([height, width]).astype(np.float32)
    y_reprojected = xy_reprojected[1].reshape([height, width]).astype(np.float32)

    return depth_reprojected, x_reprojected, y_reprojected, x_src, y_src
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<项目介绍> 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到94.5分,放心下载使用! 该资源适合计算机相关专业(如人工智能、通信工程、自动化、软件工程等)的在校学生、老师或者企业员工下载,适合小白学习或者实际项目借鉴参考! 当然也可作为毕业设计、课程设计、课程作业、项目初期立项演示等。如果基础还行,可以在此代码基础之上做改动以实现更多功能。 双目测距理论及其python运用 一、双目测距基本流程 Stereo Vision, 也叫双目立体视觉,它的研究可以帮助我们更好的理解人类的双眼是如何进行深度感知的。双目视觉在许多领域得到了应用,例如城市三维重建3D模型构建(如kinect fusion)、视角合成、3D跟踪、机器人导航(自动驾驶)、人类运动捕捉(Microsoft Kinect)等等。双目测距也属于双目立体视觉的一个应用领域,双目测距的基本原理主要是三角测量原理,即通过视差来判定物体的远近。 那么总结起来,双目测距的大致流程就是: **双目标定 --> 立体校正(含消除畸变) --> 立体匹配 --> 视差计算 --> 深度计算(3D坐标)计算** linux下安装opencv-python: ```python pip install opencv-python ``` 二、相机畸变 光线经过相机的光学系统往往不能按照理想的情况投射到传感器上,也就是会产生所谓的畸变。畸变有两种情况:一种是由透镜形状引起的畸变称之为径向畸变。在针孔模型中,一条直线投影到像素平面上还是一条直线。可是,在实际拍摄的照片中,摄像机的透镜往往使得真实环境中的一条直线在图片中变成了曲线。越靠近图像的边缘,这种现象越明显。由于实际加工制作的透镜往往是中心对称的,这使得不规则的畸变通常径向对称。它们主要分为两大类,桶形畸变 和 枕形畸变(摘自《SLAM十四讲》)如图所示: <div align=center><img src="https://img-blog.csdnimg.cn/20190907184815326.PNG" width="324" height="100" /></div> 桶形畸变是由于图像放大率随着离光轴的距离增加而减小,而枕形畸变却恰好相反。 在这两种畸变中,穿过图像中心和光轴有交点的直线还能保持形状不变。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值