(19)深度点云学习--利用RGBD图三维重建room

news2025/1/19 8:26:35

1、主要参考

(1)最主要参考,官方的blog

Make fragments — Open3D 0.16.0 documentation

(2)操作流程参考

Python从RGBD数据进行3D场景重建 - 百度文库

(3)blog

Open3d利用彩色图和深度图生成点云进行室内三维重建_两车面包人的博客-CSDN博客_生成的点云没有颜色

(4)数据集来源

ICL-NUIM RGB-D Benchmark Dataset

2、使用open3d提供的官方例子重建三维

2.1进入如下目录

C:\Users\Administrator\AppData\Local\Programs\Python\Python39\Lib\site-packages\open3d\examples\reconstruction_system

2.2运行如下指令

python run_system.py --default_dataset lounge --make --register --refine --integrate
或者
python run_system.py --default_dataset bedroom --make --register --refine --integrate
或者
python run_system.py --default_dataset jack_jack --make --register --refine --integrate

(2)其中bedroom可以手动下载,地址

https://github.com/isl-org/open3d_downloads/releases/download/20220301-data/bedroom01.zip

---------------------------------------------

-------下面待优化

--------------------------------------------------------------------

3、其它详细操作--下载指定数据集

2.1 下载数据

 (1)网址

ICL-NUIM RGB-D Benchmark Dataset

(2)下载的位置

 (3)下载后解压文件

1)发现主要由2个文件夹构成

 2)总文件数996

3)RGB图的内容如下

 4)深度图的内容如下

 2.2相机参数

(1)网址

ICL-NUIM RGB-D Benchmark Dataset

(2)参数

481.20,0,319.50
0,-480.00,239.50
0,0,1

3、基于open3d的RGBD图三维重建

3.1到你安装的open3d的目录下

(1)到安装目录的examples\reconstruction_system文件下

我的是默认安装,位置如下:

C:\Users\Administrator\AppData\Local\Programs\Python\Python39\Lib\site-packages\open3d\examples\reconstruction_system

 

 3.2Make fragments(创建片段)

注意:(1)先按照3.2.1步骤修改好json文件

然后操作以下四步即可!!!:

python run_system.py --config config/tutorial_chen_iclnuim.json --make
python run_system.py --config config/tutorial_chen_iclnuim.json --register
python run_system.py --config config/tutorial_chen_iclnuim.json --refine
python run_system.py --config config/tutorial_chen_iclnuim.json --integrate

3.2.1操作

场景重建系统的第一步是从短RGBD序列中创建片段。

(1)输入参数

该脚本使用python run_system.py [config]——make运行。在[config]中,["path_dataset"]应该有image和depth子文件夹,分别存储彩色图像和深度图像。我们假设彩色图像和深度图像是同步和配准的。在[config]中,可选参数["path_intrinsic"]指定了存储相机固有矩阵的json文件的路径(详情请参阅Read camera intrinsic)。如果没有给出,则使用PrimeSense工厂设置。

(2)具体操作

复制修改config下面的tutorial.json为你的新的config

 (3)具体内容修改了数据集的路径

{
    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
    "path_dataset": "D:/RGBD_CAMERA/livingroom_dataset/living_room_traj1_frei_png",
    "path_intrinsic": "",
    "depth_max": 3.0,
    "voxel_size": 0.05,
    "depth_diff_max": 0.07,
    "preference_loop_closure_odometry": 0.1,
    "preference_loop_closure_registration": 5.0,
    "tsdf_cubic_size": 3.0,
    "icp_method": "color",
    "global_registration": "ransac",
    "python_multi_threading": true
}

 (4)运行如下命令

python run_system.py --config config/tutorial_chen_iclnuim.json ——make

3.2.2 涉及的主要函数

(1)Register RGBD image pairs

# examples/python/reconstruction_system/make_fragments.py

def register_one_rgbd_pair(s, t, color_files, depth_files, intrinsic,
                           with_opencv, config):
    source_rgbd_image = read_rgbd_image(color_files[s], depth_files[s], True,
                                        config)
    target_rgbd_image = read_rgbd_image(color_files[t], depth_files[t], True,
                                        config)

    option = o3d.pipelines.odometry.OdometryOption()
    option.depth_diff_max = config["depth_diff_max"]
    if abs(s - t) != 1:
        if with_opencv:
            success_5pt, odo_init = pose_estimation(source_rgbd_image,
                                                    target_rgbd_image,
                                                    intrinsic, False)
            if success_5pt:
                [success, trans, info
                ] = o3d.pipelines.odometry.compute_rgbd_odometry(
                    source_rgbd_image, target_rgbd_image, intrinsic, odo_init,
                    o3d.pipelines.odometry.RGBDOdometryJacobianFromHybridTerm(),
                    option)
                return [success, trans, info]
        return [False, np.identity(4), np.identity(6)]
    else:
        odo_init = np.identity(4)
        [success, trans, info] = o3d.pipelines.odometry.compute_rgbd_odometry(
            source_rgbd_image, target_rgbd_image, intrinsic, odo_init,
            o3d.pipelines.odometry.RGBDOdometryJacobianFromHybridTerm(), option)
        return [success, trans, info]

