第三章 OpenLane与TUSimple数据集与标注(车道线感知)

第三章 OpenLane数据集与标注

  • 前言
  • 一 简介
  • 二 车道线标注(Lane Annotation)
    • 2.1 标注生成过程
    • 2.2 生成文件
    • 2.3 更加具体的标注规则
  • 三 CIPO 和场景注释标准
    • 3.1 场景注释
    • 3.2 CIPO注释等级
    • 3.3 注释文件
  • 四 数据集下载
  • 五 TUSimple数据集

第三章 OpenLane与TUSimple数据集与标注(车道线感知)_第1张图片

前言

近期参与到了手写AI的车道线检测的学习中去,以此系列笔记记录学习与思考的全过程。车道线检测系列会持续更新,力求完整精炼,引人启示。所需前期知识,可以结合手写AI进行系统的学习。

一 简介

OpenLane是迄今为止第一个真实世界和最大规模的3D车道数据集。OpenLane包含20万帧、超过88万条实例级车道、14个车道类别(单白色虚线、双黄色实体、左/右路边等),以及场景标签和路线邻近目标(CIPO)注释。详见论文。
OpenLane数据集是在自动驾驶领域的主流数据集上构建的。在1.0版本中,在Waymo开放数据集上发布了注释。OpenLane数据集侧重于车道检测和CIPO。我们注释了每一帧中的所有车道,如果中间没有路边,则包括相反方向的车道。除了车道检测任务,我们还注释:(a)场景标签,例如天气和位置;(b)CIPO,被定义为最受关注的目标w.r.t. ego车辆;除了感知的一整套对象之外,这样的标签对于随后的模块(如规划/控制)是非常实用的。

二 车道线标注(Lane Annotation)

2.1 标注生成过程

  1. 必要的高质量 2D 车道标签。它们包含跟踪 ID、类别和 2D 点地面实况的最终注释。
  2. 然后,对于每一帧,点云首先使用原始 3D 对象边界框进行过滤,然后投影回相应的图像中。我们进一步将与 2D 车道相关的点保留在一定的阈值内。
  3. 在定位和地图系统的帮助下,段内帧中的 3D 车道点可以拼接成长的、高密度的车道。
  4. 2D 投影高于其 2D 注释结束位置的点被标记为不可见。
  5. 最终部署平滑步骤来过滤任何异常值并生成 3D 标记结果。

我们用下面的格式注释车道线。

  • 车道形状。每个2D/3D车道被表示为一组2D/3D点。
  • 车道类别。每个车道都有一个类别,如双黄线或路缘。
  • 车道属性。一些车道具有诸如右、左的属性。
  • 车道追踪ID。除路缘外,每条车道都有唯一的id。
  • 停车线和路缘。

2.2 生成文件

Lane Annotation的 .json 文件中包含相机内参、外参、车道线类别、每个点的可见性、像素坐标系下点的2D坐标(u, v)、相机坐标系下点的3D坐标(x, y, z)、车道的左右属性、车道的跟踪ID以及文件的相对路径。lane_lines中有k条车道线,对应k组内容数据。

{
     "intrinsic": <float> [3, 3],       -- 摄像机的内参矩阵,描述了摄像机的几何和光学特性如焦距、光心位置等
     "extrinsic": <float> [4, 4],       -- 摄像机的外参矩阵,描述了摄像机相对于世界坐标系的位置和姿态
     "lane_lines": [                    -- 包含多条车道线的信息列表
        {
            "category": <int>,         -- 车道线的类别,如白色虚线、白色实线、双白虚线等
                                                        0: 'unkown',
                                                        1: 'white-dash',
                                                        2: 'white-solid',
                                                        3: 'double-white-dash',
                                                        4: 'double-white-solid',
                                                        5: 'white-ldash-rsolid',
                                                        6: 'white-lsolid-rdash',
                                                        7: 'yellow-dash',
                                                        8: 'yellow-solid',
                                                        9: 'double-yellow-dash',
                                                        10: 'double-yellow-solid',
                                                        11: 'yellow-ldash-rsolid',
                                                        12: 'yellow-lsolid-rdash',
                                                        20: 'left-curbside',
                                                        21: 'right-curbside'
            "visibility": <float> [n, ], -- 每个点的可见性,通常用于标记哪些点是可见或被遮挡的
            "uv": [                    -- 在图像坐标下的车道线坐标
                [u1,u2,u3...],         -- U坐标列表
                [v1,v2,v3...]          -- V坐标列表
            ],
            "xyz": [                   -- 在摄像机坐标下的车道线坐标
                [x1,x2,x3...],         -- X坐标列表
                [y1,y2,y3...],         -- Y坐标列表
                [z1,z2,z3...]          -- Z坐标列表
            ],
            "attribute": <int>,        -- 车道线的左右属性,例如左-左、左、右、右-1: left-left
                                                        2: left
                                                        3: right
                                                        4: right-right       
            "track_id": <int>          -- 车道线的跟踪ID,用于跟踪同一车道线在不同帧中的连续性
        },
        ...
    ],
    "file_path": <str>                 -- 图像的文件路径
}

