当前位置:   article > 正文

TuSimple数据集格式标注自己的数据集_tusimple数据集构建

tusimple数据集构建

目录

1.视频数据提取图像帧

2.labelme标注车道线

3.运行脚本,生成标注数据


由于需要使用自己的数据制作TuSimple格式的数据集,但是未找到合适的标注工具,只好自己写一个简单的脚本实现.

目前实现功能只能对直线进行自动标注,曲线部分还没有时间搞.

步骤:

  1. 将视频数据提取图像帧保存;
  2. 使用labelme工具对车道线进行标注,使用Line标注,存储json文件;
  3. 运行脚本程序,自动将标注数据存储到test_label.json文件中;

结果:

  1. {"lanes": [[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 545, 551, 557, 564, 570, 576, 582, 588, 594, 600, 606, 612, 619, 625, 631, 637, 643, 649, 655, 661, 667, 674, 680, 686, 692, 698, 704, 710]], "h_sample": [160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710], "raw_file": "clips/143/1641432916348132559.jpg"}
  2. {"lanes": [[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 556, 560, 565, 569, 574, 578, 582, 587, 591, 596, 600, 605, 609, 614, 618, 622, 627, 631, 636, 640, 645, 649, 654, 658, 662, 667, 671, 676]], "h_sample": [160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710], "raw_file": "clips/143/1641432907120901694.jpg"}
  3. {"lanes": [[-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 538, 543, 548, 553, 558, 563, 568, 573, 577, 582, 587, 592, 597, 602, 607, 612, 616, 621, 626, 631, 636, 641, 646, 651, 656, 660, 665]], "h_sample": [160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710], "raw_file": "clips/143/1641432928394809381.jpg"}

1.视频数据提取图像帧

        此功能代码是用C++实现的,功能比较简单,可以自己写一个python脚本.

  1. /*
  2. * @Author: hw
  3. * @Date: 2022-01-05 16:35:58
  4. * @LastEditTime: 2022-01-10 15:40:00
  5. * @Description: 将视频数据的图像帧保存
  6. * @FilePath: /lane_detect_opencv/src/lane_det/src/tools/video2frame.cpp
  7. */
  8. #include "ros/ros.h"
  9. #include <opencv2/core/core.hpp>
  10. #include <opencv2/highgui/highgui.hpp>
  11. #include <opencv2/imgproc/imgproc.hpp>
  12. #include <iostream>
  13. int main(int argc, char **argv)
  14. {
  15. ros::init(argc, argv, "video2frame");
  16. ros::NodeHandle nh_;
  17. ROS_INFO("[video2frame] node run");
  18. //打开视频文件:其实就是建立一个VideoCapture结构,"path to video"
  19. cv::VideoCapture capture("/home/hw/project/LaneDetection/datasets/video/lane_test.flv");
  20. //检测是否正常打开:成功打开时,isOpened返回ture
  21. if (!capture.isOpened())
  22. std::cout << "fail toopen!" << std::endl;
  23. //获取整个帧数
  24. long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
  25. std::cout << "整个视频共" << totalFrameNumber << "帧" << std::endl;
  26. //设置开始帧()
  27. long frameToStart = 1;
  28. capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart);
  29. std::cout << "从第" << frameToStart << "帧开始读" << std::endl;
  30. //设置结束帧
  31. long frameToStop = totalFrameNumber;
  32. if (frameToStop < frameToStart)
  33. {
  34. std::cout << "结束帧小于开始帧,程序错误,即将退出!" << std::endl;
  35. return -1;
  36. }
  37. else
  38. {
  39. std::cout << "结束帧为:第" << frameToStop << "帧" << std::endl;
  40. }
  41. //获取帧率
  42. double FPS = capture.get(CV_CAP_PROP_FPS);
  43. std::cout << "帧率为:" << FPS << std::endl;
  44. //定义一个用来控制读取视频循环结束的变量
  45. bool stop = false;
  46. //承载每一帧的图像
  47. cv::Mat frame;
  48. //显示每一帧的窗口
  49. // namedWindow( "Extractedframe" );
  50. //两帧间的间隔时间:
  51. // int delay = 1000/FPS;
  52. double delay = 1000 / FPS;
  53. //利用while循环读取帧
  54. // currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
  55. long currentFrame = frameToStart;
  56. while (!stop)
  57. {
  58. //读取下一帧
  59. if (!capture.read(frame))
  60. {
  61. std::cout << "读取视频失败" << std::endl;
  62. return -1;
  63. }
  64. // cout << "正在读取第" << currentFrame << "帧" << endl;
  65. // imshow( "Extractedframe", frame );
  66. //此处为跳帧操作
  67. if (currentFrame % 20 == 0) //此处为帧数间隔,修改这里就可以了
  68. {
  69. std::cout << "正在写第" << currentFrame << "帧" << std::endl;
  70. std::stringstream str;
  71. std::string time = std::to_string( ros::Time::now().toNSec());
  72. std::string image_folder = "/home/hw/project/LaneDetection/datasets/video2frame/lane_test/";
  73. str << image_folder << time << ".jpg"; /*图片存储位置*/
  74. std::cout << str.str() << std::endl;
  75. cv::imwrite(str.str(), frame);
  76. }
  77. // waitKey(intdelay=0)当delay≤ 0时会永远等待;当delay>0时会等待delay毫秒
  78. //当时间结束前没有按键按下时,返回值为-1;否则返回按键
  79. int c = cv::waitKey(delay);
  80. //按下ESC或者到达指定的结束帧后退出读取视频
  81. if ((char)c == 27 || currentFrame > frameToStop)
  82. {
  83. stop = true;
  84. }
  85. //按下按键后会停留在当前帧,等待下一次按键
  86. if (c >= 0)
  87. {
  88. cv::waitKey(0);
  89. }
  90. currentFrame++;
  91. }
  92. //关闭视频文件
  93. capture.release();
  94. cv::waitKey(0);
  95. return 0;
  96. }

