基于yolov3的红绿灯识别

知乎原文


You only look once (YOLO) is a state-of-the-art, real-time object detection system. On a Pascal Titan X it processes images at 30 FPS and has a mAP of 57.9% on COCO test-dev.

在这里插入图片描述

  1. Yolo使用c和cuda实现,体积小,代码量相对不大,适合于结合论文和代码去研究其神经网络的结构和原理;
  2. 已经实现了直接接入摄像头进行实时目标检测功能;
  3. 参考上图,yolo的性能好。

任务目标

实时对红绿灯的状态进行检测,由于黄灯数据量较小,目前暂未对黄灯状态进行训练,目前共包括以下状态,

green
greenleft
greenstraight
red
redleft
redstraight

数据采集

首先,在淘宝上买了一个5-50mm变焦的USB免驱工业摄像头,然后借助ROS(Robot Operating System)中的package进行图像的采集,

  1. 摄像头驱动
    http://wiki.ros.org/usb_cam。
    借助了usb_cam package,下载代码后编译运行,
    roslaunch usb_cam usb_cam-test.launch
  1. 自动采集图像
    借助了image_view package,
    其中一些参数可以自己设置,例如图片名,帧率等。
rosrun image_view extract_images _sec_per_frame:=0.5 _filename_format:=trafficlight_%04d.jpg image:=/usb_cam/image_raw

数据标注

使用的软件为labelImg,首先将predefined_classes.txt修改为红灯和绿灯的状态,

green
greenleft
greenstraight
red
redleft
redstraight

切换labelImg输出为yolo,
在这里插入图片描述
进行数据标注,
在这里插入图片描述
保存,生成的标注文件为frame1405.txt,内容如下,

1 0.030078 0.358854 0.022656 0.030208
2 0.105859 0.357812 0.025781 0.034375
2 0.256250 0.353125 0.026562 0.035417

待数据标注完成后(每种class的图片大概2000张左右,包括不同角度,天气等环境),接下来进行训练。

模型训练

yolo代码编译
git clone https://github.com/pjreddie/darknet

修改makefile,我使用的显卡是gtx 1060,6G显存(训练最好选择显存>=6G的显卡),cuda 10.0,计算能力6.1。

GPU=1
CUDNN=1
OPENCV=1
ARCH=-gencode arch=compute_61,code=[sm_61,compute_61]

修改完成后,

make
预训练模型下载

https://pjreddie.com/media/files/yolov3.weights

yolov3.cfg参数修改

在这里插入图片描述
yolov3在feature extractor时使用了新的darknet-53网络,具体的论文可以参考这里
修改yolov3.cfg,
在这里插入图片描述

关于batch size可以根据训练时所使用的硬件进行调整,

  • 第6行,说明每个step我们将使用64张图片进行训练;
  • 第7行,batch将会被分成16个小的组,64/16,用来减小显存的需求;

如果在训练中提示显存不够,可以尝试增加subdivisions值,例如,

batch=64
subdivisions=32

更甚,

batch=64
subdivisions=64

关于最大训练步数,一般设置为classes*2000,而steps设置为上述值的80%和90%。训练时classes为6,则值如下所示,
在这里插入图片描述
关于图片的大小,一般不用去修改,yolo中会根据其神经网络进行调整缩放,
在这里插入图片描述
在这里插入图片描述
关于classes and filters,class和filter的设置可以参考论文中的公式,
在这里插入图片描述

例如,我的classes为6,则yolo层上一层的filters应设置为3*(4+1+6)=33(只需修改所有yolo层的classes和该层上面一层的卷积层)。
在这里插入图片描述

修改voc.data

根据自己的实际路径去修改,

    classes= 6
    train  = /your_path/train.txt
    valid  = /your_path/test.txt
    names = /your_path/voc.names
    backup = backup
修改voc.names

必须和标注时所使用的类别文件中的内容相同,

green
greenleft
greenstraight
red
redleft
redstraight
开始训练
./darknet detector train cfg/voc.data cfg/yolov3.cfg darknet53.conv.74

训练结果测试

训练结果

在训练过程中,每4个epoch计算一次mAP,训练集和测试集的数量如下所示,

mAP (mean average precisions) calculation for each 4 Epochs (1 Epoch= images_in_train_txt /batch iteration)
dataset_train=3237
dataset_test=323

在这里插入图片描述
上图横坐标为训练的迭代次数,纵坐标为mAP值和loss值,在4000步左右时,loss已经趋于稳定,为0.2746。mAP值已经达到90%以上
下图为训练完成时的结果,mAP值已经达到98%
在这里插入图片描述

红绿灯实时检测

Yolo可以直接接入摄像头进行目标实时检测,命令如下,训练完成后的模型为trained.weights,

./darknet detector demo cfg/voc.data cfg/yolov3.cfg trained.weights

如果你的测试电脑上有多个camera(我的笔记本还有个默认的摄像头,yolo 默认device是0),可以利用-c <num>参数去选取,

./darknet detector demo cfg/voc.data cfg/yolov3.cfg trained.weights -c 1

此外,你还可以利用录制的视频去做检测,命令如下,

./darknet detector demo cfg/voc.data cfg/yolov3.cfg trained.weights <video file>

csdn无法上传视频,发一个实时测试的gif,

下面是一个基于YOLOv4的红绿灯识别程序的示例代码: ```python import cv2 import numpy as np # 加载YOLOv4模型 net = cv2.dnn.readNet("yolov4.weights", "yolov4.cfg") # 加载类别名称 classes = [] with open("coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] # 设置输入图像尺寸 input_size = (416, 416) # 加载红绿灯标签 traffic_light_class_id = classes.index("traffic light") # 加载图像 image = cv2.imread("image.jpg") # 图像预处理 blob = cv2.dnn.blobFromImage(image, 1/255.0, input_size, swapRB=True, crop=False) # 设置输入层 net.setInput(blob) # 前向传播 layer_names = net.getLayerNames() output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] outputs = net.forward(output_layers) # 解析输出结果 boxes = [] confidences = [] class_ids = [] for output in outputs: for detection in output: scores = detection[5:] class_id = np.argmax(scores) confidence = scores[class_id] if class_id == traffic_light_class_id and confidence > 0.5: center_x = int(detection[0] * image.shape[1]) center_y = int(detection[1] * image.shape[0]) width = int(detection[2] * image.shape[1]) height = int(detection[3] * image.shape[0]) x = int(center_x - width / 2) y = int(center_y - height / 2) boxes.append([x, y, width, height]) confidences.append(float(confidence)) class_ids.append(class_id) # 非最大抑制 indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4) # 绘制边界框和类别标签 if len(indices) > 0: for i in indices.flatten(): x, y, w, h = boxes[i] label = str(classes[class_ids[i]]) confidence = confidences[i] cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(image, label + " " + str(round(confidence, 2)), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 显示结果 cv2.imshow("Traffic Light Detection", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在运行上述代码之前,需要确保已经下载了YOLOv4的权重文件(yolov4.weights)、配置文件(yolov4.cfg)和类别名称文件(coco.names)。同时,将待检测的图像文件命名为image.jpg并与代码文件放在同一目录下。 上述代码使用OpenCV的dnn模块加载YOLOv4模型,并通过前向传播获取目标检测结果。然后,筛选出红绿灯物体并绘制相应的边界框和标签。最后,通过OpenCV显示检测结果。 请注意,这只是一个简单的示例代码,实际应用中可能需要根据具体情况进行调整和优化。
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值