赞
踩
目录
由于需要使用自己的数据制作TuSimple格式的数据集,但是未找到合适的标注工具,只好自己写一个简单的脚本实现.
目前实现功能只能对直线进行自动标注,曲线部分还没有时间搞.
步骤:
结果:
- {"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"}
- {"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"}
- {"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"}
此功能代码是用C++实现的,功能比较简单,可以自己写一个python脚本.
- /*
- * @Author: hw
- * @Date: 2022-01-05 16:35:58
- * @LastEditTime: 2022-01-10 15:40:00
- * @Description: 将视频数据的图像帧保存
- * @FilePath: /lane_detect_opencv/src/lane_det/src/tools/video2frame.cpp
- */
- #include "ros/ros.h"
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- #include <opencv2/imgproc/imgproc.hpp>
- #include <iostream>
-
- int main(int argc, char **argv)
- {
- ros::init(argc, argv, "video2frame");
- ros::NodeHandle nh_;
- ROS_INFO("[video2frame] node run");
-
- //打开视频文件:其实就是建立一个VideoCapture结构,"path to video"
- cv::VideoCapture capture("/home/hw/project/LaneDetection/datasets/video/lane_test.flv");
-
- //检测是否正常打开:成功打开时,isOpened返回ture
- if (!capture.isOpened())
- std::cout << "fail toopen!" << std::endl;
-
- //获取整个帧数
- long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
- std::cout << "整个视频共" << totalFrameNumber << "帧" << std::endl;
-
- //设置开始帧()
- long frameToStart = 1;
- capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart);
- std::cout << "从第" << frameToStart << "帧开始读" << std::endl;
-
- //设置结束帧
- long frameToStop = totalFrameNumber;
-
- if (frameToStop < frameToStart)
- {
- std::cout << "结束帧小于开始帧,程序错误,即将退出!" << std::endl;
- return -1;
- }
- else
- {
- std::cout << "结束帧为:第" << frameToStop << "帧" << std::endl;
- }
-
- //获取帧率
- double FPS = capture.get(CV_CAP_PROP_FPS);
- std::cout << "帧率为:" << FPS << std::endl;
-
- //定义一个用来控制读取视频循环结束的变量
- bool stop = false;
-
- //承载每一帧的图像
- cv::Mat frame;
-
- //显示每一帧的窗口
- // namedWindow( "Extractedframe" );
-
- //两帧间的间隔时间:
- // int delay = 1000/FPS;
- double delay = 1000 / FPS;
-
- //利用while循环读取帧
- // currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
- long currentFrame = frameToStart;
-
- while (!stop)
- {
- //读取下一帧
- if (!capture.read(frame))
- {
- std::cout << "读取视频失败" << std::endl;
- return -1;
- }
-
- // cout << "正在读取第" << currentFrame << "帧" << endl;
- // imshow( "Extractedframe", frame );
-
- //此处为跳帧操作
- if (currentFrame % 20 == 0) //此处为帧数间隔,修改这里就可以了
- {
- std::cout << "正在写第" << currentFrame << "帧" << std::endl;
- std::stringstream str;
- std::string time = std::to_string( ros::Time::now().toNSec());
- std::string image_folder = "/home/hw/project/LaneDetection/datasets/video2frame/lane_test/";
- str << image_folder << time << ".jpg"; /*图片存储位置*/
- std::cout << str.str() << std::endl;
- cv::imwrite(str.str(), frame);
- }
-
- // waitKey(intdelay=0)当delay≤ 0时会永远等待;当delay>0时会等待delay毫秒
- //当时间结束前没有按键按下时,返回值为-1;否则返回按键
- int c = cv::waitKey(delay);
- //按下ESC或者到达指定的结束帧后退出读取视频
- if ((char)c == 27 || currentFrame > frameToStop)
- {
- stop = true;
- }
- //按下按键后会停留在当前帧,等待下一次按键
- if (c >= 0)
- {
- cv::waitKey(0);
- }
- currentFrame++;
- }
-
- //关闭视频文件
- capture.release();
- cv::waitKey(0);
- return 0;
- }
我的文件结构如下,其中clips存放图片,clips_jsons存放标注后的json文件.
TuSimple_self
├── clip_jsons
│ ├── 143
│ ├── 144
│ └── test
└── clips
├── 143
├── 144
└── test
- import json
- import os
-
-
- # 计算线段与行直线的交点
- def getLinesData(x1, y1, x2, y2):
- intersection_x = []
- for h in h_samples:
- if h < y1 and h < y2:
- intersection_x.append(-2)
- else:
- sign = 1
- a = y2 - y1
- if a < 0:
- sign = -1
- a = sign * a
- b = sign * (x1 - x2)
- c = sign * (y1 * x2 - x1 * y2)
- x = -(b * h + c) / a
- intersection_x.append(int(x))
- return intersection_x
-
-
- # 得到文件夹下所有label.json的文件名列表
- def getLabelFilesNameList():
- # 遍历文件夹内所有json文件,找出所有标注数据文件
- file_list = os.listdir(clip_json_path)
- json_name = 'json'
- json_list = []
- for file_name in file_list:
- if json_name in file_name and file_name != 'test_label.json':
- json_list.append(file_name)
- return json_list
-
-
- # 计算车道线与h_lines的交点,并存储到json文件中
- def saveJson(json_list):
- for file_name in json_list:
- file_path = clip_json_path + file_name
- image_name = file_name.strip('.json')
- # 读取直线两个端点
- file = open(file_path, 'r', encoding='utf-8')
- data = json.load(file)
- x1 = int(data['shapes'][0]['points'][0][0])
- y1 = int(data['shapes'][0]['points'][0][1])
- x2 = int(data['shapes'][0]['points'][1][0])
- y2 = int(data['shapes'][0]['points'][1][1])
- intersection_x = getLinesData(x1, y1, x2, y2)
- file.close()
- # 构建test_label.json数据结构,写入数据
- lanes = [intersection_x]
- row_file = 'clips/144/' + image_name + '.jpg'
- info1 = {"lanes": lanes, "h_sample": h_samples, "raw_file": row_file}
- fr = open(test_label_path, 'a')
- model = json.dumps(info1)
- fr.write(model)
- fr.write('\r\n')
- fr.close()
- print(file_name + " " + "handle succeed")
-
-
- # 创建test_label.json文件
- def createJson():
- if not os.access(test_label_path, os.F_OK):
- file = open(test_label_path, 'a')
- file.close()
- print("create test_label.json success")
- else:
- print("test_label.json exist")
-
-
- # 存放结果文件夹路径
- folder_path = '/home/hw/project/LaneDetection/datasets/TuSimple_self/'
- # label文件存储路径
- clip_json_path = folder_path + 'clip_jsons/144/'
- # 结果文件名
- test_label = 'test_label.json'
- # 结果文件路径
- test_label_path = folder_path + test_label
-
- # 图片行位置
- h_samples = [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]
-
- # Press the green button in the gutter to run the script.
- if __name__ == '__main__':
- print('fuck day')
- createJson()
- label_json_list = getLabelFilesNameList()
- saveJson(label_json_list)
- '''
- Descripttion: 曲线标注文件生成Tusimple数据集格式的json文件
- version: 1.0.0
- Author: hw
- Date: 2022-05-05 13:43:12
- LastEditors: hw
- LastEditTime: 2023-07-11 17:50:52
- '''
-
- import json
- import os
- from turtle import color
- from cv2 import cv2
- import random
-
-
- '''
- name: getCrossPoint
- msg: 将标注线与h_samples的交点存储在lane_result
- param {*} x1
- param {*} y1
- param {*} x2
- param {*} y2
- param {*} lane_result
- return {*}
- '''
-
-
- def getCrossPoint(x1, y1, x2, y2, lane_result):
- for index, h in enumerate(h_samples):
- if y1 == y2 and y1 == h:
- lane_result[index] = y1
- continue
- # print("h:"+str(h)+","+"y1:"+str(y1)+","+"y2:"+str(y2))
- if y1 <= h <= y2 or y2 <= h <= y1:
- # print("h:"+str(h)+","+"y1:"+str(y1)+","+"y2:"+str(y2))
- sign = 1
- a = y2 - y1
- if a < 0:
- sign = -1
- a = sign * a
- b = sign * (x1 - x2)
- c = sign * (y1 * x2 - x1 * y2)
- x = -(b * h + c) / a
- # print("x:"+str(x))
- lane_result[index] = int(x)
-
-
- '''
- name: getLabelFilesNameList
- msg: 将clip_jsons文件夹下的json文件名存储在list中
- param {*}
- return {*}
- '''
- # 得到文件夹下所有label.json的文件名列表
-
-
- def getLabelFilesNameList():
- # 遍历文件夹内所有json文件,找出所有标注数据文件
- file_list = os.listdir(clip_json_path)
- json_name = 'json'
- json_list = []
- for file_name in file_list:
- if json_name in file_name and file_name != 'test_label.json':
- json_list.append(file_name)
- return json_list
-
-
- # 计算车道线与h_lines的交点,并存储到json文件中
- def saveJson(json_list):
- for file_name in json_list:
- print(file_name + " " + "handle start")
- file_path = clip_json_path + file_name
- image_name = file_name.strip('.json')
- # 读取直线两个端点
- file = open(file_path, 'r', encoding='utf-8')
- data = json.load(file)
- lanes = []
- j = 0
-
- if len(data['shapes'])>4:
- print("shapes length > 4")
- continue
- while(j < (len(data['shapes']))):
- lane_result = [-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, -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, -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, -2, -2, -2, -2, -2, -2]
- i = 0
- while(i < len(data['shapes'][j]['points'])-1):
- x1 = int(data['shapes'][j]['points'][i][0])
- y1 = int(data['shapes'][j]['points'][i][1])
- x2 = int(data['shapes'][j]['points'][i+1][0])
- y2 = int(data['shapes'][j]['points'][i+1][1])
- i = i+1
- getCrossPoint(x1, y1, x2, y2, lane_result)
- lanes.append(lane_result)
- j = j+1
- file.close()
- img = cv2.imread(folder_path+image_path+image_name+".jpg")
- point_size = 1
- thickness = 4
- color_num1 = [0, 100, 255, 65]
- color_num2 = [255, 0, 0, 0]
- color_num3 = [255, 255, 255, 255]
- j = 0
- while(j < len(lanes)):
- i = 0
- point_color = (color_num1[j], color_num2[j], color_num3[j])
- # print("lanes["+str(j)+"]:"+str(lanes[j]))
- for point_x in lanes[j]:
- center_coordinates = (point_x, h_samples[i])
- if point_x != -2:
- cv2.circle(img, center_coordinates,
- point_size, point_color, thickness)
- i = i+1
- j = j+1
- check_img_folder_path = folder_path+"check/"
- save_path = check_img_folder_path + image_name+".jpg"
- # 检查文件夹是否存在
- if not os.path.exists(check_img_folder_path):
- # 使用os模块中的mkdir()函数创建文件夹
- os.mkdir(check_img_folder_path)
- # cv2.imshow('test', img)
- # cv2.waitKey()
- cv2.imwrite(save_path, img)
- # 构建test_label.json数据结构,写入数据
- row_file = image_path + image_name + '.jpg'
- info1 = {"lanes": lanes, "h_samples": h_samples, "raw_file": row_file}
- fr = open(test_label_path, 'a')
- model = json.dumps(info1)
- fr.write(model)
- fr.write('\r\n')
- fr.close()
- print(file_name + " " + "handle succeed")
-
-
- # 创建test_label.json文件
- def createJson():
- if not os.access(test_label_path, os.F_OK):
- file = open(test_label_path, 'a')
- file.close()
- print("create test_label.json success")
- else:
- print("test_label.json exist")
-
-
- # 存放结果文件夹路径
- folder_path = 'path to dataset'
- # label文件存储路径
- # folder_path + 'clip_jsons/train/'
- clip_json_path = folder_path + 'clip_jsons/'
- # 结果文件名
- test_label = 'label_data_train.json' # 'label_data_test.json'
- # 图片路径
- image_path = 'clips/' # 'clips/test/'
- # 结果文件路径
- test_label_path = folder_path + test_label
-
- # 图片行位置
- h_samples = [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, 720, 730, 740, 750, 760, 770, 780,
- 780, 790, 800, 810, 820, 830, 840, 850, 860, 870, 880, 890, 900, 910, 920, 930, 940, 950, 960, 970, 980,
- 990, 1000, 1010, 1020, 1030, 1040, 1050, 1060, 1070]
-
- # Press the green button in the gutter to run the script.
- if __name__ == '__main__':
- print('fuck day')
- createJson()
- label_json_list = getLabelFilesNameList()
- 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。