PyTorch implementation of the paper Ultra Fast Structure-aware Deep Lane Detection

Overview

Ultra-Fast-Lane-Detection

PyTorch implementation of the paper "Ultra Fast Structure-aware Deep Lane Detection".

[June 28, 2021] Updates: we will release an extended version, which improves 6.3 points of F1 on CULane with the ResNet-18 backbone compared with the ECCV version.

Updates: Our paper has been accepted by ECCV2020.

alt text

The evaluation code is modified from SCNN and Tusimple Benchmark.

Caffe model and prototxt can be found here.

Demo

Demo

Install

Please see INSTALL.md

Get started

First of all, please modify data_root and log_path in your configs/culane.py or configs/tusimple.py config according to your environment.

  • data_root is the path of your CULane dataset or Tusimple dataset.
  • log_path is where tensorboard logs, trained models and code backup are stored. It should be placed outside of this project.

For single gpu training, run

python train.py configs/path_to_your_config

For multi-gpu training, run

sh launch_training.sh

or

python -m torch.distributed.launch --nproc_per_node=$NGPUS train.py configs/path_to_your_config

If there is no pretrained torchvision model, multi-gpu training may result in multiple downloading. You can first download the corresponding models manually, and then restart the multi-gpu training.

Since our code has auto backup function which will copy all codes to the log_path according to the gitignore, additional temp file might also be copied if it is not filtered by gitignore, which may block the execution if the temp files are large. So you should keep the working directory clean.


Besides config style settings, we also support command line style one. You can override a setting like

python train.py configs/path_to_your_config --batch_size 8

The batch_size will be set to 8 during training.


To visualize the log with tensorboard, run

tensorboard --logdir log_path --bind_all

Trained models

We provide two trained Res-18 models on CULane and Tusimple.

Dataset Metric paper Metric This repo Avg FPS on GTX 1080Ti Model
Tusimple 95.87 95.82 306 GoogleDrive/BaiduDrive(code:bghd)
CULane 68.4 69.7 324 GoogleDrive/BaiduDrive(code:w9tw)

For evaluation, run

mkdir tmp
# This a bad example, you should put the temp files outside the project.

python test.py configs/culane.py --test_model path_to_culane_18.pth --test_work_dir ./tmp

python test.py configs/tusimple.py --test_model path_to_tusimple_18.pth --test_work_dir ./tmp

Same as training, multi-gpu evaluation is also supported.

Visualization

We provide a script to visualize the detection results. Run the following commands to visualize on the testing set of CULane and Tusimple.

python demo.py configs/culane.py --test_model path_to_culane_18.pth
# or
python demo.py configs/tusimple.py --test_model path_to_tusimple_18.pth

Since the testing set of Tusimple is not ordered, the visualized video might look bad and we do not recommend doing this.

Speed

To test the runtime, please run

python speed_simple.py  
# this will test the speed with a simple protocol and requires no additional dependencies

python speed_real.py
# this will test the speed with real video or camera input

It will loop 100 times and calculate the average runtime and fps in your environment.

Citation

@InProceedings{qin2020ultra,
author = {Qin, Zequn and Wang, Huanyu and Li, Xi},
title = {Ultra Fast Structure-aware Deep Lane Detection},
booktitle = {The European Conference on Computer Vision (ECCV)},
year = {2020}
}

Thanks

Thanks zchrissirhcz for the contribution to the compile tool of CULane, KopiSoftware for contributing to the speed test, and ustclbh for testing on the Windows platform.

