AutoCV第八课:3D基础

news2024/10/7 12:22:43

目录

  • 3D基础
    • 前言
    • 1. nuScenes数据集
    • 2. nuScenes数据格式
    • 3. 点云可视化
    • 总结

3D基础

前言

手写 AI 推出的全新保姆级从零手写自动驾驶 CV 课程,链接。记录下个人学习笔记,仅供自己参考。

本次课程主要学习点云数据的可视化。

课程大纲可看下面的思维导图。

在这里插入图片描述

1. nuScenes数据集

nuScenes 数据集是一种用于自动驾驶研究的大规模开放式数据集,其中包含了从多个传感器收集的高清三维激光雷达数据、高清摄像头数据、GPS 和 IMU 数据以及其它传感器等多种数据类型,总数据量达到了超过 1000 小时的行驶数据。各个传感器在车辆的具体位置可参考 图1-1(from chatGPT)

nuScenes 数据集由 nuTonomy 公司于 2019 年发布,后被 Aptiv 收购并维护。数据集中包含了超过 1000 个行驶场景,每个场景长度约为 20 秒,包括了各种驾驶情况,如城市、高速公路和居住区等场景

nuScenes 数据集中的传感器数据可以用于多种自动驾驶研究任务,如目标检测、语义分割、行为预测等。

关于 nuScenes 数据集更多的描述可见官网

nuScenes 官网:https://www.nuscenes.org/nuscenes?sceneId=scene-0100&frame=0&view=lidar

nuScenes 教程:https://www.nuscenes.org/nuimages#tutorial

nuScenes mini 数据集下载网盘链接:https://pan.baidu.com/s/1BNuDTDCN37rkWRYBdF8C7Q?pwd=yolo

在这里插入图片描述

图1-1 车辆传感器位置

2. nuScenes数据格式

本次我们使用 v1.0-mini 数据集来进行后续的学习工作,它是 nuScenes 数据集的一个子集,解压后包含以下五个文件:

1.maps

  • 包含有关城市街道的地图数据,包括道路、车道、交叉口、建筑物和树木等信息

2.samples

  • 包含有关车辆传感器数据的信息,如激光雷达、相机和毫米波雷达等一些样本数据
  • 相机数据是以图片的格式存储的,LiDAR 数据是以二进制的格式存储的,Radar 数据则是以 PCD 的格式进行存储的
  • PCD 全称 Point Cloud Data,是一种用于存储三维点云数据的文件格式。每个 .pcd 文件包含了 x、y、z 的三维坐标以及反射强度等信息
  • 后续点云数据的可视化是读取的 LiDAR_TOP 中的某一个二进制文件

3.sweeps

  • 包含了一系列车辆传感器数据的信息

4.v1.0-mini

  • 包含有关数据集中每个样本的元数据信息,如时间戳、旋转矩阵等。元数据以 JSON 格式存储

5.v1.0-mini.txt

  • 说明文档

3. 点云可视化

我们来对 LiDAR 的点云数据来进行可视化,其点云数据格式是一个二进制文件,其 shape 为 [n,5]

  • n 代表点云的数量
  • 5 分别代表 x、y、z、intensity、ring index
  • x、y、z 代表基于激光雷达的 3D 坐标
  • intensity 是反射强度,指的是激光接收器接受的反射次数,通常用于区分物体或地面
  • ring index:点所在激光雷达扫描线的编号,比如 32 线激光雷达,其值就为 1-32

示例代码如下:

import numpy as np
import cv2

file = "./data/n015-2018-11-21-19-38-26+0800__LIDAR_TOP__1542800855949460.pcd.bin"

# [x, y, z, intensity, ring index]
pc = np.frombuffer(open(file, "rb").read(), dtype=np.float32)
pc = pc.reshape(-1, 5)[:, :4]

x, y, z, intensity = pc.T

# 设置图像的尺寸1024x1024
image_size = 1024

# 数据归一化
# 点的坐标范围大概是100
pc_range = 100
x = x / pc_range    # [-1,1]
y = y / pc_range

# 缩放到图像大小,并平移到图像中心
half_image_size = image_size / 2
x = x * half_image_size + half_image_size
y = y * half_image_size + half_image_size

# opencv的图像,可以用numpy进行创建
image = np.zeros((image_size, image_size, 3), np.uint8)

for ix, iy, iz in zip(x, y, z):
    ix = int(ix)
    iy = int(iy)
    
    # 判断是否在图像范围内
    if ix >= 0 and ix < image_size and iy >= 0 and iy < image_size:
        
        image[iy, ix] = 255, 255, 255

