RGB,深度图,点云和体素的相互转换记录

目录

1.RGBD2Point

1.2 步骤

2.Point2Voxel-Voxelization

2.1 原理

2.2 代码

3.Voxel2Point

4.Point2RGB

5.Voxel2RGB


1.RGBD2Point

input:RGB + D + 内外惨

output:points cloud

def depth2pcd(depth_img):"""深度图转点云数据图像坐标系 -> 世界坐标系 :param depth_img: 深度图:return: 点云数据 N*3"""# 相机内参cam_fx = 1120.12cam_fy = 1120.12cam_cx = 640.5cam_cy = 360.5factor = 1# 逐点处理,此过程可以使用numpy优化m, n = depth_img.shapepoint_cloud = []for v in range(m):for u in range(n):if depth_img[v, u] == 0:continuedepth = depth_img[v, u]p_z = depth / factor                         z = 深度/焦距p_x = (u - cam_cx) * p_z / cam_fx                             p_y = (v - cam_cy) * p_z / cam_fypoint_cloud.append([p_x, p_y, p_z])          # 这里还可以添加RGB信息point_cloud = np.array(point_cloud)return point_cloud

1.2 步骤

RGBD数据转换为点云的过程通常包括以下步骤:

  1. 从深度图像中提取点云坐标:使用深度图像中的像素值计算每个像素在三维空间中的坐标。这可以通过将深度值转换为相机坐标系下的坐标来实现。 (X,Y,Z)

    1. 确定相机内参和外参:相机内参包括相机的焦距、主点和畸变参数等,用于将像素坐标转换为相机坐标系下的坐标。相机外参包括相机在世界坐标系下的位置和方向,用于将相机坐标系下的坐标转换为世界坐标系下的坐标。

    2. 将深度图像转换为点云坐标:对于每个像素,根据其深度值和相机内参,可以计算出其在相机坐标系下的坐标。然后,根据相机外参,可以将相机坐标系下的坐标转换为世界坐标系下的坐标。这样就可以得到每个像素对应的点云坐标。

    3. 去除无效点:深度图像中可能包含一些无效点,例如深度值为0或超出一定范围的点。这些点需要被去除,以保证点云的质量和准确性。

    4. 可选:对点云进行滤波和重采样:为了减少噪声和数据量,可以对点云进行滤波和重采样。例如,可以使用高斯滤波或中值滤波来平滑点云,或使用体素格化和统计滤波来降低点云的密度。

  2. 从RGB图像中提取点云颜色:使用RGB图像中的像素值提取每个点的颜色信息。这可以通过将RGB值与对应的点云坐标进行匹配来实现。 (X,Y, Z,R,G,B)

    1. 确定相机内参和外参:与从深度图像中提取点云坐标类似,从RGB图像中提取点云颜色也需要相机内参和外参的信息。

    2. 将RGB图像转换为点云颜色:对于每个点云坐标,可以使用相机内参和外参将其对应到RGB图像上的像素坐标。然后,可以从RGB图像中提取对应像素的颜色信息,例如RGB值或HSV值等。

    3. 可选:对颜色进行校正和增强:为了提高颜色的准确性和鲁棒性,可以对颜色进行校正和增强。例如,可以使用颜色校正矩阵来校正颜色偏差,或使用直方图均衡化和对比度增强来增强颜色对比度。

  3. 将点云坐标和颜色信息组合成点云:将每个点的坐标和颜色信息组合成一个点云。这可以通过将坐标和颜色信息存储在一个结构体或数组中来实现

2.Point2Voxel-Voxelization

2.1 原理

将点云数据转换为体素(voxel)通常需要进行以下步骤:

  1. 确定体素大小和边界:体素大小是指体素的边长,它决定了体素的分辨率和精度。边界是指点云数据的空间范围,它决定了体素的数量和大小。

  2. 将点云数据转换为体素坐标:对于每个点云坐标,可以根据体素大小将其对应到体素坐标系下的坐标。例如,可以将点云坐标除以体素大小并向下取整,以得到其对应的体素坐标

  3. 将点云数据分配到体素中:对于每个体素坐标,可以将其对应的点云数据分配到该体素中。例如,可以将该体素中所有点云数据的颜色或法向量进行平均或加权平均,以得到该体素的颜色或法向量信息。

  4. 可选:对体素进行滤波和重采样:为了减少噪声和数据量,可以对体素进行滤波和重采样。例如,可以使用高斯滤波或中值滤波来平滑体素,或使用体素格化和统计滤波来降低体素的密度。

