ROS1结合自动驾驶数据集Kitti开发教程(八)画出2D检测框

该教程详细介绍了如何利用ROS1和Kitti自动驾驶数据集进行图像处理和标注。内容包括数据预处理,如转换标签和去除无关标注,然后通过OpenCV在图片上绘制2D检测框,并逐步实现每一帧图像的全部物体标注。最后,展示了如何在Rviz中显示标注后的图片,为自动驾驶研究提供可视化支持。
摘要由CSDN通过智能技术生成

注意:

  • 再学习本系列教程时,应该已经安装过ROS了并且需要有一些ROS的基本知识

ubuntu版本:20.04
ros版本:noetic

课程回顾

ROS1结合自动驾驶数据集Kitti开发教程(一)Kitti资料介绍和可视化
ROS1结合自动驾驶数据集Kitti开发教程(二)发布图片
ROS1结合自动驾驶数据集Kitti开发教程(三)发布点云数据
ROS1结合自动驾驶数据集Kitti开发教程(四)画出自己车子模型以及照相机视野
ROS1结合自动驾驶数据集Kitti开发教程(五)发布IMU数据
ROS1结合自动驾驶数据集Kitti开发教程(六)发布GPS数据
ROS1结合自动驾驶数据集Kitti开发教程(七)下载图像标注资料并读取显示

1.数据分析

上一节,我们已经能把标注数据显示出来了,其中可以看到frame代表着第几帧图像的检测结果,如第零帧数据所示:
在这里插入图片描述

第零帧图像如下所示:
在这里插入图片描述

在第一帧的图像中我们可以从中看到有面包车、自行车和行人,在标注数据中也给我们展示出来了。bbox(left,top,right,bottom)分别是标注的四个顶点,有了这四个顶点的坐标,我们就可以画出物体2D的检测框。

2.数据处理

  • 去除DontCare标签的标注数据。
  • vancartruck标签都转换成car标签。
    代码如下所示:
# 将dataframe的`van`,`car`,`truck`标签都转换成car标签。
data.loc[data.type.isin(['Van','Car','Truck']),'type'] = 'Car'
# 去除`DontCare`标签的标注数据。
data = data[data.type.isin(['Car','Cyclist','Pedestrian'])]
# 展示最新dataframe
data

数据处理结果如下图所示:
在这里插入图片描述

3.画出其中一个物体的检测框

获取其bbox(left,top,right,bottom)的各个值。

data.loc[2,['bbox_left','bbox_top','bbox_right','bbox_bottom']]
----
bbox_left      296.744956
bbox_top       161.752147
bbox_right     455.226042
bbox_bottom    292.372804
Name: 2, dtype: object

可以看到这样就可以把四个顶点的数据提取出来了,这时我们就可以绘制检测框了。