cv2.imwrite("pointcloud.jpg", image)
cv2.imshow("image", image)
cv2.waitKey(0)

该示例代码主要是对 nuScenes 数据集中的激光雷达点云数据进行了可视化,具体流程如下:

  • 读取 nuScenes 数据集中的一个 .pcd.bin 文件,该文件中存储了激光雷达采集的点云数据。
  • 读取文件中的点云数据,并将其转换为 numpy 数组。
  • 解析 numpy 数组,得到点云数据中的 x, y, z, intensity 四个维度。
  • 由于点云数据的坐标值范围比较大,需要进行归一化操作。本代码采用将点云数据的范围缩放到 [-1, 1] 的方法进行归一化。
  • 缩放点云数据,并将其平移至图像中心。
  • 创建一个黑色的 1024x1024 的图像,并遍历所有点云数据中的点,将其所在位置的像素点设为白色。
  • 将生成的图像保存并显示

可视化图如下:

在这里插入图片描述

图3-1 激光雷达数据的二维可视化

我们可以考虑高度信息,绘制一张 3D 的点云图

  • 参考自:https://blog.csdn.net/Fzc_Ztt/article/details/116668330

示例代码如下:

import numpy as np
import mayavi.mlab

# pip install mayavi
# pip install pyqt5

# lidar_path换成自己的.bin文件路径
pointcloud2 = np.fromfile("./data/n015-2018-11-21-19-38-26+0800__LIDAR_TOP__1542800855949460.pcd.bin", dtype=np.float32, count=-1).reshape([-1, 4])
 
# 提取点云坐标和反射强度
x = pointcloud2[:, 0]  # x position of point
y = pointcloud2[:, 1]  # y position of point
z = pointcloud2[:, 2]  # z position of point
r = pointcloud2[:, 3]  # reflectance value of point

# 计算点云距离和高度角
d = np.sqrt(x ** 2 + y ** 2)  # Map Distance from sensor 
degr = np.degrees(np.arctan(z / d))

# 设置颜色
vals = 'height'
if vals == "height":
    col = z
else:
    col = d

# 可视化点云数据
fig = mayavi.mlab.figure(bgcolor=(0,0,0),size=(640, 500))
mayavi.mlab.points3d(x, y, z,
                     col,  # Values used for Color
                     mode="point",
                     colormap='spectral',  # 'bone', 'copper', 'gnuplot'
                     # color=(0, 1, 0),   # Used a fixed (r,g,b) instead
                     figure=fig,
                     )
 
mayavi.mlab.show()

上述示例代码使用了 numpy 和 mayavi 库,用于读取并解析激光雷达二进制数据,然后将点云数据可视化为 3D 效果图。首先从二进制数据中提取点的 x、y、z 坐标和反射强度,然后计算出每个点到传感器的距离,最后根据距离或高度值对点进行着色,并使用 mayavi 的 point3d() 函数将点云可视化出来。通过设置不同的参数,可以调整点云的颜色、大小和透明度等属性。最后使用 mayavi 的 show() 函数显示 3D 效果图

可视化图如下:

在这里插入图片描述

图3-2 激光雷达数据的三维可视化

我们还可以将不同视角的图片进行保存,然后利用 imageio 模块绘制动态图

示例代码如下:(from chatGPT)

import numpy as np
import mayavi.mlab as mlab
import os
import imageio


# 读取点云数据
pointcloud = np.fromfile('./data/n015-2018-11-21-19-38-26+0800__LIDAR_TOP__1542800855949460.pcd.bin', dtype=np.float32, count=-1).reshape([-1, 4])

# 提取点云坐标和反射强度
x = pointcloud[:, 0]
y = pointcloud[:, 1]
z = pointcloud[:, 2]
r = pointcloud[:, 3]

# 创建 mayavi 场景
fig = mlab.figure(bgcolor=(0,0,0), size=(800, 600))

# 绘制点云
points = mlab.points3d(x, y, z, r, mode='point', colormap='spectral')

# 设置相机位置和视角
mlab.view(azimuth=0, elevation=90, distance=500, focalpoint=[0,0,0])
mlab.move(forward=-100)

# 创建保存点云数据的文件夹
if not os.path.exists('./lidar_images'):
    os.makedirs('./lidar_images')

# 保存不同视角的点云数据到文件夹
for i in range(36):
    mlab.view(azimuth=i*10, focalpoint=[0,0,0])
    mlab.move(forward=-20)
    mlab.savefig('./lidar_images/lidar_view_{}.png'.format(i))

# # 文件夹路径
folder_path = './lidar_images/'