转换后的体素数据可以用于各种计算机视觉和机器学习任务,例如三维重建、物体识别和姿态估计等。

2.2 代码

import numpy as np
from scipy.spatial import cKDTree
def pointcloud_to_voxel(pointcloud, voxel_size):# 计算体素边界和数量min_bound = np.min(pointcloud, axis=0)max_bound = np.max(pointcloud, axis=0)voxel_count = np.ceil((max_bound - min_bound) / voxel_size).astype(int)# 将点云数据转换为体素坐标voxel_coords = np.floor((pointcloud - min_bound) / voxel_size).astype(int)# 将点云数据分配到体素中voxel_data = np.zeros(voxel_count + 1)for i in range(len(pointcloud)):voxel_data[tuple(voxel_coords[i])] += 1# 可选:对体素进行滤波和重采样# ...return voxel_data

3.Voxel2Point

将3D体素数据转换为点云数据通常需要进行以下步骤:

以下是一个简单的Python代码示例,用于将点云数据转换为RGB图像:

  1. 确定体素大小和边界:体素大小是指体素的边长,它决定了体素的分辨率和精度。边界是指3D体素数据的空间范围,它决定了体素的数量和大小。

  2. 遍历体素数据,将非空体素转换为点云数据:对于每个非空体素,可以将其转换为一个或多个点云数据。例如,可以将该体素的中心点作为点云数据,或者将该体素中所有非空体素的中心点作为点云数据。

  3. 可选:对点云数据进行滤波和重采样:为了减少噪声和数据量,可以对点云数据进行滤波和重采样。例如,可以使用高斯滤波或中值滤波来平滑点云数据,或使用体素格化和统计滤波来降低点云数据的密度。

  4. import numpy as np
    def voxel_to_pointcloud(voxel_data, voxel_size):# 计算体素边界和数量min_bound = np.array([0, 0, 0])max_bound = np.array(voxel_data.shape) * voxel_size# 遍历体素数据,将非空体素转换为点云数据pointcloud = []for x in range(voxel_data.shape[0]):for y in range(voxel_data.shape[1]):for z in range(voxel_data.shape[2]):if voxel_data[x, y, z] > 0:pointcloud.append([x * voxel_size, y * voxel_size, z * voxel_size])# 可选:对点云数据进行滤波和重采样# ...return np.array(pointcloud)

    4.Point2RGB

    将点云数据转换为RGB图像通常需要进行以下步骤:

  5. 确定图像大小和分辨率:图像大小是指图像的宽度和高度,它决定了图像的分辨率和精度。分辨率是指图像中每个像素的大小,通常以像素/英寸(PPI)或像素/厘米(PPC)为单位。

  6. 将点云数据转换为图像坐标:对于每个点云坐标,可以根据图像大小和分辨率将其对应到图像坐标系下的坐标。例如,可以将点云坐标乘以分辨率并向下取整,以得到其对应的图像坐标。

  7. 将点云数据分配到图像中:对于每个图像坐标,可以将其对应的点云数据分配到该像素中。例如,可以将该像素中所有点云数据的颜色进行平均或加权平均,以得到该像素的颜色信息。

  8. 可选:对图像进行滤波和增强:为了减少噪声和提高图像质量,可以对图像进行滤波和增强。例如,可以使用高斯滤波或中值滤波来平滑图像,或使用直方图均衡化和对比度增强来增强图像对比度。

    import numpy as np
    import cv2
    def pointcloud_to_rgb(pointcloud, image_size, resolution):# 确定图像大小和分辨率image_width, image_height = image_sizepixel_size = 1 / resolution# 将点云数据转换为图像坐标image_coords = np.floor((pointcloud[:, :2] * resolution)).astype(int)# 将点云数据分配到图像中image_data = np.zeros((image_height, image_width, 3))for i in range(len(pointcloud)):x, y = image_coords[i]image_data[y, x] += pointcloud[i, 2:]# 可选:对图像进行滤波和增强# ...# 将图像数据转换为RGB图像image_data = (image_data / np.max(image_data) * 255).astype(np.uint8)rgb_image = cv2.cvtColor(image_data, cv2.COLOR_BGR2RGB)# 可选:使用OpenCV显示图像cv2.imshow('RGB Image', rgb_image)cv2.waitKey(0)cv2.destroyAllWindows()return rgb_image

    5.Voxel2RGB

    将3D体素数据转换为2D图像通常需要进行以下步骤:

  9. 确定投影方向和投影平面:投影方向是指将3D体素数据投影到2D图像的方向,通常是x、y或z轴方向。投影平面是指投影方向所在的平面,通常是与另外两个轴垂直的平面。

  10. 将3D体素数据投影到2D图像:对于每个投影平面上的像素,可以将其对应到3D体素数据中的体素坐标。然后,可以根据投影方向和投影平面,将该体素沿着投影方向上的值投影到2D图像上的像素值中。例如,可以将该体素的最大值或平均值作为该像素的像素值。

  11. 可选:对2D图像进行滤波和增强:为了减少噪声和提高图像质量,可以对2D图像进行滤波和增强。例如,可以使用高斯滤波或中值滤波来平滑图像,或使用直方图均衡化和对比度增强来增强图像对比度。

  12. import numpy as np
    import cv2
    def voxel_to_image(voxel_data):# 确定投影方向和投影平面proj_axis = 2proj_plane = np.delete(np.arange(3), proj_axis)# 将3D体素数据投影到2D图像proj_data = np.max(voxel_data, axis=proj_axis)proj_data = np.transpose(proj_data, axes=proj_plane)# 可选:对2D图像进行滤波和增强# ...# 将2D图像转换为灰度图像proj_data = (proj_data / np.max(proj_data) * 255).astype(np.uint8)# 可选:使用OpenCV显示图像cv2.imshow('Projection', proj_data)cv2.waitKey(0)cv2.destroyAllWindows()return proj_data

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

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

