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

智能推荐

关于计算机一级考试的相关整理(巨详细版)-程序员宅基地

文章浏览阅读328次,点赞6次,收藏10次。关于计算机一级考试的局详细版整理

Java 面向对象基础篇【接口、抽象类、实现类之间的关系】-程序员宅基地

文章浏览阅读740次,点赞10次,收藏7次。在面向对象设计中,根据具体需求选择使用接口、抽象类或实现类来组织扩展与维护的代码结构 ···

巧用Superset大数据分析平台搞定各类图表_superset分析hive表-程序员宅基地

文章浏览阅读6.2w次,点赞5次,收藏46次。前言其实大数据图表展示的这类平台有很多,Superset是其中之一,最近有个需求对各类图表展示的开发较多,索性将工作量交给这个平台。介绍Superset的中文翻译是快船,而Superset其实是一个自助式数据分析工具,它的主要目标是简化我们的数据探索分析操作,它的强大之处在于整个过程一气呵成,几乎不用片刻的等待。 部署docker方式(推荐)docker pull amancevice/carav_superset分析hive表

win10安全中心误删文件怎么办?解析恢复与预防策略-程序员宅基地

文章浏览阅读1.3k次,点赞28次,收藏21次。在使用Windows 10的过程中,许多用户依赖于其内置的安全中心来保护电脑免受恶意软件的侵害。然而,有时安全中心的误判可能导致重要文件被错误地删除。当面对这种情况时,了解如何恢复误删的文件并掌握预防措施显得尤为重要。本文将为您详细解析恢复误删文件的多种方法,并为您提供一系列实用的预防策略,以确保您的数据安全。

socket PHP:详细简单的socket TCP通信PHP实现_php tcp两个客户端通信-程序员宅基地

文章浏览阅读8.6k次,点赞3次,收藏34次。如果你想直接运行程序实现效果:请直接看 3.3 本地服务器及客服端程序1 背景介绍目标:我希望通过套接字的TCP传输来搭建一个服务器,这个服务器的作用是:接受多个客户端的连接并完成他们的相互通信。比如客户端A,客户端B同时连接到服务器S,客户端A向服务器S发送消息,服务器S会将A的消息转发给B,同理,B的消息也可以通过S被转发到A。这样就实现了客户端A和客户端B之间的相互通信。本次我们只实现..._php tcp两个客户端通信

【数学】简化剩余系、欧拉函数、欧拉定理与扩展欧拉定理-程序员宅基地

文章浏览阅读894次,点赞27次,收藏31次。讲解简化剩余系、欧拉函数、欧拉定理与扩展欧拉定理

随便推点

大数据框架版本_你们公司的大数据框架版本-程序员宅基地

文章浏览阅读157次。Hive 3.12Hadoop 3.1.3hbase 2.0.5spark 3.0.0zookeeper 3.5.7flume 1.9.0ranger 2.0.0sqoop 1.4.7_你们公司的大数据框架版本

jvm学习-程序员宅基地

文章浏览阅读126次。Java虚拟机一 java内存区域和内存溢出异常运行时数据区域栈帧是方法运行期的基础数据结构。程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理线程恢复等基础功能都需要依赖这个计数器来完成。Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为

vue x 兼容iphone_vue 项目对iphoneX底部兼容处理-程序员宅基地

文章浏览阅读379次。import Vue from 'vue'Vue.directive('isIphoneX', {bind: function (el, binding) {const _local = 'ios'let isIphoneX = falseif (_local === 'ios' && window.screen.height) {isIphoneX = window.screen..._min-height: 89vh;

MyBatis-Plus和SpringBoot的整合_<dependency> <groupid>com.baomidou</groupid> <arti-程序员宅基地

文章浏览阅读2.8k次,点赞2次,收藏4次。简介MyBatis-Plus是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。一、MyBatis-Plus和SpringBoot整合应用1.1 项目依赖在原项目依赖上,加上下面依赖<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-start_ com.baomidou mybatis-plus-boot-s

解决cURL resource: Resource id #147; cURL error: SSL certificate problem: unable to get local issuer.._requestcoreexception: curl error: ssl certificate -程序员宅基地

文章浏览阅读3.7k次。我这边抛出这个问题是因为我在php后端接口上 调用了阿里云OSS-SDK:"aliyuncs/oss-sdk-php": "~2.0"请求删除文件的操作后出现这个错误提示的:RequestCoreException: cURL resource: Resource id #147; cURL error: SSL certificate problem: unable to get lo..._requestcoreexception: curl error: ssl certificate problem: unable to get loc

AI绘画工具有哪些?-程序员宅基地

文章浏览阅读1.1k次,点赞40次,收藏6次。NVIDIA GauGAN:NVIDIA GauGAN是一款基于生成对抗网络(GAN)的AI绘画工具,它可以将简单的草图快速转换为逼真的图像,帮助用户实现快速的绘画创作。DeepDream:DeepDream是谷歌开发的一种图像处理算法,它基于卷积神经网络,可以将图像中的模式和特征进行增强和变形,产生具有梦幻般效果的图像。ArtBreeder:ArtBreeder是一个基于神经网络的在线创作平台,它可以通过混合不同图像的特征生成新的艺术作品,帮助用户进行创作和探索。

推荐文章

热门文章

相关标签