# 将四个顶点的坐标值转换为np格式
box = np.array(data.loc[2,['bbox_left','bbox_top','bbox_right','bbox_bottom']]) 
import cv2
# 读取第一帧图片
img = cv2.imread(BASE_PATH+"image_02/data/%010d.png"%0)
# 左上角顶点坐标
left_point = (int(box[0]),int(box[1]))
# 右下角顶点坐标
right_point = (int(box[2]),int(box[3]))
# 画出car的检测框,蓝色,2mm宽度
cv2.rectangle(img,left_point,right_point,(255,0,0),2)
cv2.imshow("img",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.1效果

最终效果如下所示:
在这里插入图片描述

4.画出所有2D检测框

上面已经获取到标注资料中的坐标点,并且能标注出其中的一件物体。但是我们的目标是把每一帧的所有能标注的物体都标注起来。
具体模块代码如下所示:

import cv2
# 一共有153帧
for i in range(153):
    # 读取每一帧的图片
    img = cv2.imread(BASE_PATH+"image_02/data/%010d.png"%i)
    # 获取每一帧的所有标注数据并且转化为numpy格式
    boxs = np.array(data.loc[data.frame.isin([i]),['type','bbox_left','bbox_top','bbox_right','bbox_bottom']])
    for box in boxs:
        left_point = (int(box[1]),int(box[2]))
        right_point = (int(box[3]),int(box[4]))
        # Car类型数据使用蓝色标注,Cyclist使用绿色标注,Pedestrian使用红色标注
        if box[0] == 'Car':
            cv2.rectangle(img,left_point,right_point,(255,0,0),2)
        elif box[0] == 'Cyclist':
            cv2.rectangle(img,left_point,right_point,(0,255,0),2)
        elif box[0] == 'Pedestrian':
            cv2.rectangle(img,left_point,right_point,(0,0,255),2)
    cv2.imshow("img",img)
    cv2.waitKey(0)
    cv2.imwrite("img.png",img)
    cv2.destroyAllWindows()

4.1效果

可以按下任意按键进行下一帧图片的标注:
在这里插入图片描述

5.在Rviz中显示标注后的图片

由于我们已经使用Jupyter Notebook编写并且验证了效果。所以想要移植到ROS中是非常方便和简单的。

  • 1.首先我们需要获取图片标注数据,并对其做相应的处理,代码如下所示:
#----- 读取图片标注数据,并做相应的处理 -----#
def read_labelfile():
    data = pd.read_csv(os.path.join(BASE_PATH, "label_02/0000.txt"), header=None, sep=" ")
    data.columns = LABEL_NAME
    data.loc[data.type.isin(['Van','Car','Truck']),'type'] = 'Car'
    data = data[data.type.isin(['Car','Cyclist','Pedestrian'])]
    return data
  • 2.在main函数中调用获取dataframe
  • 3.直接修改publish_cam_fun函数,图像标注并且发布,代码如下所示:
#----- 相机数据发布函数 -----#
def publish_cam_fun(num,df,cam_pub):
    bridge = CvBridge()
    img = cv2.imread(os.path.join(BASE_PATH, "image_02/data/%010d.png"%num))
    boxs = np.array(df.loc[df.frame.isin([num]),['type','bbox_left','bbox_top','bbox_right','bbox_bottom']])
    for box in boxs:
        left_point = (int(box[1]),int(box[2]))
        right_point = (int(box[3]),int(box[4]))
        if box[0] == 'Car':
            cv2.rectangle(img,left_point,right_point,(255,0,0),2)
        elif box[0] == 'Cyclist':
            cv2.rectangle(img,left_point,right_point,(0,255,0),2)
        elif box[0] == 'Pedestrian':
            cv2.rectangle(img,left_point,right_point,(0,0,255),2)
    cam_pub.publish(bridge.cv2_to_imgmsg(img,"bgr8"))

6.最终显示效果

在这里插入图片描述

结语

本文也是基于笔者的学习和使用经验总结的,主观性较强,如果有哪些不对的地方或者不明白的地方,欢迎评论区留言交流~

为了能和读者进一步讨论问题,建立了一个微信群,方便给大家解答问题,也可以一起讨论问题。
加群链接
✌Bye

要将KITTI数据集的点云数据投影到2D图像,可以使用ROS中的点云转换工具包`pcl_ros`来实现。具体步骤如下: 1. 安装`pcl_ros`工具包 ```bash sudo apt-get install ros-<distro>-pcl-ros ``` 其中`<distro>`是你使用的ROS版本,比如`melodic`。 2. 下载KITTI数据集KITTI官网下载点云数据集。 3. 创建ROS包并将数据集导入 在ROS工作空间中创建一个ROS包,将KITTI数据集导入到ROS包中。 4. 编写ROS节点 使用`pcl_ros`中的`PointCloud2`消息类型读取点云数据,并使用`sensor_msgs/Image`消息类型发布投影后的2D图像。 具体代码可以参考以下示例: ```python import rospy import sensor_msgs.point_cloud2 as pc2 from sensor_msgs.msg import Image, CameraInfo from cv_bridge import CvBridge import numpy as np import cv2 class PointCloudProjector(): def __init__(self): self.cloud_sub = rospy.Subscriber("/kitti/velo/pointcloud", pc2.PointCloud2, self.cloud_callback) self.image_pub = rospy.Publisher("/kitti/velo/image_raw", Image, queue_size=10) self.cam_info_pub = rospy.Publisher("/kitti/velo/camera_info", CameraInfo, queue_size=10) self.bridge = CvBridge() def cloud_callback(self, msg): # Convert PointCloud2 message to numpy array cloud = pc2.read_points(msg, skip_nans=True) # Project point cloud onto 2D image # ... # Publish image image_msg = self.bridge.cv2_to_imgmsg(image, encoding="passthrough") self.image_pub.publish(image_msg) # Publish camera info cam_info_msg = CameraInfo() # ... self.cam_info_pub.publish(cam_info_msg) if __name__ == '__main__': rospy.init_node('point_cloud_projector', anonymous=True) projector = PointCloudProjector() rospy.spin() ``` 在`cloud_callback`函数中,使用`pc2.read_points`函数将`PointCloud2`消息转换为numpy数组,然后将点云投影到2D图像中,并将结果转换为ROS中的`Image`消息类型,使用`self.image_pub.publish`函数发布2D图像。 同时,还需要发布相机信息,可使用`CameraInfo`消息类型,使用`self.cam_info_pub.publish`函数发布。 注意,这里的投影算法需要根据具体需求进行选择和实现。 5. 运行ROS节点 使用`rosrun`命令运行ROS节点。 ```bash rosrun <your_package_name> point_cloud_projector.py ``` 其中,`<your_package_name>`是你创建的ROS包的名称。 6. 查看投影结果 使用`rviz`或其他图像查看工具查看2D图像。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锡城筱凯

你的鼓励是我创造的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值