Comments
  • 一个训练问题

    一个训练问题

    你好,我在训练自己标注的数据时会出现标签越界的报错,然后加入一些调试代码后出现以下错误:

    `Traceback (most recent call last):

    File "train.py", line 159, in train(net, train_loader, loss_dict, optimizer, scheduler, logger, epoch, metric_dict, cfg.use_aux) File "train.py", line 71, in train loss = calc_loss(loss_dict, results, logger, global_step) File "train.py", line 41, in calc_loss assert torch.all(results['seg_label'] < 5), results['seg_label'][results['seg_label'] >= 5] # 5 is num_lanes + 1

    AssertionError: tensor([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], device='cuda:0') `

    请问这个是怎么造成的呢,我标注的车道线并没有超过四条。

    opened by KKKarlW 31
  • evaluation tool compilation on win10x64  with vs2019

    evaluation tool compilation on win10x64 with vs2019

    Hi there, I am currently willing to compile the C++ evaluation tools for culane following the instructions in INSTALL.md. There is a subtle difference of vs version between mine(vs2019 community) and the one used in the given command, "cmake .. -G "Visual Studio 15 2017 Win64" " which is vs2017. I have tried some possible commands according to my setup like, cmake .. -G "Visual Studio 16 2019 Win64" , cmake .. -G "Visual Studio 15 2017 Win64" , cmake .. -G "Visual Studio 16 2019" -A x64 which I found here , cmake .. -G "Visual Studio 16 2019 Win64" -A x64 , but neither works...

    Here are the cmake error messages. Is there any chance I can fix this up without install a 2017vs by modifying the cmakelist or any other configuration? Thanks in advance! image

    image

    image

    I also try to directly open the folder with vs2019, but get a following error.

    CMake Error at E:\workstation\lanedet\UltraFast\evaluation\culane\CMakeLists.txt:18 (string): string sub-command REPLACE requires at least four arguments. culane_evaluator E:\workstation\lanedet\UltraFast\evaluation\culane\CMakeLists.txt 18

    image

    opened by ustclbh 18
  • I changed the size to train your model, but the output is wired.

    I changed the size to train your model, but the output is wired.

    I changed the input size to 256*256 and change anchor to [108, 116, 125, 133, 142, 151, 160, 168, 177, 186, 195, 203, 212, 220, 229, 237, 246, 255], but when I test my model, the lane that predict by my model is really close to center like this: image I change my hyper parameter according to this issue:https://github.com/cfzd/Ultra-Fast-Lane-Detection/issues/124

    opened by jajajajaja121 15
  • The loss turned into NaN during training

    The loss turned into NaN during training

    图片 The orange line is the result which trained with following cfg:

    
    Config (path: configs/culane.py): {'dataset': 'CULane', 'data_root': '/data/home/xxxx/dataset/CULane', 'epoch': 50, 'batch_size': 128, 'optimizer': 'SGD', 'learning_rate': 0.1, 'weight_decay': 0.0001, 'momentum': 0.9, 'scheduler': 'multi', 'steps': [25, 38], 'gamma': 0.1, 'warmup': 'linear', 'warmup_iters': 695, 'use_aux': True, 'griding_num': 200, 'backbone': '18', 'sim_loss_w': 0.0, 'shp_loss_w': 0.0, 'note': 'First train on CULane', 'log_path': './train_log', 'finetune': None, 'resume': None, 'test_model': None, 'test_work_dir': './tmp'}
    
    

    The blue line is the result which trained with following cfg:

    
    Config (path: configs/culane.py): {'dataset': 'CULane', 'data_root': '/data/home/xxxx/dataset/CULane', 'epoch': 50, 'batch_size': 128, 'optimizer': 'SGD', 'learning_rate': 0.1, 'weight_decay': 0.0001, 'momentum': 0.9, 'scheduler': 'multi', 'steps': [25, 38], 'gamma': 0.1, 'warmup': 'linear', 'warmup_iters': 695, 'use_aux': True, 'griding_num': 200, 'backbone': '18', 'sim_loss_w': 1, 'shp_loss_w': 1, 'note': 'Train on CULane with other loss', 'log_path': './train_log', 'finetune': None, 'resume': None, 'test_model': None, 'test_work_dir': './tmp'}
    
    

    The difference between cfgs is that the orange one do not applied sim_loss and shp_loss ( the weight of them are set to 0.0 ) and blue one applied with weight 1.0 and 1.0 ( which used in the paper ). Such kind of difference made loss ill. According my observation, the loss gone into mad in second epoch and here are some log from stdout:

    .......
     100%|█████████▉| 694/695 [42:47<00:04,  4.02s/it, data_time=1.159, iou=0.194, loss=nan                                                    100%|█████████▉| 694/695 [42:48<00:04,  4.02s/it, data_time=0.055, iou=0.194, loss=nan                                                    100%|██████████| 695/695 [42:48<00:00,  2.96s/it, data_time=0.055, iou=0.194, loss=nan                                                    100%|██████████| 695/695 [42:48<00:00,  3.70s/it, data_time=0.055, iou=0.194, loss=nan                                                    , net_time=0.213, top1=0.001, top2=0.002, top3=0.003]
      0%|          | 0/695 [00:14<?, ?it/s, data_time=13.690, iou=0.194, loss=nan, net_tim                                                      0%|          | 1/695 [00:14<2:51:37, 14.84s/it, data_time=13.690, iou=0.194, loss=na                                                      0%|          | 1/695 [00:16<2:51:37, 14.84s/it, data_time=0.043, iou=0.194, loss=nan                                                      0%|          | 2/695 [00:16<2:04:03, 10.74s/it, data_time=0.043, iou=0.194, loss=nan                                                      0%|          | 2/695 [00:17<2:04:03, 10.74s/it, data_time=0.043, iou=0.195, loss=nan                                                      0%|          | 3/695 [00:17<1:30:50,  7.88s/it, data_time=0.043, iou=0.195, loss=nan                                                      0%|          | 3/695 [00:18<1:30:50,  7.88s/it, data_time=0.059, iou=0.195, loss=nan  
    ......
    

    Is that gradient explosion? But it seems quite good in first epoch. Furthermore, I use single tesla V100 to train and batchsize is set to 128 according former issue

    opened by eeyrw 15
  • 车辆变道时效果变差

    车辆变道时效果变差

    大佬,我在测试model时发现车辆在变道时,检测出的车道会扭曲变形严重,变道结束后,效果就恢复良好了,分析了下,原因感觉是变道过程中车辆骑在车道线上行驶,导致模型对这条骑着的车道线进行分类时,无法区分是左车道还是右车道,所以产生一个中间临界状态,不知这个解释是否正确,以及这种变道过程中检测效果变差的case该如何解决呢, 拜谢大佬!

    opened by gneworld 13
  • 关于测试自己的视频

    关于测试自己的视频

    你好,我用您提供的demo.py测试时候出现: Expected 4-dimensional input for 4-dimensional weight [64, 3, 7, 7], but got 3-dimensional input of size [3, 288, 800] instead 请问这可能是什么问题呢,该如何解决呢?比较小白,请指教,谢谢了。代码如下:

    ` import torch, os, cv2 from model.model import parsingNet from utils.common import merge_config from utils.dist_utils import dist_print import torch import scipy.special, tqdm import numpy as np import torchvision.transforms as transforms from data.dataset import LaneTestDataset

    if name == "main": torch.backends.cudnn.benchmark = True args, cfg = merge_config() dist_print('start testing...') assert cfg.backbone in ['18','34','50','101','152','50next','101next','50wide','101wide']

    if cfg.dataset == 'CULane':
        cls_num_per_lane = 18
    elif cfg.dataset == 'Tusimple':
        cls_num_per_lane = 56
    else:
        raise NotImplementedError
    
    net = parsingNet(pretrained = False, backbone=cfg.backbone,cls_dim = (cfg.griding_num+1,cls_num_per_lane,4),
                    use_aux=False).cuda() # we dont need auxiliary segmentation in testing
    
    state_dict = torch.load(cfg.test_model, map_location='cpu')['model']
    compatible_state_dict = {}
    for k, v in state_dict.items():
        if 'module.' in k:
            compatible_state_dict[k[7:]] = v
        else:
            compatible_state_dict[k] = v
    
    net.load_state_dict(compatible_state_dict, strict=False)
    net.eval()
    
    img_transforms = transforms.Compose([
        transforms.Resize((288, 800)),
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
    ])
    
    
    cap = cv2.VideoCapture("0000.mp4")
    frame = cap.read()
    fourcc = cv2.VideoWriter_fourcc(*'MJPG')
    vout = cv2.VideoWriter(str(111)+'.avi', fourcc , 30.0, (1280,720))
    from PIL import Image
    print('加载cuda是否成功:',torch.cuda.is_available())
    while 1:
        rval,frame = cap.read()
        if rval == False:
            break
        cv2.imwrite("ssss.jpg",frame)
        img_ = Image.open("ssss.jpg")
    
        imgs = img_transforms(img_)
        imgs = imgs.cuda()
        with torch.no_grad():
            out = net(imgs)
    
        col_sample = np.linspace(0, 800 - 1, cfg.griding_num)
        col_sample_w = col_sample[1] - col_sample[0]
    
    
        out_j = out[0].data.cpu().numpy()
        out_j = out_j[:, ::-1, :]
        prob = scipy.special.softmax(out_j[:-1, :, :], axis=0)
        idx = np.arange(cfg.griding_num) + 1
        idx = idx.reshape(-1, 1, 1)
        loc = np.sum(prob * idx, axis=0)
        out_j = np.argmax(out_j, axis=0)
        loc[out_j == cfg.griding_num] = 0
        out_j = loc
    
        # import pdb; pdb.set_trace()
        # vis = cv2.imread(os.path.join(cfg.data_root,names[0]))
        for i in range(out_j.shape[1]):
            if np.sum(out_j[:, i] != 0) > 2:
                for k in range(out_j.shape[0]):
                    if out_j[k, i] > 0:
                        ppp = (int(out_j[k, i] * col_sample_w * 1280 / 800) - 1, int(720 - k * 20) - 1)
                        cv2.circle(img_,ppp,5,(0,255,0),-1)
        vout.write(img_)
        
    vout.release()
    

    `

    opened by ylc2580 12
  • Experimenting with efficientNet: small Val loss but trash prediction

    Experimenting with efficientNet: small Val loss but trash prediction

    Hi,

    I've been recently experimenting with using different feature extractor, in this case MobilenetV3 and efficientNet-B2. Results with MobilenetV3 was acceptable but in the case of efficientNet I came across a weird phenomenon.

    First, I changed the following things:

    The Dense head has now been replaced by 4 branches each containing 3 sets of FC at 256, 256 and 128. When using the segmentation branch I adopted a NAS-net like structure essentially pooling from the last layer and a previous block where the stride is at 16. Also in efficientNet instead of the convolution with filter 8, I used convolution with filter 32.

    In both case I am not using structural losses.

    in the case of Mobilenet the experiment worked. I was able to get a functional model. However with efficienNet although the loss was a lot smaller the predicitons seems to be just random. Any thoughts on this?

    small loss weird prediction

    Thanks again for the paper and repository.

    opened by normandra 11
  • culane的数据集处理

    culane的数据集处理

    1、因图片数据需要,把culane数据集裁剪出中间部分,图像大小为1280*590,那个row_anchor保持相同18个; 2、使用默认超参数culane.py,那个shm和shp的损失权重设置为0,进行训练,那个relation_loss和relation_dis损失一直上升,训练25epoch后,检测效果不好 3、有些人提到shm和shp的损失权重分别设置为0.8,0.5,进行训练,那个relation_dis损失下降,relation_loss一直上升,同样检测效果不好

    考虑culane的场景比较丰富,加上自己场景组成混合数据集,进行训练,不知道能否达到目的?

    opened by longzeyilang 11
  • Lower F1 when training on CULane

    Lower F1 when training on CULane

    I trained a model on CULane, using ResNet-34 as the backbone, and the model's F1 on the test set was only 70.5. The only modification I did was changing the backbone line in the config file to backbone = '34'. Are there any more changes that are necessary to achieve the reported 72.3% F1 in the paper?

    opened by lucastabelini 11
  • Train the model with input shape of 256 x 512 rather than 288 x 800

    Train the model with input shape of 256 x 512 rather than 288 x 800

    I wanted to train the model with an input shape of 256 x 512 rather than 288 x 800. While changing the shape I get lots of errors with the unsupported shape. How do we try to make this transition easy and code to work for every different input shape? or u recommend converting all FC layers to conv

    opened by letdivedeep 10
  • Extract the detected lane pixel

    Extract the detected lane pixel

    Hello @cfzd,

    thank you for such amazing work.

    I want to know if there are any methods to extract the array of detected lane pixels? As I want to try to calculate the lane curvature using the detected lanes.

    Any approaches that I can use?

    Thanks.

    opened by k-nayak 9
  • 一个可能提升算法测试准确率的小改进

    一个可能提升算法测试准确率的小改进

    在使用自己的数据跑ufld算法时,我发现用test.py测试出的结果并不能很好的代表模型的能力。比如我使用训练过的数据进行测试,测试的准确率仅仅在0.3左右,但是用demo.py跑出的可视化结果可以看出,推理结果是与标注基本一致的(毕竟是训练过的数据),所以我仔细对比了一下两个代码的推理部分,发现在demo.py中,代码用到了row_anchor作为评价标准, ppp = (int(out_j[k, i] * col_sample_w * img_w / 800) - 1, int(img_h * (row_anchor[cls_num_per_lane-1-k]/288)) - 1 ) 而在test.py引用的eval_wrapper.py中,row_anchor部分被写成如下: fp.write( '%d %d ' % (int(out_j[k, i] * col_sample_w * 1640 / 800) - 1, int(590 - k * 20) - 1)) 其中int(590 - k * 20) - 1并未考虑resize成288的操作,区域的划分也比较粗暴,所以我改成了demo.py中的写法,再次测试训练过的数据的结果接近1。所以我想测试部分可能并没有完全展现出算法的性能。我仅在自己的数据上进行了测试,那么我猜想在culane数据集上是否已可以通过这样的改动提升算法的准确率呢,大家有兴趣可以尝试一下。

    opened by Khadaz 1
  • how to generate top1 top2 top3

    how to generate top1 top2 top3

    Hi @cfzd , thanks for your great work, it's really impressive!

    i have trained ufast on my dataset, and i find running test.py ,i can get the accuaacy 、fp、fn, but how can i get top1 top2 top3? hope your reply!

    opened by PilotPhil 2
Owner
null
Example scripts for the detection of lanes using the ultra fast lane detection model in Tensorflow Lite.

TFlite Ultra Fast Lane Detection Inference Example scripts for the detection of lanes using the ultra fast lane detection model in Tensorflow Lite. So

Ibai Gorordo 12 Aug 27, 2022
LaneDet is an open source lane detection toolbox based on PyTorch that aims to pull together a wide variety of state-of-the-art lane detection models

LaneDet is an open source lane detection toolbox based on PyTorch that aims to pull together a wide variety of state-of-the-art lane detection models. Developers can reproduce these SOTA methods and build their own methods.

TuZheng 405 Jan 4, 2023
LaneDetectionAndLaneKeeping - Lane Detection And Lane Keeping

LaneDetectionAndLaneKeeping This project is part of my bachelor's thesis. The go

null 5 Jun 27, 2022
Code for the IJCAI 2021 paper "Structure Guided Lane Detection"

SGNet Project for the IJCAI 2021 paper "Structure Guided Lane Detection" Abstract Recently, lane detection has made great progress with the rapid deve

Jinming Su 27 Dec 8, 2022
Lane follower: Lane-detector (OpenCV) + Object-detector (YOLO5) + CAN-bus

Lane Follower This code is for the lane follower, including perception and control, as shown below. Environment Hardware Industrial Camera Intel-NUC(1

Siqi Fan 3 Jul 7, 2022
Find-Lane-Line - Use openCV library and Python to detect the road-lane-line

Find-Lane-Line This project is to use openCV library and Python to detect the road-lane-line. Data Pipeline Step one : Color Selection Step two : Cann

Kenny Cheng 3 Aug 17, 2022
Implementation of our paper 'RESA: Recurrent Feature-Shift Aggregator for Lane Detection' in AAAI2021.

RESA PyTorch implementation of the paper "RESA: Recurrent Feature-Shift Aggregator for Lane Detection". Our paper has been accepted by AAAI2021. Intro

null 137 Jan 2, 2023
PyTorch implementation of 'Gen-LaneNet: a generalized and scalable approach for 3D lane detection'

(pytorch) Gen-LaneNet: a generalized and scalable approach for 3D lane detection Introduction This is a pytorch implementation of Gen-LaneNet, which p

Yuliang Guo 233 Jan 6, 2023
A Data Annotation Tool for Semantic Segmentation, Object Detection and Lane Line Detection.(In Development Stage)

Data-Annotation-Tool How to Run this Tool? To run this software, follow the steps: git clone https://github.com/Autonomous-Car-Project/Data-Annotation

TiVRA AI 13 Aug 18, 2022
Official Pytorch Implementation of 3DV2021 paper: SAFA: Structure Aware Face Animation.

SAFA: Structure Aware Face Animation (3DV2021) Official Pytorch Implementation of 3DV2021 paper: SAFA: Structure Aware Face Animation. Getting Started

QiulinW 122 Dec 23, 2022
Use tensorflow to implement a Deep Neural Network for real time lane detection

LaneNet-Lane-Detection Use tensorflow to implement a Deep Neural Network for real time lane detection mainly based on the IEEE IV conference paper "To

MaybeShewill-CV 1.9k Jan 8, 2023
The implementation of the CVPR2021 paper "Structure-Aware Face Clustering on a Large-Scale Graph with 10^7 Nodes"

STAR-FC This code is the implementation for the CVPR 2021 paper "Structure-Aware Face Clustering on a Large-Scale Graph with 10^7 Nodes" ?? ?? . ?? Re

Shuai Shen 87 Dec 28, 2022
Implementation for paper "STAR: A Structure-aware Lightweight Transformer for Real-time Image Enhancement" (ICCV 2021).

STAR-pytorch Implementation for paper "STAR: A Structure-aware Lightweight Transformer for Real-time Image Enhancement" (ICCV 2021). CVF (pdf) STAR-DC

null 43 Dec 21, 2022
Based on Yolo's low-power, ultra-lightweight universal target detection algorithm, the parameter is only 250k, and the speed of the smart phone mobile terminal can reach ~300fps+

Based on Yolo's low-power, ultra-lightweight universal target detection algorithm, the parameter is only 250k, and the speed of the smart phone mobile terminal can reach ~300fps+

null 567 Dec 26, 2022
LaneAF: Robust Multi-Lane Detection with Affinity Fields

LaneAF: Robust Multi-Lane Detection with Affinity Fields This repository contains Pytorch code for training and testing LaneAF lane detection models i

null 155 Dec 17, 2022
CondLaneNet: a Top-to-down Lane Detection Framework Based on Conditional Convolution

CondLaneNet: a Top-to-down Lane Detection Framework Based on Conditional Convolution This is the official implementation code of the paper "CondLaneNe

Alibaba Cloud 311 Dec 30, 2022
VIL-100: A New Dataset and A Baseline Model for Video Instance Lane Detection (ICCV 2021)

Preparation Please see dataset/README.md to get more details about our datasets-VIL100 Please see INSTALL.md to install environment and evaluation too

null 82 Dec 15, 2022
Python scripts for performing lane detection using the LSTR model in ONNX

ONNX LSTR Lane Detection Python scripts for performing lane detection using the Lane Shape Prediction with Transformers (LSTR) model in ONNX. Requirem

Ibai Gorordo 29 Aug 30, 2022
A lane detection integrated Real-time Instance Segmentation based on YOLACT (You Only Look At CoefficienTs)

Real-time Instance Segmentation and Lane Detection This is a lane detection integrated Real-time Instance Segmentation based on YOLACT (You Only Look

Jin 4 Dec 30, 2022