Depth maps转点云

news2024/9/23 5:23:32

前言
本文主要记录一下如何可视化相机位姿,如何用Blender得到的深度图反投影到3D空间,得到相应的点云。

Refernce

https://github.com/colmap/colmap/issues/1106
https://github.com/IntelRealSense/librealsense/issues/12090
https://medium.com/yodayoda/from-depth-map-to-point-cloud-7473721d3f
https://stackoverflow.com/questions/59590200/generate-point-cloud-from-depth-image
https://github.com/isl-org/Open3D/issues/481
https://stackoverflow.com/questions/31265245/extracting-3d-coordinates-given-2d-image-points-depth-map-and-camera-calibratio
https://github.com/vitalemonate/depth2Cloud

1 可视化相机位姿

import open3d as o3d
import numpy as np

focal = 346.4101498574051
img_w = img_h = 400.0
intrinsic = np.array([[focal, 0., -img_w / 2],
                      [0., -focal, -img_h / 2],
                      [0., 0., -1.]])
print(intrinsic)
pcds = []
# 创建相机线集并添加到列表中
for pose in poses:
#     extrinsic = pose
    extrinsic = np.eye(4)
    R, t = pose[:3, :3], pose[:3, 3]
    extrinsic[:3, :3] = R.T
    extrinsic[:3, 3] = -np.dot(R.T, t)
    print(extrinsic)
    cam_pcd = o3d.geometry.LineSet()
    cam_pcd = cam_pcd.create_camera_visualization(view_width_px=400,
                                                  view_height_px=400,
                                                  intrinsic=intrinsic,
                                                  extrinsic=extrinsic)
#     cam_pcd.paint_uniform_color(color)
#     cam_pcd.colors[4] = 0.5 * color
    cam_pcd.scale(scale=1., center=t)
    pcds.append(cam_pcd)

# 初始化Open3D的可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()

vis.add_geometry()

# 添加相机线集到可视化窗口
for cam_pcd in pcds:
    vis.add_geometry(cam_pcd)

# 设置视图参数
vis.get_render_option().background_color = [0.5, 0.5, 0.5]  # 设置背景颜色为灰色
vis.get_render_option().point_show_normal = True  # 显示法线

# 更新可视化窗口
# vis.update_geometry()

# 运行可视化窗口
while True:
    vis.poll_events()
    vis.update_renderer()
    

# 关闭可视化窗口
vis.destroy_window()

在这里插入图片描述

2 Depth2PointCloud

2.1 depth map反投影至三维空间

# 将depth map反投影至三维空间
def depth_image_to_point_cloud(rgb, depth, scale, K, pose):
    u = range(0, rgb.shape[1])
    v = range(0, rgb.shape[0])

    u, v = np.meshgrid(u, v)
    u = u.astype(float)
    v = v.astype(float)
    
    # K为内参矩阵3*3
    # 图片坐标转相机坐标
    Z = depth.astype(float) / scale
    X = (u - K[0, 2]) * Z / K[0, 0]
    Y = (v - K[1, 2]) * Z / K[1, 1]
    X = np.ravel(X)
    Y = -np.ravel(Y)   # Blender的坐标系为[x, -y, -z]
    Z = -np.ravel(Z)

    valid = Z < 0
    X = X[valid]
    Y = Y[valid]
    Z = Z[valid]
    position = np.vstack((X, Y, Z, np.ones(len(X))))
    
    # 相机坐标转世界坐标
    transform = np.array([[1, 0, 0, 0],
                          [0, -1, 0, 0],
                          [0, 0, -1, 0],
                          [0, 0, 0, 1]])
    pose = np.dot(transform, pose)
    position = np.dot(pose, position)
    
    R = np.ravel(rgb[:, :, 0])[valid]
    G = np.ravel(rgb[:, :, 1])[valid]
    B = np.ravel(rgb[:, :, 2])[valid]
    
    print(position.shape, R.shape)
    points = np.transpose(np.vstack((position[:3, :], R, G, B))).tolist()

    return points

2.2 将点云保存至ply文件

import os
import numpy as np
import cv2
from path import Path
from tqdm import tqdm

# 将点云写入ply文件
def write_point_cloud(ply_filename, points):
    formatted_points = []
    for point in points:
        formatted_points.append("%f %f %f %d %d %d 0\n" % (point[0], point[1], point[2], point[3], point[4], point[5]))

    out_file = open(ply_filename, "w")
    out_file.write('''ply
    format ascii 1.0
    element vertex %d
    property float x
    property float y
    property float z
    property uchar blue
    property uchar green
    property uchar red
    property uchar alpha
    end_header
    %s
    ''' % (len(points), "".join(formatted_points)))
    out_file.close()
    
    