# 获取文件夹下的所有图片路径
image_paths = sorted([os.path.join(folder_path, f) for f in os.listdir(folder_path) if f.endswith('.png')])

# 读取所有图片并保存到列表中
images = []
for image_path in image_paths:
    images.append(imageio.imread(image_path))

# 将所有图片合成为一张动态图
imageio.mimsave('./lidar.gif', images, fps=9)

可视化图如下所示,效果并不是很好,凑合看吧😂

在这里插入图片描述

图3-3 激光雷达数据的不同视角图

顺便想看看毫米波雷达的点云数据,但是其数据格式不是很清楚,就没去折腾解析工作了,主要是通过工具 pcl-tools 来查看的

首先安装 pcl-tools 库

sudo apt-get install pcl-tools

然后运行对应的毫米波雷达的 pcd 数据就行

pcl_viewer xxx.pcd

可视化效果如下:

在这里插入图片描述

图3-4 毫米波雷达数据的可视化

好像没啥好看的,就一堆点,而且相比于激光雷达来说点云非常稀疏

毫米波雷达是通过发送一束毫米波,利用物体对毫米波的反射来确定物体的位置。它可以探测物体的反射并测量反射的时间和强度,从而确定物体的距离、角度和速度等信息。毫米波雷达的点云密度相对较低,需要更多的数据处理和算法优化来进行点云重建和应用。

总结

本次课程为 3D 基础,主要了解了 nuScenes 数据集,并了解了其中的激光雷达传感器采集到的数据格式,其 shape 为 [n,5],其中 n 为采集到的点云数量,5 个维度分别代表 x、y、z、intensity、ring index,利用 numpy 数据库对激光雷达的数据进行了解析,并利用 opencv、mayavi、imageio 等库对点云进行了可视化,整体效果还是比较 OK 的。

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

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

相关文章

【Shiro】SimpleAuthenticationInfo如何验证password

一、前言 通篇的关键就是知道ShiroRealm类重写的doGetAuthenticationInfo这个方法&#xff0c;到底是谁的方法。 从上图我们可以知道&#xff0c;ShiroRealm最终继承到了AuthenticatingRealm这个方法。 二、自定义的ShiroRealm类 ps&#xff1a;该图中①上的注释是没看过底…

Jetpack之livedata原理

1.LiveData是什么&#xff1f; 只有在生命周期处于started和resumed时。livedata才会更新观察者 2.Livedata的各种使用方式 1.更新数据 class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceSta…

c++之函数对象和谓词

目录 函数对象&#xff1a; 谓词&#xff1a; 一元谓词函数举例如下 二元谓词举例如下 函数对象和函数的区别 一元谓词的案例 二元函数对象案例 二元谓词案例 函数对象&#xff1a; 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff08;function obj…

内网渗透之linux到linux横向移动-ssh

0x01 一般情况下SSH密钥存放在~/.ssh/目录下&#xff0c;也可以文件中搜索已保存的SSH凭证 ~/.ssh/config ~/.ssh/known_hosts ~/.bash_history grep -ir "BEGIN RSA PRIVATE KEY" /* grep -ir "BEGIN DSA PRIVATE KEY" /* grep -ir "BEGIN OPENSSH…

SpringBoot入门学习笔记-快速认识

SpringBoot入门学习笔记-快速认识 快速案例入门案例解析parentstarter引导类内嵌tomcat ) 快速案例 在controller定义一个类 package com.ustc.sp5.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.…

redis 数据类型简介

redis 数据类型 redis的五种数据类型是&#xff1a;1、string&#xff08;字符串&#xff09;&#xff1b;2、hash&#xff08;哈希&#xff09;&#xff1b;3、list&#xff08;列表&#xff09;&#xff1b;4、set&#xff08;集合&#xff09;&#xff1b;5、sort set &…

QT初体验:手把手带你写一个自己的串口助手

前言 本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程&#xff0c;整个工程只有几百行代码&#xff0c;跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法。对新手学习QT能增强信心&#xff0c;话不多说&#xff0c;正文开始 先看…

Mysql日志redo log、bin log、undo log 区别与作用及二阶段提交

一、redo log 重做日志 作用&#xff1a;确保事务的持久性。防止在发生故障的时间点&#xff0c;尚有脏页未写入磁盘&#xff0c;在重启mysql服务的时候&#xff0c;根据redo log进行重做&#xff0c;从而达到事务的持久性这一特性。 内容&#xff1a;物理格式的日志&#x…

46-Dockerfile-USER/WORKDIR指令