2.labelme标注车道线

我的文件结构如下,其中clips存放图片,clips_jsons存放标注后的json文件.

TuSimple_self
├── clip_jsons
│   ├── 143
│   ├── 144
│   └── test
└── clips
    ├── 143
    ├── 144
    └── test

3.运行脚本,生成标注数据

  • 数据集为720P图像,标注只有一条直线
  1. import json
  2. import os
  3. # 计算线段与行直线的交点
  4. def getLinesData(x1, y1, x2, y2):
  5. intersection_x = []
  6. for h in h_samples:
  7. if h < y1 and h < y2:
  8. intersection_x.append(-2)
  9. else:
  10. sign = 1
  11. a = y2 - y1
  12. if a < 0:
  13. sign = -1
  14. a = sign * a
  15. b = sign * (x1 - x2)
  16. c = sign * (y1 * x2 - x1 * y2)
  17. x = -(b * h + c) / a
  18. intersection_x.append(int(x))
  19. return intersection_x
  20. # 得到文件夹下所有label.json的文件名列表
  21. def getLabelFilesNameList():
  22. # 遍历文件夹内所有json文件,找出所有标注数据文件
  23. file_list = os.listdir(clip_json_path)
  24. json_name = 'json'
  25. json_list = []
  26. for file_name in file_list:
  27. if json_name in file_name and file_name != 'test_label.json':
  28. json_list.append(file_name)
  29. return json_list
  30. # 计算车道线与h_lines的交点,并存储到json文件中
  31. def saveJson(json_list):
  32. for file_name in json_list:
  33. file_path = clip_json_path + file_name
  34. image_name = file_name.strip('.json')
  35. # 读取直线两个端点
  36. file = open(file_path, 'r', encoding='utf-8')
  37. data = json.load(file)
  38. x1 = int(data['shapes'][0]['points'][0][0])
  39. y1 = int(data['shapes'][0]['points'][0][1])
  40. x2 = int(data['shapes'][0]['points'][1][0])
  41. y2 = int(data['shapes'][0]['points'][1][1])
  42. intersection_x = getLinesData(x1, y1, x2, y2)
  43. file.close()
  44. # 构建test_label.json数据结构,写入数据
  45. lanes = [intersection_x]
  46. row_file = 'clips/144/' + image_name + '.jpg'
  47. info1 = {"lanes": lanes, "h_sample": h_samples, "raw_file": row_file}
  48. fr = open(test_label_path, 'a')
  49. model = json.dumps(info1)
  50. fr.write(model)
  51. fr.write('\r\n')
  52. fr.close()
  53. print(file_name + " " + "handle succeed")
  54. # 创建test_label.json文件
  55. def createJson():
  56. if not os.access(test_label_path, os.F_OK):
  57. file = open(test_label_path, 'a')
  58. file.close()
  59. print("create test_label.json success")
  60. else:
  61. print("test_label.json exist")
  62. # 存放结果文件夹路径
  63. folder_path = '/home/hw/project/LaneDetection/datasets/TuSimple_self/'
  64. # label文件存储路径
  65. clip_json_path = folder_path + 'clip_jsons/144/'
  66. # 结果文件名
  67. test_label = 'test_label.json'
  68. # 结果文件路径
  69. test_label_path = folder_path + test_label
  70. # 图片行位置
  71. h_samples = [160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360,
  72. 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570,
  73. 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710]
  74. # Press the green button in the gutter to run the script.
  75. if __name__ == '__main__':
  76. print('fuck day')
  77. createJson()
  78. label_json_list = getLabelFilesNameList()
  79. saveJson(label_json_list)
  • 数据集为1080p,标注包含多条直线或曲线
    1. '''
    2. Descripttion: 曲线标注文件生成Tusimple数据集格式的json文件
    3. version: 1.0.0
    4. Author: hw
    5. Date: 2022-05-05 13:43:12
    6. LastEditors: hw
    7. LastEditTime: 2023-07-11 17:50:52
    8. '''
    9. import json
    10. import os
    11. from turtle import color
    12. from cv2 import cv2
    13. import random
    14. '''
    15. name: getCrossPoint
    16. msg: 将标注线与h_samples的交点存储在lane_result
    17. param {*} x1
    18. param {*} y1
    19. param {*} x2
    20. param {*} y2
    21. param {*} lane_result
    22. return {*}
    23. '''
    24. def getCrossPoint(x1, y1, x2, y2, lane_result):
    25. for index, h in enumerate(h_samples):
    26. if y1 == y2 and y1 == h:
    27. lane_result[index] = y1
    28. continue
    29. # print("h:"+str(h)+","+"y1:"+str(y1)+","+"y2:"+str(y2))
    30. if y1 <= h <= y2 or y2 <= h <= y1:
    31. # print("h:"+str(h)+","+"y1:"+str(y1)+","+"y2:"+str(y2))
    32. sign = 1
    33. a = y2 - y1
    34. if a < 0:
    35. sign = -1
    36. a = sign * a
    37. b = sign * (x1 - x2)
    38. c = sign * (y1 * x2 - x1 * y2)
    39. x = -(b * h + c) / a
    40. # print("x:"+str(x))
    41. lane_result[index] = int(x)
    42. '''
    43. name: getLabelFilesNameList
    44. msg: 将clip_jsons文件夹下的json文件名存储在list中
    45. param {*}
    46. return {*}
    47. '''
    48. # 得到文件夹下所有label.json的文件名列表
    49. def getLabelFilesNameList():
    50. # 遍历文件夹内所有json文件,找出所有标注数据文件
    51. file_list = os.listdir(clip_json_path)
    52. json_name = 'json'
    53. json_list = []
    54. for file_name in file_list:
    55. if json_name in file_name and file_name != 'test_label.json':
    56. json_list.append(file_name)
    57. return json_list
    58. # 计算车道线与h_lines的交点,并存储到json文件中
    59. def saveJson(json_list):
    60. for file_name in json_list:
    61. print(file_name + " " + "handle start")
    62. file_path = clip_json_path + file_name
    63. image_name = file_name.strip('.json')
    64. # 读取直线两个端点
    65. file = open(file_path, 'r', encoding='utf-8')
    66. data = json.load(file)
    67. lanes = []
    68. j = 0
    69. if len(data['shapes'])>4:
    70. print("shapes length > 4")
    71. continue
    72. while(j < (len(data['shapes']))):
    73. lane_result = [-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    74. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    75. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    76. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    77. -2, -2, -2, -2, -2, -2, -2, -2, -2]
    78. i = 0
    79. while(i < len(data['shapes'][j]['points'])-1):
    80. x1 = int(data['shapes'][j]['points'][i][0])
    81. y1 = int(data['shapes'][j]['points'][i][1])
    82. x2 = int(data['shapes'][j]['points'][i+1][0])
    83. y2 = int(data['shapes'][j]['points'][i+1][1])
    84. i = i+1
    85. getCrossPoint(x1, y1, x2, y2, lane_result)
    86. lanes.append(lane_result)
    87. j = j+1
    88. file.close()
    89. img = cv2.imread(folder_path+image_path+image_name+".jpg")
    90. point_size = 1
    91. thickness = 4
    92. color_num1 = [0, 100, 255, 65]
    93. color_num2 = [255, 0, 0, 0]
    94. color_num3 = [255, 255, 255, 255]
    95. j = 0
    96. while(j < len(lanes)):
    97. i = 0
    98. point_color = (color_num1[j], color_num2[j], color_num3[j])
    99. # print("lanes["+str(j)+"]:"+str(lanes[j]))
    100. for point_x in lanes[j]:
    101. center_coordinates = (point_x, h_samples[i])
    102. if point_x != -2:
    103. cv2.circle(img, center_coordinates,
    104. point_size, point_color, thickness)
    105. i = i+1
    106. j = j+1
    107. check_img_folder_path = folder_path+"check/"
    108. save_path = check_img_folder_path + image_name+".jpg"
    109. # 检查文件夹是否存在
    110. if not os.path.exists(check_img_folder_path):
    111. # 使用os模块中的mkdir()函数创建文件夹
    112. os.mkdir(check_img_folder_path)
    113. # cv2.imshow('test', img)
    114. # cv2.waitKey()
    115. cv2.imwrite(save_path, img)
    116. # 构建test_label.json数据结构,写入数据
    117. row_file = image_path + image_name + '.jpg'
    118. info1 = {"lanes": lanes, "h_samples": h_samples, "raw_file": row_file}
    119. fr = open(test_label_path, 'a')
    120. model = json.dumps(info1)
    121. fr.write(model)
    122. fr.write('\r\n')
    123. fr.close()
    124. print(file_name + " " + "handle succeed")
    125. # 创建test_label.json文件
    126. def createJson():
    127. if not os.access(test_label_path, os.F_OK):
    128. file = open(test_label_path, 'a')
    129. file.close()
    130. print("create test_label.json success")
    131. else:
    132. print("test_label.json exist")
    133. # 存放结果文件夹路径
    134. folder_path = 'path to dataset'
    135. # label文件存储路径
    136. # folder_path + 'clip_jsons/train/'
    137. clip_json_path = folder_path + 'clip_jsons/'
    138. # 结果文件名
    139. test_label = 'label_data_train.json' # 'label_data_test.json'
    140. # 图片路径
    141. image_path = 'clips/' # 'clips/test/'
    142. # 结果文件路径
    143. test_label_path = folder_path + test_label
    144. # 图片行位置
    145. h_samples = [160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360,
    146. 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500, 510, 520, 530, 540, 550, 560, 570,
    147. 580, 590, 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 750, 760, 770, 780,
    148. 780, 790, 800, 810, 820, 830, 840, 850, 860, 870, 880, 890, 900, 910, 920, 930, 940, 950, 960, 970, 980,
    149. 990, 1000, 1010, 1020, 1030, 1040, 1050, 1060, 1070]
    150. # Press the green button in the gutter to run the script.
    151. if __name__ == '__main__':
    152. print('fuck day')
    153. createJson()
    154. label_json_list = getLabelFilesNameList()
    155. saveJson(label_json_list)
    数据集整理完成之后需要使用ultra fast lane detection 项目下的scripts/convert_tusimple.py生成train_gt.txt文件,如果数据集为1080p图像需要改程序90行的像素参数
    label = np.zeros((1080,1920),dtype=np.uint8)

    运行指令为:python convert_tusimple.py --root path_to_dataset

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/345240
推荐阅读
相关标签
  

闽ICP备14008679号