ROS 将kitti图像的目标检测2D检测框画出来,并用rviz显示。_cv2.imread读取的kitti的图片没有shape-程序员宅基地

技术标签: rviz  自动驾驶  ros  ROS学习笔记  kitti  

这节细节有点多,下面只是粗略的实现,还有很多细节还在完善中(2022.10.03)!!!

  ROS 将kitti图像的目标检测2D检测框画出来,并用rviz显示,效果如下:
在这里插入图片描述

前文,我们已经讲kitti的图像进行发布,并用rviz显示,所以本文只将2D的检测框画出来即可。

将kitti图像的目标检测2D检测框画出来,并用rviz显示

1.准备数据

2.读取数据

2.1data_utils.py中添加的内容

在data_utils.py中添加读取标签数据的代码

import pandas as pd

COLUMN_NAMES=['frame','track_id','type',
'truncated','occluded','alpha',
'bbox_left','bbox_top','bbox_right','bbox_bottom',
'height','width','length','pos_x','pos_y','pos_z','rot_y']

def read_tracking(path):
    df=pd.read_csv(path,header=None,sep=' ')
    df.columns=COLUMN_NAMES
    df.loc[df.type.isin(['Truck','Van','Tram']),'type']='Car'
    df=df[df.type.isin(['Car','Pedestrian','Cyclist'])]
    return df

2.2标签数据解释

  我们用jupyter notebook加载数据,对数据进行逐一的解释。

  1. 首先是加载功能包
import numpy as np
import pandas as pd
  1. 读取数据,并给每一列起一个名字
COLUMN_NAMES=['frame','track_id','type',
'truncated','occluded','alpha',
'bbox_left','bbox_top','bbox_right','bbox_bottom',
'height','width','length','pos_x','pos_y','pos_z','rot_y']

df=pd.read_csv("/home/chen/Downloads/kittidata/2011_09_26/2011_09_26_drive_0005_sync/training/label_02/0000.txt",header=None,sep=' ')
df.columns=COLUMN_NAMES
df.head()

  其中2011_09_26/2011_09_26_drive_0005_sync/training/label_02/0000.txt"是我们要用到的标签数据;关于COLUMN_NAMES中每一项的详细解释,可以参考这篇文章
在这里插入图片描述

  我们只对关键数据进行解释。frame是当前检测到的物体属于的帧数;type是该物体的类型,包含有:'Car', 'Van', 'Truck', 'Pedestrian', 'Person_sitting', 'Cyclist', 'Tram', 'Misc' or 'DontCare''bbox_left','bbox_top','bbox_right','bbox_bottom'是2D包围框的信息。

在这里插入图片描述

  1. 将各类机动车都合并,归为一类Car
df.loc[df.type.isin(['Truck','Van','Tram']),'type']='Car'
df=df[df.type.isin(['Car','Pedestrian','Cyclist'])]
  1. 获取某一各物体的2D检测框
box=np.array(df.loc[2,['bbox_left','bbox_top','bbox_right','bbox_bottom']])
  1. 读取一张图片,并画出2D检测框
DETECTION_COLOR_DATA={
    'Car':(255,255,0),'Pedestrian':(0,226,255),'Cyclist':(141,40,255)}
frame=120

image=cv2.imread('/home/chen/Downloads/kittidata/2011_09_26/2011_09_26_drive_0005_sync/image_02/data/%010d.png'%frame)


boxes=np.array(df[df["frame"]==frame][['bbox_left','bbox_top','bbox_right','bbox_bottom']])
types=np.array(df[df["frame"]==frame]['type'])

for typ,box in list(zip(types,boxes)):
    top_left=int(box[0]),int(box[1])
    bottom_right=int(box[2]),int(box[3])
    cv2.rectangle(image,top_left,bottom_right,DETECTION_COLOR_DATA[typ],2)
    
    
cv2.imshow("image",image)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

3.发布数据