USER/WORKDIR指令 前言USER作用格式使用示例 WORKDIR作用格式说明使用示例 前言 本篇来学习下Dockerfile中的USER/WORKDIR指令 USER 作用 指定运行容器时的用户名或 UID&#xff0c;后续的RUN等指令也会使用指定的用户身份 说明&#xff1a; USER 只是帮助我们切换到指定的…

12_Uboot启动流程_4

目录 images全局变量 do_bootz函数 bootz_start函数 do_bootm_states函数 bootm_os_get_boot_func函数 do_bootm_linux函数 images全局变量 不管是bootz还是bootm命令,在启动Linux内核的时候都会用到一个重要的全局变量:images, images在文件cmd/bootm.c中有如下定义: i…

【2023/05/09】Scratch

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第4天。 Share The mighty desert is burning for the love of a blade of grass who shaks her head and laughs and flies away. 译文&#xff1a; 无垠的沙漠热烈追求一叶绿草的爱&#xff0c;她摇摇…

PCL中点云分割算法简析

文章目录 前言一、点云分割算法简介1.1 基于RANSAC的点云分割1.2 基于聚类的点云分割1.2.1 欧式聚类分割 1.3 基于深度学习的点云分割 二、算法示例2.1 基于RANSAC的平面分割2.2 欧式聚类2.3 基于PointNet的点云分割 总结 前言 点云分割算法广泛应用于激光遥感、无人驾驶、工业…

centos安装nginx教程

安装所需环境 Nginx 是 C语言 开发&#xff0c;建议在 Linux 上运行&#xff0c;当然&#xff0c;也可以安装 Windows 版本&#xff0c;本篇则使用 CentOS 7 作为安装环境。 一. gcc 安装 安装 nginx 需要先将官网下载的源码进行编译&#xff0c;编译依赖 gcc 环境&#xff0c…

【ESD专题】案例:TVS管钳位电压能不能通过TLP测试数据表征?

这几天遇到一个问题,就是还是想说TVS管导入的时候需要进行IEC61000-4-2 8kV接触静电的钳位波形测试。 比如有时可以看到规格书中给出对应的在IEC61000-4-2 8kV接触时的真实钳位波形: 根据我们文章【ESD专题】TVS管的选择的误区及钳位电压测试方法和一些参考手册所说…

计算机操作系统第四版第七章文件管理—课后习题答案

1.何谓数据项、记录和文件&#xff1f; 数据项&#xff1a;是最低级的数据组织形式&#xff0c;可以分为两种类型&#xff1a;基本数据项和组合数据项。基本数据项是用于描述一个对象的某种属性的字符集&#xff0c;是数据组织中可以命名的最小逻辑数据单位&#xff0c;又称为字…

使用volta对node版本进行控制

安装volta 首先下载volta 下载完成之后在电脑上使用命令行工具查看是否安装成功 volta -v 使用 volta -h 命令可以查看volta的一些用法 安装全局的node版本,可以有三种,第一种是安装最新的,第二种是安装某一个大版本下的,第三种是安装指定的node版本(安装的时候需要等待一段时…

Rest风格复习

Rest风格复习 简介三种注解的风格快速开发 简介 通过一段路径和访问方式来确定访问资源的行为方式 使用POST方式 // value定义 路径 method定义访问的方式RequestMapping(value "/users",method RequestMethod.POST)ResponseBodypublic String save(){System.out.…

Andrew Ng和OpenAI教你写prompt

课程地址&#xff1a; https://learn.deeplearning.ai/chatgpt-prompt-engb站搬运&#xff1a; https://www.bilibili.com/video/BV1No4y1t7Zn 教学人员&#xff1a;Lsa Fulford&#xff0c; Andrew NG LLM的两种样式 Base LLM:基于文本训练数据预测下一个词的概率&#xff0…

制作Alpine Linux镜像报错errors: 15 distinct packages available

1.执行报错 执行docker build -t 镜像:版本 -f Dockerfile . 报错&#xff1a; 2.查看网上的解决思路 网上文档解决思路&#xff1a; 这边我做了一下改变把这些写入了dockerfile 加了几个RUN RUN rm -rf /var/cache/apk RUN mkdir -p /var/cache/apk RUN apk update -v 发现还…

Java基本数据类型详解及应用示例

Java作为一门强类型语言&#xff0c;基本数据类型是非常重要的概念。Java中基本数据类型分为四种类别&#xff1a;整数类型、浮点数类型、字符类型和布尔类型。其中&#xff0c;每一种数据类型都有着不同的占用字节数和表示范围&#xff0c;合理使用选择不同的数据类型可以提高…