kitti数据深度图转点云坐标计算方法与教程(代码实现)

文章目录

  • 前言
  • 一、kitti深度图官网介绍
    • 1、官网深度图介绍
    • 2、深度图读取官网代码(python)
    • 3、深度图解读
      • 1、数据格式内容
      • 2、深度图加工
      • 3、深度图转相机坐标深度
  • 二、kitti数据内参P矩阵解读
    • 1、P2矩阵举例
    • 2、内参矩阵 (3x3)
    • 3、特殊平移向量(第4列)
    • 4、kitti的bx与by解释
  • 三、kitti深度图转换基础函数
    • 1、图像获取函数方法
    • 2、点云数据获取函数方法
    • 3、标定文件数据获取函数方法
      • 外参逆矩阵求解(转置方法求解)
      • 外参逆矩阵求解(直接求解)
    • 4、可视化点云数据函数方法
  • 四、kitti深度图转点云坐标方法
    • 1、深度图读取与转深度坐标方法
    • 2、深度图转点云坐标整体代码
    • 3、像素坐标与深度值获取
    • 4、坐标转换 u v depth格式
    • 5、深度图图像深度值绘制
    • 6、像素与深度值对转相机坐标
    • 7、相机坐标系转点云坐标系
  • 五、完整代码与结果现实
    • 1、结果现实
    • 2、完整代码

前言

kitti数据是一个通用数据,但里面点云坐标如何转到像素坐标以及对应点云转到像素坐标对应的相机坐标的深度值求解,也是一个较为麻烦的事情。如果你是小白,必然会在其中摸不着头脑。为此,本文分享kitti数据的点云坐标转像素坐标方法以及对应像素坐标的深度值求解方法,这也是本文重点介绍内容。而本文与其它文章不太相同,我们不纯粹讲解原理,而是使用代码直接转换,并在代码过程中说明其原理,我们也会给出完整代码。

注:像素与深度值对转相机坐标内容就是给出深度值如何转3d相机坐标,该部分内容十分重要!

一、kitti深度图官网介绍

1、官网深度图介绍

通过kitti官网下载后获得devkit内容获得了深度图说明,而devkit内容如下:
在这里插入图片描述
深度图解读如下,该部分内容来源readme.txt文件内容,我只是将其部分翻译成了中文而已。

