点云3D 目标检测
点云
点云是雷达采集到的信息.
关于点云基本介绍参考https://zhuanlan.zhihu.com/p/22581673
ros中的点云消息结构:http://docs.ros.org/jade/api/sensor_msgs/html/msg/PointCloud2.html
# This message holds a collection of N-dimensional points, which may
# contain additional information such as normals, intensity, etc. The
# point data is stored as a binary blob, its layout described by the
# contents of the "fields" array.
# The point cloud data may be organized 2d (image-like) or 1d
# (unordered). Point clouds organized as 2d images may be produced by
# camera depth sensors such as stereo or time-of-flight.
# Time of sensor data acquisition, and the coordinate frame ID (for 3d
# points).
Header header
# 2D structure of the point cloud. If the cloud is unordered, height is
# 1 and width is the length of the point cloud.
uint32 height
uint32 width
# Describes the channels and their layout in the binary data blob.
PointField[] fields
bool is_bigendian # Is this data bigendian?
uint32 point_step # Length of a point in bytes
uint32 row_step # Length of a row in bytes
uint8[] data # Actual point data, size is (row_step*height)
bool is_dense # True if there are no invalid points
PointField结构:http://docs.ros.org/melodic/api/sensor_msgs/html/msg/PointField.html
# This message holds the description of one point entry in the
# PointCloud2 message format.
uint8 INT8 = 1
uint8 UINT8 = 2
uint8 INT16 = 3
uint8 UINT16 = 4
uint8 INT32 = 5
uint8 UINT32 = 6
uint8 FLOAT32 = 7
uint8 FLOAT64 = 8
string name # Name of field
uint32 offset # Offset from start of point struct
uint8 datatype # Datatype enumeration, see above
uint32 count # How many elements in the field
点云消息数据存储在PointCloud2.data中.
示例:
header: // 点云的头信息
seq: 963 //
stamp: // 时间戳
secs: 1541143772
nsecs: 912011000
frame_id: "/camera_init"
height: 1 // If the cloud is unordered, height is 1 如果cloud 是无序的 height 是 1
width: 852578 //点云的长度
fields: // sensor_msgs/PointField[] fields
-
name: "x"
offset: 0
datatype: 7 // uint8 INT8 = 1
// uint8 UINT8 = 2
// uint8 INT16 = 3
// uint8 UINT16 = 4
// uint8 INT32 = 5
// uint8 UINT32 = 6
// uint8 FLOAT32 = 7
// uint8 FLOAT64 = 8
count: 1
-
name: "y"
offset: 4
datatype: 7
count: 1
-
name: "z"
offset: 8
datatype: 7
count: 1
-
name: "intensity"
offset: 16
datatype: 7
count: 1
is_bigendian: False
point_step: 32 // Length of a point in bytes 一个点占的字节数
row_step: 27282496 // Length of a row in bytes 一行的长度占用的字节数
data: [ .......................................................... ] // Actual point data, size is (row_step*height)
is_dense: True // 没有非法数据点
datatype=7对应的类型为PointField.FLOAT32,size为4.x/y/z的偏移都是正常的.为什么intensity的offset变成了16而不是12呢?ros在包装PointCloud2的时候可能在PointField之间添加了一些额外信息,这点我们在处理的时候要注意一下.同理还有Point与Point之间也可能有额外的信息.
点云rosbag转numpy
参考https://gist.github.com/bigsnarfdude/eeb156dc7b4caca69f5b31037da54708
我们想将PointCloud2格式的msg转换为numpy的矩阵格式.即转换成m行n列,每一列即为x,y,z,intensity...
首先我们希望对msg.data做反序列化处理,即
def msg_to_arr(msg):
arr = np.fromstring(msg.data, dtype_list)
现在问题变成了如何从点云的datatype转到numpy的datatype
DUMMY_FIELD_PREFIX = '__'
# mappings between PointField types and numpy types
type_mappings = [(PointField.INT8, np.dtype('int8')), (PointField.UINT8, np.dtype('uint8')), (PointField.INT16, np.dtype('int16')),
(PointField.UINT16, np.dtype('uint16')), (PointField.INT32, np.dtype('int32')), (PointField.UINT32, np.dtype('uint32')),
(PointField.FLOAT32, np.dtype('float32')), (PointField.FLOAT64, np.dtype('float64'))]
pftype_to_nptype = dict(type_mappings)
nptype_to_pftype = dict((nptype, pftype) for pftype, nptype in type_mappings)
# sizes (in bytes) of PointField types
pftype_sizes = {PointField.INT8: 1, PointField.UINT8: 1, PointField.INT16: 2, PointField.UINT16: 2,
PointField.INT32: 4, PointField.UINT32: 4, PointField.FLOAT32: 4, PointField.FLOAT64: 8}
def fields_to_dtype(fields, point_step):
'''
Convert a list of PointFields to a numpy record datatype.
'''
offset = 0
np_dtype_list = []
for f in fields:
while offset < f.offset:
# might be extra padding between fields
np_dtype_list.append(('%s%d' % (DUMMY_FIELD_PREFIX, offset), np.uint8))
offset += 1
dtype = pftype_to_nptype[f.datatype]
if f.count != 1:
dtype = np.dtype((dtype, f.count))
np_dtype_list.append((f.name, dtype))
offset += pftype_sizes[f.datatype] * f.count
# might be extra padding between points
while offset < point_step:
np_dtype_list.append(('%s%d' % (DUMMY_FIELD_PREFIX, offset), np.uint8))
offset += 1
return np_dtype_list
代码逻辑很清楚,pftype_to_nptype和nptype_to_pftype定义了点云消息中数据结构和numpy中数据结构的映射关系.
唯一需要注意的就是前面提到过的ros在包装PointCloud2的时候可能在PointField之间添加了一些额外信息,这点我们在处理的时候要注意一下.同理还有Point与Point之间也可能有额外的信息. 代码里的
while offset < f.offset:
# might be extra padding between fields
np_dtype_list.append(('%s%d' % (DUMMY_FIELD_PREFIX, offset), np.uint8))
offset += 1
# might be extra padding between points
while offset < point_step:
np_dtype_list.append(('%s%d' % (DUMMY_FIELD_PREFIX, offset), np.uint8))
offset += 1
就是为了处理上述问题.
复现点云检测模型SqueezeSeg检测点云数据
https://blog.csdn.net/AdamShan/article/details/83544089
原文用的py2.7,复现的时候遇到了很多问题
- conda activate env2.7
- pip install tensorflow
- pip install easydict
- pip install joblib
直接运行squeezeseg_ros_node.py的时候会报如下错误.
错误代码的意思是出错于读launch文件.
npy_path = rospy.get_param('npy_path')
这一句会读launch文件中的配置.
在执行了roslaunch squeezeseg_ros squeeze_seg_ros.launch之后,会报错
这之后再执行python squeezeseg_ros_node.py就可以正常运行了.
点云3D 目标检测的更多相关文章
- ICCV2019论文点评:3D Object Detect疏密度点云三维目标检测
ICCV2019论文点评:3D Object Detect疏密度点云三维目标检测 STD: Sparse-to-Dense 3D Object Detector for Point Cloud 论文链 ...
- CVPR2020|3D-VID:基于LiDar Video信息的3D目标检测框架
作者:蒋天园 Date:2020-04-18 来源:3D-VID:基于LiDar Video信息的3D目标检测框架|CVPR2020 Brief paper地址:https://arxiv.org/p ...
- CVPR2019:无人驾驶3D目标检测论文点评
CVPR2019:无人驾驶3D目标检测论文点评 重读CVPR2019的文章,现在对以下文章进行点评. Stereo R-CNN based 3D Object Detection for Autono ...
- CVPR2020论文介绍: 3D 目标检测高效算法
CVPR2020论文介绍: 3D 目标检测高效算法 CVPR 2020: Structure Aware Single-Stage 3D Object Detection from Point Clo ...
- 3D目标检测(CVPR2020:Lidar)
3D目标检测(CVPR2020:Lidar) LiDAR-Based Online 3D Video Object Detection With Graph-Based Message Passing ...
- 点云3d检测模型pointpillar
PointPillars 一个来自工业界的模型.https://arxiv.org/abs/1812.05784 3D目标检测通常做法 3d卷积 投影到前平面 在bird-view上操作 处理思路依然 ...
- 三维目标检测论文阅读:Deep Continuous Fusion for Multi-Sensor 3D Object Detection
题目:Deep Continuous Fusion for Multi-Sensor 3D Object Detection 来自:Uber: Ming Liang Note: 没有代码,主要看思想吧 ...
- CVPR2020:利用图像投票增强点云中的三维目标检测(ImVoteNet)
CVPR2020:利用图像投票增强点云中的三维目标检测(ImVoteNet) ImVoteNet: Boosting 3D Object Detection in Point Clouds With ...
- Faster R-CNN:详解目标检测的实现过程
本文详细解释了 Faster R-CNN 的网络架构和工作流,一步步带领读者理解目标检测的工作原理,作者本人也提供了 Luminoth 实现,供大家参考. Luminoth 实现:https:// ...
随机推荐
- Java面试,如何在短时间内做突击
面试前很有必要针对性的多刷题,大部分童鞋实战能力强,理论不行,面试前不做准备很吃亏.这里整理了很多常考面试题,希望对你有帮助. 面试技术文 Java岗 面试考点精讲(基础篇01期) Java岗 面 ...
- 【nodejs原理&源码赏析(4)】深度剖析cluster模块源码与node.js多进程(上)
目录 一. 概述 二. 线程与进程 三. cluster模块源码解析 3.1 起步 3.2 入口 3.3 主进程模块master.js 3.4 子进程模块child.js 四. 小结 示例代码托管在: ...
- git如何合并远程2个分支
1,先检出项目到一个文件夹git clone 2,你检出的项目默认是master,所以现在要查看远程全部分支git branch -a * master remotes/origin/HEAD -&g ...
- tableView代理方法执行顺序
tableView代理方法执行顺序,随着iOS系统版本的不断升级,执行顺序也有所变化 1.iOS7.1中先依次调一遍heightForRow方法再依次调一遍cellForRow方法,在调cellFor ...
- 框架用多了真的会死人的,spring-cloud全家桶与mybitais 集成完整示例(附下载)
题外话: 看到这一长串包含各种技术名词的标题,一路走来感觉研发深深的被各种框架给绑架了,从我们刚出生最简单的jsp,servlet打天下,到spring mvc的盛行,再到现在spring-boo ...
- RDIFramework.NET敏捷开发框架WinForm新增文件中心-实现附件集中管理
1.引言 文件中心类似附件管理是一个非常实用功能,可以归档自己平时所需要的文件,也可以把文件分享给别人,更像一个知识中心.文件中心主界面如下图所示,左侧"附件分类"展示了用户对文件 ...
- Oracle impdp导入数据临时表空间与undo表空间爆满解决实例
Oracle impdp导入数据临时表空间与undo表空间爆满解决实例 [日期:2018-01-24] 来源:Linux社区 作者:rangle [字体:大 中 小] 针对Oracle数据迁移, ...
- 使用VS Code开发纸壳CMS自动编译主题压缩CSS,JS
Visual Studio Code (简称 VS Code / VSC) 是一款免费开源的现代化轻量级代码编辑器,支持语法高亮.智能代码补全.自定义热键.括号匹配.代码片段.代码对比 Diff.GI ...
- tornado的IOLoop.instance()方法和IOLoop.current()方法区别
在使用tornado时,经常有人疑惑IOLoop.instance()方法和IOLoop.current()方法的区别是什么. IOLoop.instance() 返回一个全局 IOLoop实例. 大 ...
- mysql五大引擎的区别和优劣之分
数据库引擎介绍 MySQL数据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引擎:ISAM.MYISAM和HEAP.另 ...