def publish_3dbox(box3d_pub,corner_3d_velos,object_type):
    marker_array=MarkerArray()
    for i, corners_3d_velo in enumerate(corner_3d_velos):
        marker=Marker()
        marker.header.frame_id=FRAME_ID
        marker.header.stamp=rospy.Time.now()

        marker.id=i
        marker.action=Marker.ADD
        marker.lifetime=rospy.Duration(LIFETIME)
        marker.type=Marker.LINE_STRIP
        b,g,r=DETECTION_COLOR_DATA[object_type[i]]

        marker.color.r=r/255.0
        marker.color.g=g/255.0
        marker.color.b=b/255.0

        marker.color.a=1.0

        marker.scale.x=0.1

        marker.points=[]
        for l in LINES:
            p1=corners_3d_velo[l[0]]
            marker.points.append(Point(p1[0],p1[1],p1[2]))
            p2=corners_3d_velo[l[1]]
            marker.points.append(Point(p2[0],p2[1],p2[2]))
        marker_array.markers.append(marker)

    box3d_pub.publish(marker_array)

4.发布节点

#!/usr/bin/env python

import os

from data_utils import *
from publish_utils import *
from kitti_utils import *


DATA_PATH='/home/chen/Downloads/kittidata/2011_09_26/2011_09_26_drive_0005_sync/'
TRACKING_DATA_PATH="/home/chen/Downloads/kittidata/2011_09_26/2011_09_26_drive_0005_sync/training/label_02/0000.txt"

def compute_3d_box_cam2(h,w,l,x,y,z,yaw):
    """
    Return : 3xn in cam2 coordinate
    """
    R=np.array([[np.cos(yaw),0,np.sin(yaw)],[0,1,0],[-np.sin(yaw),0,np.cos(yaw)]])
    x_corners=[ l/2, l/2,-l/2,-l/2,
                l/2, l/2,-l/2,-l/2]
    y_corners=[0,0,0,0,-h,-h,-h,-h]
    z_corners=[ w/2,-w/2,-w/2, w/2,
                w/2,-w/2,-w/2, w/2,]
    corners_3d_cam2=np.dot(R,np.vstack([x_corners,y_corners,z_corners]))
    corners_3d_cam2+=np.vstack([x,y,z])
    return corners_3d_cam2

if __name__=='__main__':
    rospy.init_node('kitti_node',anonymous=True)
    cam_pub=rospy.Publisher('kitti_cam',Image,queue_size=10)
    pcl_pub=rospy.Publisher('kitti_pcl',PointCloud2,queue_size=10)
    ego_pub=rospy.Publisher('kitti_ego_car',MarkerArray,queue_size=10)
    imu_pub=rospy.Publisher('kitti_imu',Imu,queue_size=10)
    gps_pub=rospy.Publisher('kitti_gps',NavSatFix,queue_size=10)
    box3d_pub=rospy.Publisher('kitti_box3d',MarkerArray,queue_size=10)
    bridge=CvBridge()
    rate=rospy.Rate(10)

    df_tracking=read_tracking(TRACKING_DATA_PATH)
    calib=Calibration('/home/chen/Downloads/kittidata/2011_09_26',from_video=True)

    frame=0

    while not rospy.is_shutdown():
        df_tracking_frame=df_tracking[df_tracking["frame"]==frame]

        img=read_camera(os.path.join(DATA_PATH,'image_02/data/%010d.png'%frame))
        pcl=read_point_cloud(os.path.join(DATA_PATH,'velodyne_points/data/%010d.bin'%frame))
        imu=read_imu(os.path.join(DATA_PATH,'oxts/data/%010d.txt'%frame))
        boxes_2d=np.array(df_tracking[df_tracking["frame"]==frame][['bbox_left','bbox_top','bbox_right','bbox_bottom']])
        types=np.array(df_tracking[df_tracking["frame"]==frame]['type'])
        boxes_3d=np.array(df_tracking_frame[['height','width','length','pos_x','pos_y','pos_z','rot_y']])

        corners_3d_velos=[]
        for box_3d in boxes_3d:
            corners_3d_cam2=compute_3d_box_cam2(*box_3d)
            corners_3d_velo=calib.project_rect_to_velo(corners_3d_cam2.T)
            corners_3d_velos+=[corners_3d_velo]

        publish_camera(cam_pub,bridge,img,boxes_2d,types)
        publish_pcl(pcl_pub,pcl)
        publish_ego_car(ego_pub)
        publish_imu(imu_pub,imu)
        publish_gps(gps_pub,imu)
        publish_3dbox(box3d_pub,corners_3d_velos,types)



        rospy.loginfo('published')
        rate.sleep()
        frame+=1
        frame%=154
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39400324/article/details/127156867