###########################################################################
# THE KITTI VISION BENCHMARK: DEPTH PREDICTION/COMPLETION BENCHMARKS 2017 #
#       based on our publication Sparsity Invariant CNNs (3DV 2017)       #
#                                                                         #
#           Jonas Uhrig     Nick Schneider     Lukas Schneider            #
#           Uwe Franke       Thomas Brox        Andreas Geiger            #
#                                                                         #
#          Daimler R&D Sindelfingen       University of Freiburg          #
#          KIT Karlsruhe         ETH Zürich         MPI Tübingen          #
#                                                                         #
###########################################################################This file describes the 2017 KITTI depth completion and single image depth
prediction benchmarks, consisting of 93k training and 1.5k test images.
Ground truth has been acquired by accumulating 3D point clouds from a
360 degree Velodyne HDL-64 Laserscanner and a consistency check using
stereo camera pairs. Please have a look at our publications for details.这份文件描述了2017年的KITTI深度完成及单目图像深度预测基准测试,包含93,000张训练图
像和1,500张测试图像。真实数据是通过累积来自360度Velodyne HDL-64激光雷达扫描仪的3D
点云数据,并使用立体相机对进行一致性检查获得的。更多详情请参阅我们的出版物。
Dataset description:
====================If you unzip all downloaded files from the KITTI vision benchmark website
into the same base directory, your folder structure will look like this:|-- devkit
|-- test_depth_completion_anonymous|-- image|-- 0000000000.png|-- ...|-- 0000000999.png|-- velodyne_raw|-- 0000000000.png|-- ...|-- 0000000999.png
|-- test_depth_prediction_anonymous|-- image|-- 0000000000.png|-- ...|-- 0000000999.png
|-- train|-- 2011_xx_xx_drive_xxxx_sync|-- proj_depth|-- groundtruth           # "groundtruth" describes our annotated depth maps|-- image_02            # image_02 is the depth map for the left camera|-- 0000000005.png    # image IDs start at 5 because we accumulate 11 frames|-- ...               # .. which is +-5 around the current frame ;)|-- image_03            # image_02 is the depth map for the right camera|-- 0000000005.png|-- ...|-- velodyne_raw          # this contains projected and temporally unrolled|-- image_02            # raw Velodyne laser scans|-- 0000000005.png|-- ...|-- image_03|-- 0000000005.png|-- ...|-- ... (all drives of all days in the raw KITTI dataset)
|-- val|-- (same as in train)
|-- val_selection_cropped       # 1000 images of size 1216x352, cropped and manually|-- groundtruth_depth         # selected frames from from the full validation split|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...|-- image|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...|-- velodyne_raw|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...For train and val splits, the mapping from the KITTI raw dataset to our
generated depth maps and projected raw laser scans can be extracted. All
files are uniquely identified by their recording date, the drive ID as well
as the camera ID (02 for left, 03 for right camera).
对于训练和验证集的划分,可以从原始的KITTI数据集映射到我们生成的深度图和投影的原始激光雷达扫描。
所有文件都通过记录日期、驾驶ID以及相机ID02表示左相机,03表示右相机)唯一标识。Submission instructions:
========================NOTE: WHEN SUBMITTING RESULTS, PLEASE STORE THEM IN THE SAME DATA FORMAT IN
WHICH THE GROUND TRUTH DATA IS PROVIDED (SEE BELOW), USING THE FILE NAMES
0000000000.png TO 0000000999.png (DEPTH COMPLETION) OR 0000000499.png (DEPTH
PREDICTION). CREATE A ZIP ARCHIVE OF THEM AND STORE YOUR RESULTS IN YOUR
ZIP'S ROOT FOLDER:|-- zip|-- 0000000000.png|-- ...|-- 0000000999.pngData format:
============Depth maps (annotated and raw Velodyne scans) are saved as uint16 PNG images,
which can be opened with either MATLAB, libpng++ or the latest version of
Python's pillow (from PIL import Image). A 0 value indicates an invalid pixel
(ie, no ground truth exists, or the estimation algorithm didn't produce an
estimate for that pixel). Otherwise, the depth for a pixel can be computed
in meters by converting the uint16 value to float and dividing it by 256.0:
深度图(标注过的和原始的Velodyne扫描)保存为uint16的PNG图像,可以使用MATLAB、
libpng++或Python的pillow库的最新版本(从PIL导入Image)打开。一个0值表示无效像
素(即,没有真实值,或者估计算法没有为该像素产生估计)。否则,可以通过将uint16
值转换为浮点数并除以256.0来计算像素的深度(以米为单位):disp(u,v)  = ((float)I(u,v))/256.0;
valid(u,v) = I(u,v)>0;Evaluation Code:
================For transparency we have included the benchmark evaluation code in the
sub-folder 'cpp' of this development kit. It can be compiled by running
the 'make.sh' script. Run it using two arguments:./evaluate_depth gt_dir prediction_dirNote that gt_dir is most likely '../../val_selection_cropped/groundtruth_depth'
if you unzipped all files in the same base directory. We also included a sample
result of our proposed approach for the validation split ('predictions/sparseConv_val').
为了保证透明性,我们在此开发套件的子文件夹'cpp'中包含了基准评估代码。可以通过运行
'make.sh'脚本来编译它。使用两个参数来运行它:./evaluate_depth gt_dir prediction_dir注意,gt_dir很可能就是'../../val_selection_cropped/groundtruth_depth',假如你是在
同一个基础目录下解压了所有文件的话。我们也包括了我们提出的方法在验证集上的一个示例
结果('predictions/sparseConv_val')。

2、深度图读取官网代码(python)

读取深度图有MATLAB、cpp与python代码,我这里直接给出python代码,如下:

#!/usr/bin/pythonfrom PIL import Image
import numpy as npdef depth_read(filename):# loads depth map D from png file# and returns it as a numpy array,# for details see readme.txtdepth_png = np.array(Image.open(filename), dtype=int)# make sure we have a proper 16bit depth map here.. not 8bit!assert(np.max(depth_png) > 255)depth = depth_png.astype(np.float) / 256.depth[depth_png == 0] = -1.return depth

3、深度图解读

1、数据格式内容

我还是引入官网内容,如下:

|-- devkit
|-- test_depth_completion_anonymous|-- image|-- 0000000000.png|-- ...|-- 0000000999.png|-- velodyne_raw|-- 0000000000.png|-- ...|-- 0000000999.png
|-- test_depth_prediction_anonymous|-- image|-- 0000000000.png|-- ...|-- 0000000999.png
|-- train|-- 2011_xx_xx_drive_xxxx_sync|-- proj_depth|-- groundtruth           # "groundtruth" describes our annotated depth maps|-- image_02            # image_02 is the depth map for the left camera|-- 0000000005.png    # image IDs start at 5 because we accumulate 11 frames|-- ...               # .. which is +-5 around the current frame ;)|-- image_03            # image_02 is the depth map for the right camera|-- 0000000005.png|-- ...|-- velodyne_raw          # this contains projected and temporally unrolled|-- image_02            # raw Velodyne laser scans|-- 0000000005.png|-- ...|-- image_03|-- 0000000005.png|-- ...|-- ... (all drives of all days in the raw KITTI dataset)
|-- val|-- (same as in train)
|-- val_selection_cropped       # 1000 images of size 1216x352, cropped and manually|-- groundtruth_depth         # selected frames from from the full validation split|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...|-- image|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...|-- velodyne_raw|-- 2011_xx_xx_drive_xxxx_sync_groundtruth_depth_xxxxxxxxxx_image_0x.png|-- ...

2、深度图加工

官网已经说的很明白了,我们读取的深度图(标注过的和原始的Velodyne扫描)保存为uint16的PNG图像,可以使用MATLAB、libpng++或Python的pillow库的最新版本(从PIL导入Image)打开。一个0值表示无效像素(即,没有真实值,或者估计算法没有为该像素产生估计)。否则,可以通过将uint16值转换为浮点数并除以256.0来计算像素的深度(以米为单位)。使用计算方法如下代码:

disp(u,v)  = ((float)I(u,v))/256.0;
valid(u,v) = I(u,v)>0;

3、深度图转相机坐标深度

其实就是1中的代码,我这里将其再次给出,以此强调含义,代码如下:

from PIL import Image
import numpy as npdef depth_read(filename):# loads depth map D from png file# and returns it as a numpy array,# for details see readme.txtdepth_png = np.array(Image.open(filename), dtype=int)# make sure we have a proper 16bit depth map here.. not 8bit!assert(np.max(depth_png) > 255)depth = depth_png.astype(np.float) / 256.depth[depth_png == 0] = -1.return depth

二、kitti数据内参P矩阵解读

1、P2矩阵举例

在KITTI数据集中,校准文件中的每个数值都有其特定的含义。下面是对您提供的P2矩阵中各个数值的具体解释:

P2: 7.215377000000e+02 0.000000000000e+00 6.095593000000e+02 4.485728000000e+01 0.000000000000e+00 7.215377000000e+02 1.728540000000e+02 2.163791000000e-01 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 2.745884000000e-03

我们可以将其重组成一个3x4矩阵的形式:

[ 7.215377000000e+02  0.000000000000e+00  6.095593000000e+02  4.485728000000e+01 ]
[ 0.000000000000e+00  7.215377000000e+02  1.728540000000e+02  2.163791000000e-01 ]
[ 0.000000000000e+00  0.000000000000e+00  1.000000000000e+00  2.745884000000e-03 ]

这个矩阵可以分为两部分:左上角的3x3子矩阵是相机的内参矩阵,右列(第4列)是与相机坐标系到图像坐标系之间平移相关的参数。