相关文章

翻译 《The Old New Thing》 - Why is a registry file called a “hive“?

Why is a registry file called a “hive“?https://devblogs.microsoft.com/oldnewthing/20030808-00/?p42943 为什么注册表文件被称为‘蜂巢’? Raymond Chen 2003年8月8日 分享一个没用的知识: 话说有一位 Windows NT 的开发者十分讨厌蜜蜂。于是&a…

FLV流媒体封装格式

1、FLV 简介 FLV(Flash Video) 是 Adobe 公司推出的一种流媒体格式,由于其封装后的音视频文件体积小、封装简单等特点,非常适合于互联网上使用。目前主流的视频网站基本都支持FLV。采用 FLV 格式封装的文件后缀为.flv。直播场景下拉流比较常见的是 http-…

计算机网络:现代通信的基石

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

小白了解Pinia第2集 · 三大核心状态Getters、Actions以及Plugins 插件

三大核心状态 state 第1集有详细讲解:https://blog.csdn.net/qq_51463650/article/details/137137080?spm1001.2014.3001.5501 getters Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个…

Elastic 8.13:Elastic AI 助手中 Amazon Bedrock 的正式发布 (GA) 用于可观测性

作者:来自 Elastic Brian Bergholm 今天,我们很高兴地宣布 Elastic 8.13 的正式发布。 有什么新特性? 8.13 版本的三个最重要的组件包括 Elastic AI 助手中 Amazon Bedrock 支持的正式发布 (general availability - GA),新的向量…

汽车电子行业知识:什么是智能驾驶辅助系统(ADAS)

文章目录 1. 什么是智能驾驶辅助系统(ADAS)1.1 ADAS的功能1.2 ADAS的优势1.3 未来发展趋势 2. ADAS等级2.1. 0级驾驶辅助2.2. 1级驾驶辅助2.3. 2级驾驶辅助2.4. 3级驾驶辅助2.5. 4级和5级驾驶辅助 3. 智能车4. ADAS供应商 1. 什么是智能驾驶辅助系统&…

文章分享:协和文章《病原宏基因组高通量测序性能确认方案》

摘要:宏基因组学利用新一代高通量测序技术,以特定环境下病原体基因组为研究对象,在分析病原体多样性、种群结构、进化关系的基础上,进一步探究病原体的群体功能活性、相互作用及其与环境之间的关系,发掘潜在的生物学意…