智能推荐

学习C++的第一步,环境搭建:Visual Studio的安装和创建C++项目_visual studio c++安装教程-程序员宅基地

文章浏览阅读9.7k次,点赞8次,收藏39次。无论学习任何语言,首先要有编译环境,这里介绍Visual Studio的安装和使用,作为后面C++学习的环境。当然,除了Visual Studio,还有qtcreater、vscode等IDE可以使用,可以根据自己的喜欢安装对应的软件。下面对Visual Studio的安装进行一个详细说明,对具体版本没有限制。_visual studio c++安装教程

有关SAP中等于空的问题_sap 固定值 為空-程序员宅基地

文章浏览阅读2.1k次。20.17. 表字段初始值、NULL等问题20.17.1. SE11表设置中的Initial Values如果一个表是新创建的,数据库中的所有字段都会被设计成非NULL,此时与钩不钩上“Initial Values”框没有关系,且都会设置默认值,并且所有的主键都会强制将“Initial Values”框钩上该标示只在修改表结构且在现有表结构增加一个字段时,才起..._sap 固定值 為空

[C/C++ -STL]vector底层实现机制刨析-程序员宅基地

文章浏览阅读7.2k次,点赞17次,收藏30次。一、vector底层实现机制刨析通过分析 vector 容器的源代码不难发现,它就是使用 3 个迭代器(可以理解成指针)来表示的:其中statrt指向vector 容器对象的起始字节位置;finish指向当前最后一个元素的末尾字节end_of指向整个 vector 容器所占用内存空间的末尾字节。如图 演示了以上这 3 个迭代器分别指向的位置如图 演示了以上这 2个迭代器分别指向的位置在此基础上,将 3 个迭代器两两结合,还可以表达不同的含义,例如:start 和 finish 可以用来表_vector底层实现

搭建5个节点的hadoop集群环境(CDH5)-程序员宅基地