该函数读取一对RGBD图像,并将source_rgbd_image注册到target_rgbd_image。Open3D函数compute_rgbd_odometry被调用来对齐RGBD图像。对于相邻的RGBD图像,使用单位矩阵作为初始化。对于非相邻的RGBD图像,采用宽基线匹配作为初始化。特别地,函数pose_estimate计算OpenCV ORB特征来匹配宽基线图像上的稀疏特征,然后执行5点RANSAC来估计一个粗略的对齐,这被用作compute_rgbd_odometry的初始化。

(2)Multiway registration

# examples/python/reconstruction_system/make_fragments.py

def make_posegraph_for_fragment(path_dataset, sid, eid, color_files,
                                depth_files, fragment_id, n_fragments,
                                intrinsic, with_opencv, config):
    o3d.utility.set_verbosity_level(o3d.utility.VerbosityLevel.Error)
    pose_graph = o3d.pipelines.registration.PoseGraph()
    trans_odometry = np.identity(4)
    pose_graph.nodes.append(
        o3d.pipelines.registration.PoseGraphNode(trans_odometry))
    for s in range(sid, eid):
        for t in range(s + 1, eid):
            # odometry
            if t == s + 1:
                print(
                    "Fragment %03d / %03d :: RGBD matching between frame : %d and %d"
                    % (fragment_id, n_fragments - 1, s, t))
                [success, trans,
                 info] = register_one_rgbd_pair(s, t, color_files, depth_files,
                                                intrinsic, with_opencv, config)
                trans_odometry = np.dot(trans, trans_odometry)
                trans_odometry_inv = np.linalg.inv(trans_odometry)
                pose_graph.nodes.append(
                    o3d.pipelines.registration.PoseGraphNode(
                        trans_odometry_inv))
                pose_graph.edges.append(
                    o3d.pipelines.registration.PoseGraphEdge(s - sid,
                                                             t - sid,
                                                             trans,
                                                             info,
                                                             uncertain=False))

            # keyframe loop closure
            if s % config['n_keyframes_per_n_frame'] == 0 \
                    and t % config['n_keyframes_per_n_frame'] == 0:
                print(
                    "Fragment %03d / %03d :: RGBD matching between frame : %d and %d"
                    % (fragment_id, n_fragments - 1, s, t))
                [success, trans,
                 info] = register_one_rgbd_pair(s, t, color_files, depth_files,
                                                intrinsic, with_opencv, config)
                if success:
                    pose_graph.edges.append(
                        o3d.pipelines.registration.PoseGraphEdge(
                            s - sid, t - sid, trans, info, uncertain=True))
    o3d.io.write_pose_graph(
        join(path_dataset, config["template_fragment_posegraph"] % fragment_id),
        pose_graph)

 此脚本使用Multi way注册中演示的技术。函数make_posegraph_for_fragment构建了一个用于该序列中所有RGBD图像的多路配准的姿态图。每个图节点代表一个RGBD图像及其姿态,它将几何图形转换为全局片段空间。为了提高效率,只使用关键帧。

一旦创建了一个姿态图,通过调用函数optimize_posegraph_for_fragment来执行多路注册

(3) optimize_posegraph_for_fragment

# examples/python/reconstruction_system/optimize_posegraph.py

def optimize_posegraph_for_fragment(path_dataset, fragment_id, config):
    pose_graph_name = join(path_dataset,
                           config["template_fragment_posegraph"] % fragment_id)
    pose_graph_optimized_name = join(
        path_dataset,
        config["template_fragment_posegraph_optimized"] % fragment_id)
    run_posegraph_optimization(pose_graph_name, pose_graph_optimized_name,
            max_correspondence_distance = config["depth_diff_max"],
            preference_loop_closure = \
            config["preference_loop_closure_odometry"])

这个函数调用global_optimization来估计RGBD图像的姿态。

(4)Make a fragment