STM32之HAL开发——串口配置(CubeMX)

串口引脚初始化(CubeMX) 选择RCC时钟来源 选择时钟频率,配置为最高频率72MHZ 将单片机调试模式打开 SW模式 选择窗口一配置为异步通信模式 点击IO口设置页面,可以看到当前使用的串口一的引脚。如果想使用复用功能,只需…

每天五分钟深度学习:使用神经网络完成人脸的特征点检测

本文重点 我们上一节课程中学习了如何利用神经网络对图片中的对象进行定位,也就是通过输出四个参数值bx、by、bℎ和bw给出图片中对象的边界框。 本节课程我们学习特征点的检测,神经网络可以通过输出图片中对象的特征点的(x,y)坐标来实现对目标特征的识别,我们看几个例子。…

前端发版上线出现白屏问题

目录 路由配置问题资源缓存问题首屏加载过慢 :喂,你的页面白啦! 出现上线白屏的问题有很多,如:配置错误、缓存问题、浏览器兼容问题,根据不同情况去解决。 路由配置问题 问题描述: 在vue开发…

C语言中的联合体和枚举

联合体 联合体的创建 联合体的关键字是union union S {char a;int i; };除了关键字和结构体不一样之外,联合体的创建语法形式和结构体的很相似,如果不熟悉结构体的创建,可以看一下我上一篇的博客关于结构体知识的详解。 联合体的特点 联合…

HarmonyOS 应用开发之进程模型

系统的进程模型如下图所示。 应用中(同一Bundle名称)的所有UIAbility、ServiceExtensionAbility和DataShareExtensionAbility均是运行在同一个独立进程(主进程)中,如下图中绿色部分的“Main Process”。应用中&#x…

matlab及其在数字信号处理中的应用001:软件下载及安装

目录 一,matlab的概述 matlab是什么 matlab适用于的问题 matlab的易扩展性 二,matlab的安装 1,解压所有压缩文件 2,解压镜像压缩文件 3,运行setup.exe 4,开始安装 5,不要运行软件…

Python环境下基于深度学习的旋转机械故障诊断及其权重可视化

随着神经网络所要完成的任务越来越智能化,其内部的结构也变得越来越复杂,神经网络学到的解题方法也越来越难以被人类所理解。神经网络的内部单元就好比一个“黑箱”,虽然这种处理方法能够在某种程度上达到非常不错的效果,但其原因…

同城外卖多商户点餐系统平台开发JAVA版源码跑腿小程序APP

项目背景 在快节奏的现代生活中,人们对于时间的需求愈发敏感。如何在忙碌中兼顾生活与工作,如何在繁杂琐事中找到一丝便利,这已然成为众多都市人共同关心的议题。在这样的背景下,同城外卖跑腿系统软件应运而生,以其高…

Modbus转Profinet网关快速解决PLC插槽数量不够用的烦恼

通过Modbus转Profinet(XD-MDPN100)网关的应用,不仅可以实现Modbus设备与Profinet网络的平滑对接,还能有效解决PLC插槽限制和Modbus指令轮询等问题,Modbus转Profinet网关(XD-MDPN100)在解决PLC插…

Etcd 基本入门

1:什么是 Etcd ? Etcd 是 CoreOS 团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,Etcd基于 Go 语言实现。 名字由来,它源于两个方面,…

java将文件转成流文件返回给前端

环境:jdk1.8,springboot2.5.3,项目端口号:9100 1.待转换的文件 一、路径 二、文件内容 2.controller中代码 package com.example.pdf.controller;import com.example.pdf.service.GetFileStreamService; import org.springframework.web.b…

嵌入式linux学习之交叉编译器安装

交叉编译器介绍 ARM 裸机、Uboot 移植、Linux 移植这些都需要在 Ubuntu 下进行编译,编译就需要编译器,在 Liux 进行 C 语言开发里面使用 GCC 编译器进行代码编译,但是 Ubuntu 自带的 gcc 编译器是针对 X86 架构的!而我们现在要编…

封装性练习

练习 1 : 创建程序:在其中定义两个类: Person 和 PersonTest 类。定义如下: 用 setAge() 设置人的合法年龄 (0~130) ,用 getAge() 返回人的年龄。在 PersonTest 类中实例化 Person 类的对象 b ,调用 set…