2、内参矩阵 (3x3)

  • 第一行第一列(fx):x轴方向上的焦距(以像素为单位)。这是将物理尺寸转换为像素的重要参数。在本例中,fx = 7.215377
  • 第二行第二列(fy):y轴方向上的焦距(以像素为单位)。这同样用于物理尺寸到像素的转换。在本例中,fy = 7.215377
  • 第一行第三列(cx):图像坐标系的主点(光心)在x轴上的位置(以像素为单位)。这是图像中心的x坐标。在本例中,cx = 6.095593
  • 第二行第三列(cy):图像坐标系的主点(光心)在y轴上的位置(以像素为单位)。这是图像中心的y坐标。在本例中,cy = 1.728540

3、特殊平移向量(第4列)

  • 第一行第四列(tx):相机坐标系到图像平面在x轴上的平移距离(通常以像素为单位)。在本例中,tx = 4.4857

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Redis实现记录访问次数(三种方案)

目录 0. 前言1. 使用Filter实现2. 使用AOP实现 1. 导入依赖 2. 写一个切面类,实现统计访问次数。 3. 开启AOP 4. 测试 5. plus版本 (1) 新建一个bean类 (2) 新增一个controller方法 (3) 新增一个循环增强方法 (4) 测试…

Python之Redis操作方法

目录 一. 介绍A. 什么是 Redis?B. Redis 的特点和用途C. Python 操作 Redis 的优势 二. 使用 Redis 客户端库A. 安装 Redis 客户端库B. 导入 Redis 模块C. 创建 Redis 客户端实例 三. 数据操作A. 键值对操作1. 设置键值对2. 获取键值对3. 检查键是否存在4. 删除键5.…

使用切换 JDK 的方式优化部署微服务占用内存过高的问题

使用切换 JDK 的方式优化部署微服务占用内存过高的问题 一、前言二、下载 J9 虚拟机的JDK三、切换 JDK1、上传到服务器2、解压3、修改 JDK 路径4、解决 JDK 没有切换成功的问题 一、前言 前段时间在服务器部署了微服务项目,但即使限制了每个服务的堆,内…

【网络安全】-文件下载漏洞-pikachu

文件操作漏洞包括文件上传漏洞,文件包含漏洞,文件下载漏洞。 文章目录  前言 什么是文件下载漏洞? 1.常见形式: 常见链接形式: 常见参数: 2.利用方式: 3.举例:pikachu不安全的文件…

ABB机械手备份与恢复

ABB机械手备份与恢复 备份恢复系统 备份 ABB机器人数据备份的对象是所有正在系统内存中运行的RAPID程序和系统参数。当机器人系统出现错乱或者重新安装系统以后,可以通过备份快速地把机器人恢复到备份时的状态。 如果导出到U盘需要将U盘插入USB接口,位置…

【思博伦】史上最详细思博伦测试仪使用精讲!图解超赞超详细!!!

承接上文 目录 2.2.9.7 配置TCPFLAG 2.2.9.8 配置分片 2.2.9.9 添加VLAN标签 2.2.9.10 添加MPLS标签 2.2.9.11 添加Vntag标签 2.2.9.12 重新快速新建新的帧内容 ​​​​​​​2.2.10 导入Pcap包 2.2.11 发包配置 2.2.11.1 发包模式配置 ​​​​​​​2.2.11.2 配置…

SpringMVC基于注解使用:国际化

01-国际化介绍 首先在bootstrap下载个页面 下载后把登录页面的代码粘上去 然后再登录页面代码上有些超链接需要再spring-mvc.xml里面配置下,登录页面才能正常显示 配置静态资源 国际化-根据浏览器语言国际化 现在是中文的情况,要改为英文 1.配置下属…

ROS入门教程(八)—— 路径规划导航实战

通过Gazebo仿真和RViz仿真的学习后,本文将通过Gazebo与RViz联合仿真实现机器人在Gazebo仿真环境中运动,通过远距搜索与近距搜索实现机器人路径规划导航。 目录 前言 实现思路 仿真模型 仿真源码 前言 前面的ROS入门教程提供ROS仿真的基础步骤,本文提供了实现思路,仿真…