# examples/python/reconstruction_system/make_fragments.py

def integrate_rgb_frames_for_fragment(color_files, depth_files, fragment_id,
                                      n_fragments, pose_graph_name, intrinsic,
                                      config):
    pose_graph = o3d.io.read_pose_graph(pose_graph_name)
    volume = o3d.pipelines.integration.ScalableTSDFVolume(
        voxel_length=config["tsdf_cubic_size"] / 512.0,
        sdf_trunc=0.04,
        color_type=o3d.pipelines.integration.TSDFVolumeColorType.RGB8)
    for i in range(len(pose_graph.nodes)):
        i_abs = fragment_id * config['n_frames_per_fragment'] + i
        print(
            "Fragment %03d / %03d :: integrate rgbd frame %d (%d of %d)." %
            (fragment_id, n_fragments - 1, i_abs, i + 1, len(pose_graph.nodes)))
        rgbd = read_rgbd_image(color_files[i_abs], depth_files[i_abs], False,
                               config)
        pose = pose_graph.nodes[i].pose
        volume.integrate(rgbd, intrinsic, np.linalg.inv(pose))
    mesh = volume.extract_triangle_mesh()
    mesh.compute_vertex_normals()
    return mesh

 一旦姿态估计出来,使用RGBD集成从每个RGBD序列中重建一个彩色片段。

(5)Batch processing

# examples/python/reconstruction_system/make_fragments.py

def run(config):

    print("making fragments from RGBD sequence.")
    make_clean_folder(join(config["path_dataset"], config["folder_fragment"]))

    [color_files, depth_files] = get_rgbd_file_lists(config["path_dataset"])
    n_files = len(color_files)
    n_fragments = int(
        math.ceil(float(n_files) / config['n_frames_per_fragment']))

    if config["python_multi_threading"] is True:
        from joblib import Parallel, delayed
        import multiprocessing
        import subprocess
        MAX_THREAD = min(multiprocessing.cpu_count(), n_fragments)
        Parallel(n_jobs=MAX_THREAD)(delayed(process_single_fragment)(
            fragment_id, color_files, depth_files, n_files, n_fragments, config)
                                    for fragment_id in range(n_fragments))
    else:
        for fragment_id in range(n_fragments):
            process_single_fragment(fragment_id, color_files, depth_files,
                                    n_files, n_fragments, config)

 main函数调用上面解释的每个单独的函数。

(6)结果

 

 (7)以下是来自optimize_posegraph_for_fragment的日志

(8)以下是来自integrate_rgb_frames_for_fragment 的日志

3.3 Register fragments

一旦场景的片段(fragments)被创建,下一步就是在全局空间中对齐它们。

(1)主要操作方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/93255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新冠第6天,简单总结下

大家好,我是彭涛!今天是阳了个阳第6天,我已经完全康复了,没任何感觉了!因为前几天发了篇文章,我去,阳了个阳,打了一把高端局!很多人都知道我新冠阳性了,都来关…

如何做好疫情防控档案管理工作

近日,国内疫情虽整体可控,但各地区性突发疫情仍此起彼伏,防控攻坚战继续处于艰难的拉锯状态,那在疫情防控工作中的档案是如何收集、整理、形成的呢?什么是疫情防控档案?本文将带你走近疫情期间的档案&#…

cuda学习笔记1——cuda概述