2.3 更加具体的标注规则

  • 车道经常被物体遮挡或因磨损而看不见,但它们对于实际应用仍然有价值。因此,如果车道的部分可见,我们会对车道进行注释,这意味着根据上下文,一侧被遮挡的车道将被延长,或者中间部分不可见的车道将被完成。
  • 可见度主要与远处的点有关,而不是遮挡或磨损。评估中不需要它,但它可以帮助模型区分可见车道点和不可见车道点。
  • 车道数量变化是很常见的,特别是当车道具有复杂拓扑时,例如合并和分流情况下的分叉车道。叉车道被注释为具有共同起点(分割)或终点(合并)的单独车道 - 车道检测方法需要两个紧密相邻的车道。
  • 我们将每个车道注释为 14 个车道类别之一。请注意,如果交通护柱不是临时放置的,则也被视为路边
  • 我们为每个车道标注了一个跟踪 ID,该 ID 在整个路段中是唯一的。我们相信这可能有助于视频车道检测或车道跟踪任务。
    我们还根据最重要的 4 条车道与自我车辆的相对位置,为它们分配 1-4 中的编号。基本上,左右车道为1,左侧车道为2,右侧车道为3,左右车道为4。
  • 我们根据这些主题提供不同的拆分:上下案例、曲线案例、极端天气案例、夜间案例、交叉案例和合并&拆分案例。 Up&Down 案例重点关注上坡/下坡道路。曲线情况由不同的大曲线道路组成。极端天气,顾名思义,是由雨中的道路组成的。夜间箱针对光线昏暗的道路。交叉路口情况和合并&分割情况是车道拓扑困难的两种常见交通场景。

最终可以获得:

三 CIPO 和场景注释标准

3.1 场景注释

我们用下面的格式注释CIPO和场景。

  • 具有代表对象重要性级别的类别的2D Bounding Box。
  • 场景标签。它描述了在何种情况下收集该帧。
  • 天气标签。它描述了在什么天气下收集该帧。
  • 小时标签。它标注了该帧是在什么时间收集的。

3.2 CIPO注释等级

我们利用Waymo开放数据集中的2D边界框注释来生成CIPO注释。为了涵盖复杂的场景,我们将对象(主要包括车辆、行人和骑自行车的人)分为 4 个不同的 CIPO 级别。

  • 级别1:在所需的反应距离内最接近自我车辆,并且有超过50%的部分在自我车道上。级别 1 最多包含一个对象。
  • 级别2:身体与自我通道的真实或虚拟线条相互作用的物体,通常在切入或切出的过程中。
  • 级别3:主要在反应距离或可驾驶区域内的物体,或位于左/自我/右车道内的物体,遮挡率小于50%。请注意,相反方向的车辆也可以处于此 CIPO 级别。
  • 级别4:几乎不太可能影响未来道路的遗骸。它们主要是远距离车道中的物体、可驾驶区域以外的物体或我们数据集中停放的车辆。

3.3 注释文件

  • CIPO 注释的数据格式:
{
    "results": [                           -- 结果列表,包含多个cipo对象的信息
        {
            "width": <float>,                -- cipo边界框的宽度
            "height": <float>,               -- cipo边界框的高度
            "x": <float>,                    -- cipo边界框左上角的x坐标
            "y": <float>,                    -- cipo边界框左上角的y坐标
            "id": <str>,                     -- cipo的重要性级别
            "trackid": <str>,                -- cipo的跟踪ID,整个片段中唯一
            "type": <int>,                   -- cipo的类型,如未知、车辆、行人、标志、骑行者等
                                                            0: TYPE_UNKNOWN
                                                            1: TYPE_VEHICLE
                                                            2: TYPE_PEDESTRIAN
                                                            3: TYPE_SIGN
                                                            4: TYPE_CYCLIST
        },
        ...                                 
    ],
    "raw_file_path": <str>                  -- 图像的文件路径
}

  • 场景标签:
{
    "segment-xxx":                              <str> -- segment id
    {
        "scene":                                <str> 
        "weather":                              <str>
        "time":                                 <str>
    }
    ...                                         (1000 segments)
}
  • scene:住宅、城市、郊区、高速公路、停车场
  • weather:晴朗, 部分云, 阴, 雨, 有雾
  • time:白天,夜晚,黎明/黄昏

最后可以得到:

四 数据集下载

  • **Google Drive:**https://drive.google.com/drive/folders/18upnDfB-VVuQf3GPiv_JQn1-BUOcAotk?usp=sharing
  • 百度云(直接将网址粘贴到浏览器中):https://pan.baidu.com/s/ 14Mbo1u6VndFl6O7aeEW9SQ?pwd=t6h6
  • OpenDateLab: https: //opendatalab.org.cn/OpenLane
  • 代码实现:
from openxlab.dataset import dataset_get
import openxlab
openxlab.login(ak="6eg34zgvrkye9yg2jx91", 
        sk="orjrgbdlkq1j8klwr20jm7gxewyw2vmm47eqxvpd", re_login=True)
dataset_get(dataset_repo_name='OpenDriveLab/OpenLane', 
            destination_path='/media/wanj/MSSD1/OpenSourceDataset/Openlane/')  # destination_path:下载文件指定的本地路径

五 TUSimple数据集

标注json 文件中每一行包括三个字段

raw_file : 每一个数据段的第20帧图像的的 path 路径
lanes 和 h_samples 是数据具体的标注内容,为了压缩,h_sample 是纵坐标(应该是从上到下拍好顺序的),lanes 是每个车道的横坐标,是个二维数组。
-2 表示这个点是无效的点

第三章 OpenLane与TUSimple数据集与标注(车道线感知)_第2张图片
上面的数据就有 4 条车道线,第一条车道线的第一个点的坐标是(632,280)。
标注的过程应该是,将图片的下半部分如70%*height 等分成N份。然后取车道线(如论虚实)与该标注线交叉的点
第三章 OpenLane与TUSimple数据集与标注(车道线感知)_第3张图片
利用以下脚本可以处理得到标注的数据,这个脚本稍微改动下也可以作为深度学习输入的图像。

# -*- coding: utf-8 -*-  
import cv2
import json
import numpy as np

# 设置基础路径
base_path = "/Users/jcl/workspace/lane_detection/"

# 打开 JSON 格式的标签文件
file=open(base_path+'test_label.json','r')
image_num=0

# 逐行读取 JSON 文件
for line in file.readlines():
    # 将 JSON 行转换成字典
    data=json.loads(line)
    # 如果是第 29 帧,进行处理
    if image_num == 29:
        # 读取相应的原始图像
        image=cv2.imread(base_path+data['raw_file'])
        # 初始化二进制图像数组,用于存储车道线的二值图像
        binaryimage=np.zeros((image.shape[0],image.shape[1],1),np.uint8)
        # 初始化实例图像数组,用于存储每条车道线的实例
        instanceimage=binaryimage.copy()
        # 获取车道线的横坐标和纵坐标
        arr_width=data['lanes']
        arr_height=data['h_samples']
        width_num=len(arr_width)
        height_num=len(arr_height)

        # 遍历车道线的纵坐标
        for i in range(height_num):
            lane_hist=40  # 用于实例图像中不同车道的区分,每条车道加 50
            # 遍历各车道线的横坐标
            for j in range(width_num):
                # 检查坐标是否有效,并在图像上标记
                if arr_width[j][i-1]>0 and arr_width[j][i]>0:
                    binaryimage[int(arr_height[i]),int(arr_width[j][i])]=255
                    instanceimage[int(arr_height[i]),int(arr_width[j][i])]=lane_hist
                    # 若前一个点也有效,画线连接两点
                    if i>0:
                        cv2.line(binaryimage, (int(arr_width[j][i-1]),int(arr_height[i-1])), (int(arr_width[j][i]),int(arr_height[i])), 255, 10)
                        cv2.line(instanceimage,(int(arr_width[j][i-1]),int(arr_height[i-1])), (int(arr_width[j][i]),int(arr_height[i])), lane_hist, 10)
                lane_hist+=50
        # 显示原始图像和生成的二值图与实例图
        cv2.imshow('image.jpg',image)
        cv2.waitKey()
        cv2.imshow('binaryimage.jpg',binaryimage)
        cv2.waitKey()
        cv2.imshow('instanceimage.jpg',instanceimage)
        cv2.waitKey()
        break
        # 保存生成的图像
        # string1=base_path+"gt_image_binary/"+str(image_num)+".png"
        # string2=base_path+"gt_image_instance/"+str(image_num)+".png"
        # string3=base_path+"raw_image/"+str(image_num)+".png"
        # cv2.imwrite(string1,binaryimage)
        # cv2.imwrite(string2,instanceimage)
        # cv2.imwrite(string3,image)
    image_num = image_num + 1
    
file.close()
print "total image_num:"+str(image_num)

处理完之后图片输出如下所示:
第三章 OpenLane与TUSimple数据集与标注(车道线感知)_第4张图片
得到二值图

Tusimple 数据的标注特点:

1、车道线实际上不只是道路上的标线,虚线被当作了一种实线做处理的。这里面双实线、白线、黄线这类信息也是没有被标注的。
2、每条线实际上是点序列的坐标集合,而不是区域集合

你可能感兴趣的:(手写AI,车道线检测,深度学习,深度学习,图像处理)