Depth maps转点云

2024-04-15 19:36
文章标签 maps depth 转点

本文主要是介绍Depth maps转点云,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言
本文主要记录一下如何可视化相机位姿,如何用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 npfocal = 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 = poseextrinsic = np.eye(4)R, t = pose[:3, :3], pose[:3, 3]extrinsic[:3, :3] = R.Textrinsic[: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 * colorcam_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) / scaleX = (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 < 0X = 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('''plyformat ascii 1.0element vertex %dproperty float xproperty float yproperty float zproperty uchar blueproperty uchar greenproperty uchar redproperty uchar alphaend_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)

这篇关于Depth maps转点云的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/906725

相关文章

【CSS in Depth 2 精译_023】第四章概述 + 4.1 Flexbox 布局的基本原理

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

【CSS in Depth 2 精译_024】4.2 弹性子元素的大小

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结) 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位(已完结) 2.1 相对单位的威力2.2 em 与 rem2.3 告别像素思维2.4 视口的相对单位2.5 无单位的数值与行高2.6 自定义属性2.7 本章小结 第三章 文档流与盒模型(已

Go-Maps

语法汇总 前面介绍的array、slice都是顺序性列表,本节的map则是无序的。 这个map和C/C++/Java的map一样,在Python中称为字典/dictionary。但Golang中map的用法更符合脚本语言的特点,和Python很像。 涉及的主要语法点: var the_map map[string]intthe_map := make(map[string]int)th

Maximum Depth of N-ary Tree

Input: root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]Output: 5 思路1:DFS ,divide and conquer /*// Definition for a Node.class Node {public int v

Android Google Maps

Android 谷歌地图 前言正文一、设置Google Cloud 项目二、项目配置① 设置SDK② 配置API密钥③ 配置AndroidManifest.xml 三、添加地图四、定位当前① 请求定位权限② 我的位置控件③ 获取当前位置 五、配置地图① xml配置地图② 代码配置地图③ 地图点击事件④ 管理Marker 六、地址位置编码① 坐标转地址② 地址转坐标 七、源码 前言

HTML5培训第15节课堂笔记(HTML5+maps,geolocation)

HTML5培训第15节课堂笔记 1.地理信息定位: window.οnlοad=function(){         mui.plusReady(function(){            plus.geolocation.getCurrentPosition(function(p){                latitude=p.coords.latitude;

leetcode104 Maximum Depth Of Binary Java

Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 1、递归解法。两行 public int maxDept

leetcode 刷题之路 40 Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 求二叉树的最小深度,最小深度定义为从根节点到最近的叶子节点经过的节点个

【CVPR‘24】深度补全:Flexible Depth Completion for Sparse and Varying Point Densities

【CVPR'24】深度补全:Flexible Depth Completion for Sparse and Varying Point Densities 摘要1. 引言3. 方法3.1 基础深度估计架构3.2 基于亲和度的偏移校正3.3 校正置信度预测3.4 联合深度估计与完成3.5 损失 4. 实验4.1 数据集和评估指标4.2 实验概述4.3 消融研究 参考文献 摘要

【综述】 从稀疏的数据中进行深度补全:Deep Depth Completion from Extremely Sparse Data: A Survey

【综述】 从稀疏的数据中进行深度补全:Deep Depth Completion from Extremely Sparse Data: A Survey 占坑,3日内更新