cuda学习笔记1——cuda概述1. GPU架构特点2. CUDA线程模型3. CUDA内存模型4. CUDA编程模型第一个要掌握的编程要点:关键字第二个编程要点:数据传输参考: CUDA编程之快速入门 英伟达官方——CUDA C 编程指南 CUDA(Compute Unified…

vue2和vue3的环境搭建

1. node 安装 可以使用nvm 对node 的版本进行控制 # 查看版本 $ npm -v 2.3.0#升级 npm cnpm install npm -g# 升级或安装 cnpm npm install cnpm -g2.vue2环境安装# 安装最新vue稳定版 $ cnpm install vue 二种方式创建vue2项目 vue create vuepro1 //vue的方式创建项目v…

Git的安装,理论基础与基本使用

前言 本文为Git的安装,理论基础与基本使用相关知识,下边将对Git的安装与环境配置,Git相关理论基础(包含:Git 是什么,Git的三种状态,Git保证完整性),以及Git的相关操作&am…

form rules校验:动态table中input校验

问题描述 使用antd的form-model的rules表单校验 那如图表格中的input如何也一同校验? 如图可见规则是一个数据结构为二维数组的可动态生成的表格,如何对其中的input进行校验? 一维数组表格校验分析 先分析简单点的问题,表格是数…

Redis持久化RDB的三种触发机制及其优缺点

一、前言 大家都知道Redis是内存数据库,所有的数据都存放在内存中,如果没有配置持久化,当我们关闭redis服务器再重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,保证在redis重启…

全景也要更清晰,基于RK3588核心板的8K全景相机方案【飞凌嵌入式】

内容来源:飞凌嵌入式官网www.forlinx.com伴随着虚拟现实技术(简称VR)的热潮,VR全景影像开始兴起,全景相机市场也迎来了高速发展。近年来,360全景相机几乎成为了数码潮人和vlog拍摄者手中必不可少的一款产品…

Ghidra逆向工具之旅与二进制代码分析【3】

逆向工程中涉及到多种多样的工具(例如IDA Pro,Angr等),熟练使用这些工具可以化繁为简,使得程序分析工作得以顺利开展。本系列文章系统地介绍众多逆向工具中的一种——Ghidra,它是由美国国家安全局(NSA,National Security Agency)的研究理事会为 NSA 的网络安全任务开发…

手把手教你成为荣耀开发者:应用管理指南

荣耀开发者服务平台是荣耀面向开发者的统一生态入口,通过聚合周边内外部系统,分全球多站点部署,为全球开发者提供业务全生命周期的商业支撑服务,拥有应用分发、智慧服务、开放能力、HONOR Connect等众多业务等您来合作。 应用管理…

满足条件 -C++条件判断

引言 小森在玩MC(我的世界) 的时候,一般都玩生存,所以你们应该知道 :要想致富先 撸树,这个玩法 可是非常原始,但必须在平原或者森林里,若是一开始就在沙漠里可想而知,没有一点资源,怎么玩下去 ,当然走出去 要是下一个区域 里有树那很好, 没树继续.若在此之前发生了饱腹度一点一…

Linux中使用交叉编译、二进制分析工具链

交叉编译,顾名思义,就是要生成在其它平台上运行的目标代码。例如,现在个人电脑上的CPU都基于X86/X86-64架构。但很多手机或其它嵌入式设备的处理器则可能是基于ARM架构的。如果要在个人电脑上开发嵌入式应用,就要进行交叉编译。本文主要演示在Linux环境下使用交叉编译及二进…

Qt 模型视图编程之表头设置

背景 Qt 模型视图编程中模型定义了标准接口对数据进行访问,可根据需求继承对应的抽象模型类来实现自定义的数据模型。一个基本的数据模型至少要实现以下虚函数: ①.rowCount:行数,返回要显示多少行; ②&am…

Django 图书借书系统

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、Django是什么? 二、django安装 1.安装 2.需要的pip list 安装 三、django 建立图书馆管理系统 1.建立项目 建立项目locallibrary 2.参加APP 建…

[附源码]Python计算机毕业设计高校医疗健康服务系统的设计与实现Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

java计算机毕业设计基于安卓Android的婚恋相亲app

项目介绍 网络的广泛应用给生活带来了十分的便利。所以把网上婚恋相亲系统与现在网络相结合,利用java技术建设网上婚恋相亲系统APP,实现网上婚恋相亲系统的信息化。则对于进一步提高网上婚恋相亲系统发展,丰富网上婚恋相亲系统经验能起到不少的促进作用。 网上婚恋相亲系统APP能…

气泡水位计的安装方法与安装注意事项

气泡水位计它由活塞泵产生的压缩空气流经测量管和气泡室,进入被测的水体中,测量管中的静压力与气泡室上的水位高度成正比。那么接下来就请跟随小编的脚步一起来了解下气泡水位计的安装方法与安装注意事项的相关内容。 气泡式水位计的安装方法: 1.气管安装…

JDK的使用——Java开发第一步

JDK的使用——Java开发第一步 1 什么是JDK JDK是 Java 语言的软件开发工具包,是整个java开发的核心,使用Java开发第一步就是要在计算机上安装JDK。 JDK主要包含三个部分: 1 JAVA开发工具(jdk\bin) 2 基础开发库(jdk\jre\lib) 3 基础开发库…

Codeforces Round #762 (Div. 3) E. MEX and Increments

https://codeforces.com/contest/1619/problem/E 翻译: Dmitry有一个𝑛非负整数数组𝑎1,𝑎2,…,𝑎𝑛。 在一次操作中,Dmitry可以选择任意索引&#x1d457…

SAP ABAP——数据类型(六)【预定义基本数据类型详解】

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…