C#笔记10 Thread类怎么终止(Abort)和阻止(Join)线程

Thread类 C#笔记8 线程是什么?多线程怎么实现和操作?-CSDN博客 C#笔记9 对线程Thread的万字解读 小小多线程直接拿下!-CSDN博客 上次说过怎么简单的使用多线程,怎么创建多线程,但是没有具体分析它的终止和释放。 线…

L2线性回归模型

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 鸢尾花数据集的单变量与多变量预测 在这周学习如何使用 机器学习 模型对鸢尾花(Iris)数据集进行单变量与多变量预测。我们将使用鸢尾花…

学习pyqt5相关知识回顾

1. 模块 1.1 import导入 1) 模块:是一系列功能的集合体,模块名.功能名,就可以使用模块的功能 2) 首次导入模块,就会立即执行模块里面的内容 3) 当前名称空间会产生一个名字module,指向module.py产生的名称空间.我们可以使用module.name/函数名,来调用module.py里面的内容. …

RQ-RAG:提升检索增强生成模型的查询精炼能力

人工智能咨询培训老师叶梓 转载标明出处 大模型在面对未见场景时,往往会产生不准确或虚构的回答,这限制了它们的实用性。为了解决这一问题,香港科技大学、香港理工大学和麻省理工学院的研究团队提出了一种名为RQ-RAG(Retrieval-A…

被低估的SQL

SQL是现代数据库管理系统中不可或缺的一部分。尽管它的使用已十分普遍,但在数据处理领域,SQL的某些功能和潜力仍然被许多人低估。接下来,小编将与您一起,探讨SQL的一些被忽视的特性,揭示它在数据管理中的真正实力。 1.…

模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<、==、<=、>=、!=的运算符重载、赋值运算符(=)重载等的介绍

文章目录 前言一、 clear函数二、流提取(<<)和流插入(>>)运算符重载三、 >、<、、<、>、!的运算符重载四、赋值运算符&#xff08;&#xff09;重载总结 前言 模拟实现string类: clear函数、流提取(<<)和流插入(>>)运算符重载、>、<…

记一次导入dbf文件后数据为空问题的解决方法

前言 省流&#xff1a;这篇文章最终采用的是更换导出文件格式的方法&#xff0c;看到这里觉得方法不适用的小伙伴可以不用浪费几秒钟看完这篇文章哦。 问题描述 作者使用的是Navicat数据库管理工具&#xff0c;然后在将源数据库的数据表导出为dbf格式文件后&#xff0c;再将…

Linux进阶命令-echodatealias

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 经过上一章Linux日志的讲解&#xff0c;我们对Linux系统自带的日志服务已经有了一些了解。我们接下来将讲解一些进阶命令&am…

JAVA中获取类的超类(父类)或接口的class类型

一、前言 这里所说的超类&#xff08;父类&#xff09;或接口&#xff0c;指的就是某个类继承了一个类或实现了N个接口。 比如ArrayList&#xff0c;它继承了一个类&#xff08; java. util. AbstractList<E> &#xff09;&#xff0c;这时候AbstractList就称为ArrayLi…

如何让人工智能训练更快

影响人工智能训练时间的因素 在深度学习训练中&#xff0c;训练时间的计算涉及到多个因素&#xff0c;包括 epoch 数、全局 batch size、微 batch size、计算设备数量等。下面是一个基本的公式来说明这些参数之间的关系&#xff08;注意&#xff0c;这只是一个基本的说明公式&…

ctfshow-文件包含

web78 <?phpif(isset($_GET[file])){$file $_GET[file];include($file); }else{highlight_file(__FILE__); } 判断是否存在file参数 如果存在 将包含这个参数值 文件 php://filter可以获取指定文件源码。当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执…

Jmeter终极线程组“Ultimate Thread Group“如何使用?

1、安装,点击"选项"&#xff0c;再点击"Plugins Manager"&#xff0c;下载"Custom Thread Groups" 2、添加"jpgc - Ultimate Thread Group" 3、"jpgc - Ultimate Thread Group"使用