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

news2024/11/16 18:06:39

文章目录

  • 前言
  • 一、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.png

Data 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_dir

Note 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/python

from PIL import Image
import numpy as np

def depth_read(filename):
    # loads depth map D from png file
    # and returns it as a numpy array,
    # for details see readme.txt

    depth_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 np

def depth_read(filename):
    # loads depth map D from png file
    # and returns it as a numpy array,
    # for details see readme.txt

    depth_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.coloradmin.cn/o/2126670.html

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

相关文章

【getshell】phpmyadmin后台getshell(4.8.5)

🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍收藏💗支持一下哦 【getshell】phpmyadmin后台getshell(4.8.5) 一、进入sql命令输入界面二、上传代码三、getshell 一、进入…

LINQ 和 LINQ扩展方法 (1)

LINQ函数概念: LINQ(Language Integrated Query)是一种C#语言中的查询技术,它允许我们在代码中使用类似SQL的查询语句来操作各种数据源。这些数据源可以是集合、数组、数据库、XML文档等等。LINQ提供了一种统一的编程模型&#x…

2024/9/11 数学20题(拐点、定积分比大小、二重积分比大小)

拐点: 1000题基础篇: 1000题强化篇: 选b 、 定积分比大小: 二重积分比大小:

【读书笔记-《30天自制操作系统》-19】Day20

本篇的内容围绕系统调用展开。为了让应用程序能够调用操作系统功能,引入了系统调用以及API的概念。首先实现了显示单个字符的API,让应用程序通过传递地址的方式进行调用;接下来又改进为通过中断的方式进行调用。在此基础上继续实现了显示字符…

【CanMV K230 AI视觉】人脸姿态(脸部朝向)

【CanMV K230 AI视觉】人脸姿态(脸部朝向) 人脸姿态(脸部朝向) (动态测试效果可以去下面网站自己看。) B站视频链接:已做成合集 抖音链接:已做成合集 人脸姿态(脸部朝向…

基于yolov8的工程车辆挖掘机叉车卡车检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的工程车辆(如挖掘机、叉车、卡车)检测系统是一种利用先进深度学习技术的智能监控系统。该系统集成了YOLOv8算法,该算法以其高效的检测速度和准确的识别能力著称,特别适用于实时视频分析场景。 该系统通…

C2 Magic 附工具下载,供学习使用

最近,我们进行了一次安全演练,想要模拟一些复杂的攻击场景并测试我们的防御能力。这时,我想到了一款开源工具,它在处理抗沙箱后门启动和隐蔽ShellCode调用方面表现得非常出色。这款工具的设计理念是为了帮助安全团队更好地应对高级…

使用QT界面运行roslaunch,roslaunch,roscore等

QT通过界面运行rosrun,roslaunch,roscore等 QT 运行roslaunch加入ui界面修改cmakelist运行 使用qt界面运行rosrun,roscore,roslaunch等方法一方法二方法三 QT 运行roslaunch 首先需要使用QT安装好ROS插件,并且配置好环境,这个在之前的文章已…

nvm ls-remote: N/A

背景: 项目因为node版本问题运行失败,在彻底删除node后再重新安装 问题描述: 原因分析: 可能是因为终端不能获取镜像包 解决办法: 【方法一】 输入: step1. export NVM_NODEJS_ORG_MIRRORIndex of …

数据处理与统计分析篇-day01-Linux基础与环境搭建

day01-Linux基础 计算机简介 概述 电子计算机, 电脑, PC, Computer, 就是由 软件 硬件组成的 电子设备. 组成 计算机硬件 CPU(运算器, 控制器) 存储器(内存, 外存) 输入设备 输出设备 计算机软件 系统软件: 充当 用户 和 计算机硬件之间的 桥梁的. PC端: windows, Linu…

Elasticsearch 使用误区之五——单次请求获取大量数据

在使用 Elasticsearch 进行数据查询时,很多开发者、读者会遇到这样的问题:一次性检索大量数据,导致查询速度缓慢、网络延迟增加,甚至影响系统的整体性能。 单次获取过多数据不仅增加了网络传输的负担,还会使查询过程复…

Vue 中的 Web Workers:提升性能与流畅度

大家可能都听到过 Web Workers,那究竟如何使用呢?可以往下了解一下。 1. 什么是 Web Workers? Web Workers 是现代浏览器提供的一种机制,允许我们在主线程之外运行 JavaScript 脚本,避免阻塞 UI 渲染和用户交互操作。…

verilog vscode 与AI 插件

Verilog 轻量化开发环境 背景 笔者常用的开发环境 VIAVDO, 体积巨大,自带编辑器除了linting 能用,编辑器几乎不能用,仿真界面很友好,但是速度比较慢。Sublime Text, 非常好用的编辑器,各种插件使用verilog 非常方便…

深入理解Java虚拟机:Jvm总结-Java内存区域与内存溢出异常

第二章 Java内存区域与内存溢出异常 2.1 意义 对于C、C程序开发来说,程序员需要维护每一个对象从开始到终结。Java的虚拟自动内存管理机制,让java程序员不需要手写delete或者free代码,不容易出现内存泄漏和内存溢出问题,但是如果…

CSGHub携手Nvidia NIM、阿里计算巢打造企业级私有化部署解决方案

强强联合 人工智能与大数据的迅速发展,大模型的推理应用和资产管理已成为企业数字化转型的重要组成部分,企业正寻求高效、安全的AI模型部署解决方案。为应对日益增长的计算需求和复杂的数据管理挑战,CSGHub、Nvidia和阿里云计算巢强强联手&a…

Frozen CLIP: A Strong Backbone for Weakly Supervised Semantic Segmentation

摘要 弱监督语义分割在图像级标签方面取得了巨大的成就。最近的几种方法使用CLIP模型生成伪标签来训练单个分割模型,而没有尝试将CLIP模型作为主干,直接分割具有图像级标签的对象。在本文中,我们提出了 WeCLIP,一个基于 CLIP 的单…

【笔记】自动驾驶预测与决策规划_Part1_自动驾驶决策规划简介

自动驾驶决策规划简介 0、前言1、自动驾驶概述1.1 预测(Prediction)1.2 决策(Decision Making)1.3 规划(Planning) 2、自动驾驶历史和背景3、自动驾驶级别和分类4、预测决策规划的重要性4.1 预测的重要性4.…

环境搭建---部署rabbitmq集群

rabbitmq下载:https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.34/rabbitmq-server-generic-unix-3.8.34.tar.xz erlang下载:https://github.com/erlang/otp/releases/download/OTP-24.3.4.1/otp_src_24.3.4.1.tar.gz 配置主机名 …

MySQL原理之UUID主键分析,插入或更新语法分析

文章目录 1 MySQL不能用UUID做主键1.1 前言1.2 mysql和程序实例1.2.1 准备工作1.2.2 开始测试1.2.3 程序写入结果1.2.4 效率测试结果 1.3 使用uuid和自增id的索引结构对比1.3.1 自增id1.3.2 uuid 1.4 自增id缺点1.5 雪花算法 2 插入或更新2.1 on duplicate key2.1.1 定义2.1.2 …

git版本问题Your branch is behind ‘origin/dev‘by 2 commits,

git版本问题 一个不小心点击了版本的修改,于是就进入了翻滚中,回不来了 遇事还是不要慌,出现这个问题,如果那些你不需要,只是需要回到某一个版本,那么就是需要 git reset --hard origin/master 上面这就…