文章浏览阅读1.9k次。提示:如果还不了解Hadoop的,可以下查看这篇文章Hadoop生态系统,通过这篇文章,我们可以首先大致了解Hadoop及Hadoop的生态系统中的工具的使用场景。搭建一个分布式的hadoop集群环境,下面是详细步骤,使用cdh5 。一、硬件准备基本配置:操作系统64位CPU(英特尔)Intel(R_cdh5

fxfactory卸载不干净?Fxfactory及插件卸载教程_fxfacory的插件有时候能用有时候用不了-程序员宅基地

文章浏览阅读432次。fxfactory是一款非常受欢迎的视频特效插件合集,能应用到FCPX、AE、PR、motion等软件中。过多特效插件下载会导致这些软件运行打开速度慢,那么如何卸载fxfactory这款软件或者删除那些特效插件呢?跟随小编一起来看看吧!fxfactory中插件删除教程打开fxfactory 软件,在Installed处找到已经安装过的插件,比如安装好的Caption Burner插件去掉勾选,插件颜色变黑白即可运行FCPX、AE、PR、motion等软件,Caption Burner就不会出现了,影响软件_fxfacory的插件有时候能用有时候用不了

Windows系统设置每天自动备份指定文件并自动删除七天前的文件(脚本+Windows任务计划)_ms-dos七天自动删除-程序员宅基地

文章浏览阅读8.3k次,点赞8次,收藏41次。Windows系统设置每天自动备份指定文件并自动删除七天前的文件(脚本+Windows任务计划)在生活中和工作中有时候为了避免电脑宕机导致文件丢失常常会使用一些方式去备份文件,今天小编给大家介绍一个方法,用于自动备份指定文件,并删除N天前的文件。_ms-dos七天自动删除

随便推点

【信息系统项目管理师】高项知识框架--考点大汇总_高项管师章节重点知识归纳-程序员宅基地

文章浏览阅读5.9k次,点赞10次,收藏72次。【信息系统项目管理师】高项知识框架–考点大汇总_高项管师章节重点知识归纳

ASP.NET网站制作-程序员宅基地

文章浏览阅读6.4k次,点赞3次,收藏28次。ASP.NET网站制作1、ASP.NET页面对象1网页脚本当客户端通过客户浏览器发送HTTP请求时,web服务器将HTML文档部分和脚本部分返回给客户端浏览器,在客户端浏览器中解释执行并及时更新页面,脚本处理工作全部在客户端浏览器执行完成。优点: 减轻服务器负荷,同时增加页面的反应速度。缺点:浏览器差异性导致页面差异支持的语言: JavaScriptJScript VBScript(2)服务端脚本..._asp.net网站制作

车载 OTA技术概念_sota和ota的区别?-程序员宅基地

文章浏览阅读3k次,点赞10次,收藏54次。总的来说,OTA实现方案分为两种,一种与通常的刷写方式一样,即先擦除当前版本软件,再刷写新版本软件,但这种方法有个隐患,就是新软件有问题时,由于旧软件已经被擦除,没有备份,恢复会很麻烦,因此就提出了另一种,即A/B交换。(Firmware-Over-the-Air),是指不改变车辆原有配件的前提下,通过写入新的固件程序,使拥有联网功能的设备进行升级,包括车辆的发动机,电机,变速箱,底盘等控制系统,比如特斯拉曾通过FOTA新增过自动驾驶功能、增加过电池容量和改善过刹车距离等。,那都将是一项很繁重的任务。_sota和ota的区别?

清空数据库的方法_548数据库清库-程序员宅基地

文章浏览阅读744次。近来发现数据库过大,空间不足,因此打算将数据库的数据进行全面的清理,但表非常多,一张一张的清空,实在麻烦,因此就想利用SQL语句一次清空所有数据.找到了三种方法进行清空.使用的数据库为MS SQL SERVER.1.搜索出所有表名,构造为一条SQL语句declare @trun_name varchar(8000)set @trun_name=''select_548数据库清库

STL --- 四、算法 Algorithms_c++ algorithms-程序员宅基地

STL中的算法提供了丰富的功能,包括常用算法介绍和时间、空间复杂度的选择。在编写程序时需根据具体问题选择适当的算法,满足时间或空间需求。

【计算机网络学习笔记04】网络体系架构与网络协议_网络体系以及网络协议的定义和内容。-程序员宅基地

文章浏览阅读1.4w次。【计算机网络学习笔记04】网络体系架构与网络协议一、网络协议的概念和要素网络协议是计算机网络相互通信的对等层实体之间,用来交换信息时必须遵守的规则或约定的集合。这些为网络数据交换而制定的通信规则、约定与标准被统称为网络协议,简称协议。网络协议主要由三个基本要素组成,分别是语法、语义和时序。语法:用于定义数据和控制信息的结构或格式。语义:用于解释数据或控制信息的具体含义。时序(同步):用于对事件实现顺序的详细说明。二、计算机网络体系结构计算机网络各层、层中协议以及层间接口的集合(即网络层次_网络体系以及网络协议的定义和内容。