# image_files: XXXXXX.png (RGB, 24-bit, PNG)
# depth_files: XXXXXX.png (16-bit, PNG)
# poses: camera-to-world, 4×4 matrix in homogeneous coordinates
def build_point_cloud(dataset_path, scale, view_ply_in_world_coordinate, poses):
    K = np.fromfile(os.path.join(dataset_path, "K.txt"), dtype=float, sep="\n ")
    K = np.reshape(K, newshape=(3, 3))
    print(K)
    print(poses)
    image_files = sorted(Path(os.path.join(dataset_path, "images")).files('*.png'))
    depth_files = sorted(Path(os.path.join(dataset_path, "depth_maps")).files('*.png'))
    sum_points_3D = []
    for i in tqdm(range(0, len(image_files))):
        image_file = image_files[i]
        depth_file = depth_files[i]

        rgb = cv2.imread(image_file)
        depth = cv2.imread(depth_file, -1).astype(np.uint16)

        if view_ply_in_world_coordinate:
            current_points_3D = depth_image_to_point_cloud(rgb, depth, scale=scale, K=K, pose=poses[i])
        else:
            current_points_3D = depth_image_to_point_cloud(rgb, depth, scale=scale, K=K, pose=poses[i])
#             print(len(current_points_3D), current_points_3D[0])
        save_ply_name = os.path.basename(os.path.splitext(image_files[i])[0]) + ".ply"
        save_ply_path = os.path.join(dataset_path, "point_clouds")

        if not os.path.exists(save_ply_path):  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.mkdir(save_ply_path)
        write_point_cloud(os.path.join(save_ply_path, save_ply_name), current_points_3D)
        sum_points_3D.extend(current_points_3D)
    write_point_cloud(os.path.join(save_ply_path, 'all.ply'), sum_points_3D)

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

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

相关文章

图灵奖简介及2023年获奖者Avi Wigderson的贡献

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 2023年的…

C语言基础入门案例(1)

目录 第一题&#xff1a;实现大衍数列的打印 第二题&#xff1a;生成所有由1、2、3、4组成的互不相同且无重复数字的三位数&#xff0c;并计算总数 第三题&#xff1a;整数加法计算器 第四题&#xff1a;实现一个范围累加和函数 第五题&#xff1a;编写一个函数计算整数的阶…

Webscoket简单demo介绍

前言 WebSocket 是从 HTML5 开始⽀持的⼀种⽹⻚端和服务端保持⻓连接的 消息推送机制. 理解消息推送: 传统的 web 程序, 都是属于 “⼀问⼀答” 的形式. 客⼾端给服务器发送了⼀个 HTTP 请求, 服务器给客 ⼾端返回⼀个 HTTP 响应.这种情况下, 服务器是属于被动的⼀⽅. 如果客⼾…

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测

分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测 目录 分类预测 | Matlab实现OOA-BP鱼鹰算法优化BP神经网络数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现OOA-BP鱼鹰算法优化BP神经网络多特征分类预测&#xff08;完整源码和数…

Win7开机进不了系统一直再自动修复,只能选禁用驱动签名才能进系统 其它模式都不行

环境&#xff1a; Win7专业版 问题描述&#xff1a; Win7开机进不了系统一直再修复&#xff0c;只能选禁用驱动签名才能进系统 其它模式都不行 解决方案&#xff1a; 1.开机按F8&#xff0c;选择禁用驱动签名进系统 2.查看系统日志文件定位错误原因 3.我这是DsArk64.sys导…

JS-32-jQuery01-jQuery的引入

一、初识jQuery jQuery是JavaScript世界中使用最广泛的一个库。鉴于它如此流行&#xff0c;又如此好用&#xff0c;所以每一个入门JavaScript的前端工程师都应该了解和学习它。 jQuery是一个优秀的JS函数库。 &#xff08;对BOM和DOM的封装&#xff09; jQuery这么流行&#x…

Flink设计运行原理 | 大数据技术

⭐简单说两句⭐ ✨ 正在努力的小新~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &…

计算机毕业设计springboot小区物业报修管理系统m8x57

该物业报修管理系统实施的目的在于帮助物业管理企业升级员工管理、住户管理、报修问题管理等内部管理平台&#xff0c;整合物业管理企业物力和人力&#xff0c;全面服务于维修人员管理的内部管理需求,并重视需求驱动、管理创新、与业主交流等外部需求,通过物业管理企业各项资源…

ArrayList部分底层源码分析

JDK版本为1.8.0_271&#xff0c;以插入和删除元素为例&#xff0c;部分源码如下&#xff1a; // 部分属性 transient Object[] elementData; // 底层数组 private int size; // 记录元素个数 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA {}; // 空Obje…

异地组网怎么安装?

异地组网安装是指在不同地域的多个设备之间建立网络连接&#xff0c;以便实现数据传输和协同工作的过程。在如今的数字化时代&#xff0c;异地组网安装已经成为了许多企业和组织所必需的一项技术。 天联的使用场景 在异地组网安装中&#xff0c;天联是一种常用的工具。它具有以…

得物 Zookeeper SLA 也可以 99.99% | 得物技术

一、背景 ZooKeeper&#xff08;ZK&#xff09;是一个诞生于2007年的分布式应用程序协调服务。尽管出于一些特殊的历史原因&#xff0c;许多业务场景仍然不得不依赖它。比如&#xff0c;Kafka、任务调度等。特别是在 Flink 混合部署 ETCD 解耦 时&#xff0c;业务方曾要求绝对…

网络与系统攻防技术实验及实验报告

1.实验内容 正确使用msf编码器&#xff0c;veil-evasion&#xff0c;自己利用shellcode编程等免杀工具或技巧 正确使用msf编码器&#xff0c;使用msfvenom生成如jar之类的其他文件veil&#xff0c;加壳工具使用C shellcode编程 通过组合应用各种技术实现恶意代码免杀 如果成功…

多目标跟踪 | 基于anchor-free目标检测+ReID的实时一阶多类多目标跟踪算法实现

项目应用场景 面向多目标检测跟踪场景&#xff0c;项目采用 anchor-free 目标检测ReID 的实时一阶段多类多目标跟踪算法实现&#xff0c;效果嘎嘎好。 项目效果 项目细节 > 具体参见项目 README.md (1) 类别支持 1~10 object classes are what we need non-interest-…

智能热流体仿真软件AICFD 2024R1新版本功能介绍

AICFD是由天洑软件自主研发的一款通用的智能热流体仿真软件。软件引入AI技术&#xff0c;具备智能问答、智能加速、智能预测等特色功能&#xff0c;解决用户在传统CFD软件中遇到的“网格划分繁、求解设置难、仿真计算慢”等痛点&#xff0c;使设计师和工程师可以专注于业务本身…

AI大模型语言开源大语言模型完整列表

开源大语言模型完整列表 Large Language Model (LLM) 即大规模语言模型&#xff0c;是一种基于深度学习的自然语言处理模型&#xff0c;它能够学习到自然语言的语法和语义&#xff0c;从而可以生成人类可读的文本。 所谓"语言模型"&#xff0c;就是只用来处理语言文…

WP免费主题下载

免费wordpress模板下载 高端大气上档次的免费wordpress主题&#xff0c;首页大图全屏显示经典风格的wordpress主题。 https://www.wpniu.com/themes/289.html 免费WP主题 蓝色简洁实用的wordpress免费主题模板&#xff0c;免费主题资源分享给大家。 https://www.wpniu.com/…

如何查找overlayfs对应的POD如何根据pod找到containerd id

如何查找overlayfs对应的POD mount |grep overlayfs | grep 1738 ctr -n k8s.io c list | grep 11ac4083419be11174746b68d018a0a402d9ae43c6b52125810fe1ec7db63bc6 查找目录并统计大小 find / -name "jfsCache" -exec du -sh {} | sort -rh如何根据pod找到c…

配置IP地址并验证连通性

1.实验环境 主机 A和主机 B通过一根网线相连&#xff0c;如图6.13所示。 图6.13 实验案例一示意图 2.需求描述 为两台主机配置!P地址&#xff0c;验证P地址是否生效&#xff1b;验证同一网段的两台主机可以互通&#xff0c;不同网段的主机不能直接互通。 3.推荐步骤 为两台…

笔记软件功能多样的是哪款?做笔记的软件哪个好用

在快节奏的现代生活中&#xff0c;笔记软件已成为我们提高工作效率、记录生活点滴的重要工具。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速记录下关键信息&#xff0c;或在灵感迸发时及时捕捉&#xff0c;这是多么方便高效。 一款功能多样的笔记软件&#xff0…

JAVA-贪吃蛇(源代码)

游戏界面: 图片素材: 背景图片 蛇身 食物 蛇头 标题 源代码: 运行界面 package com.snake.game;public class snakeApp {public static void main(String[] args) {//添加界面new snakeJFrame();} }游戏界面类JFrame package com.snake.game;import javax.swing.*; import …