├── 018af92b6053b90b664e19bf1da09332.png ├── 030afb332f13e4bc6b0596b5aa365aa2.png ├── 1b2765c8344e32b7e4caa27f19a765c0.png ├── 472bdda4b1b5e1bdd999f42572323628.png ├── 58c0d1aa280cc0c77f1c507d97b1b4e6.png ├── 62adeab6ed8dcfe56517b13a7e575bb3.png ├── 761f359dd001f5f8cb8b1cb239aeeb46.png ├── 888add61eab5b53665e2128ed2cfafe8.png ├── 8e1a04bd14d7d5f49f4627bd3da34123.png ├── README.md ├── a04a71c82ea4fecb18eb7123c15277a5.png ├── b618faf45cd351490d0362755e8e0cae.png ├── efa812bb804f0fb161e3c69ed54531d2.png ├── f4422dfba3bbfb604826e4699346fbe4.png ├── import_tensorflow_as.py ├── model_save_traffic_m.py ├── model_tf_keras_Seque.py ├── show.py ├── x_.py └── x_np_array_x_.py /018af92b6053b90b664e19bf1da09332.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/018af92b6053b90b664e19bf1da09332.png -------------------------------------------------------------------------------- /030afb332f13e4bc6b0596b5aa365aa2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/030afb332f13e4bc6b0596b5aa365aa2.png -------------------------------------------------------------------------------- /1b2765c8344e32b7e4caa27f19a765c0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/1b2765c8344e32b7e4caa27f19a765c0.png -------------------------------------------------------------------------------- /472bdda4b1b5e1bdd999f42572323628.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/472bdda4b1b5e1bdd999f42572323628.png -------------------------------------------------------------------------------- /58c0d1aa280cc0c77f1c507d97b1b4e6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/58c0d1aa280cc0c77f1c507d97b1b4e6.png -------------------------------------------------------------------------------- /62adeab6ed8dcfe56517b13a7e575bb3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/62adeab6ed8dcfe56517b13a7e575bb3.png -------------------------------------------------------------------------------- /761f359dd001f5f8cb8b1cb239aeeb46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/761f359dd001f5f8cb8b1cb239aeeb46.png -------------------------------------------------------------------------------- /888add61eab5b53665e2128ed2cfafe8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/888add61eab5b53665e2128ed2cfafe8.png -------------------------------------------------------------------------------- /8e1a04bd14d7d5f49f4627bd3da34123.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/8e1a04bd14d7d5f49f4627bd3da34123.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |  2 | # 1.图片演示: 3 | ![1.png](018af92b6053b90b664e19bf1da09332.png) 4 | 5 | ![2.png](761f359dd001f5f8cb8b1cb239aeeb46.png) 6 | 7 | ![3.png](030afb332f13e4bc6b0596b5aa365aa2.png) 8 | # 2.视频演示: 9 | 10 | [[项目分享]Python基于YOLOv5的交通标志识别系统[源码&技术文档&部署视频&数据集]_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1Gg411Q7jU/?vd_source=bc9aec86d164b67a7004b996143742dc) 11 | 12 | # 3.标注好的数据集: 13 | ![b1.png](62adeab6ed8dcfe56517b13a7e575bb3.png) 14 | 15 | ![b2.png](f4422dfba3bbfb604826e4699346fbe4.png) 16 | 17 | ![b3.png](58c0d1aa280cc0c77f1c507d97b1b4e6.png) 18 | 19 | ![b4.png](888add61eab5b53665e2128ed2cfafe8.png) 20 | 21 | ![b5.png](b618faf45cd351490d0362755e8e0cae.png) 22 | 23 | # 4.YOLO网络的构建: 24 | ![11.png](472bdda4b1b5e1bdd999f42572323628.png) 25 | 网络结构是首先用Focus将计算图长宽变为原先1/4, channel 数量乘4。再用bottlenectCSP 提取特征,个人理解 CSP 就是更多不同channel的融合吧。 26 | ![22.png](a04a71c82ea4fecb18eb7123c15277a5.png) 27 | 然后再用maxpooling 下采样构建特征金字塔。下采样过每阶段与input cancatenate。 28 | ![33.png](efa812bb804f0fb161e3c69ed54531d2.png) 29 | 再对下采样产生的feature map 上采样,与backbone里相应的层融合。最后用detect层预测anchors。detect 层输出channel是 (class num + 5)* 每层每grid预测的anchor 数。num class是预测结果为每类的概率,5是anchor的 x, y, w, h 和是否为object的置信度。默认配置经过maxpooling 以后产生三个尺寸的feature map,每个feature map 经过上采样融合等操作后都会用来预测anchor,每个grid 预测三个anchor。比如yolov5 s 预测anchor 有80类。输出 x.shape=(bs, 3, 20, 20, 85)。 30 | # 5.数据增强: 31 | 在深度学习领域,对于数据量的要求是巨大的,在CV领域,我们通过图像数据增强对现有图像数据进行处理来丰富图像训练集,这样可以有效的泛化模型,解决过拟合的问题。 32 | 33 | [该博客提出的图像数据增强方式](https://mbd.pub/o/bread/Yp6clZtx)有旋转图像、裁剪图像、水平或垂直翻转图像,改变图像亮度等,为了方便训练模型,我们通常会对数据进行归一化或者标准化以及将图片大小设置为一样。 34 | ![预处理.png](1b2765c8344e32b7e4caa27f19a765c0.png) 35 | 36 | 37 | # 6.代码实现: 38 | [该博客代码写法上来值得注意](https://afdian.net/item?plan_id=c673a3305e4f11ed83be52540025c377)的有这几处: 39 | 40 | 1 首先有 focus 层,对输入图片slice, 把feature map减小增加channel 后面计算速度会快。 41 | 42 | 2 构建模型(parse_model) 在yolo.py 里面,用一个数组(ch) 存储了每层的输出channel, 后续concatenate的时候很容易构成concatenate后输出的channel 数量。 43 | 44 | 3 对除了最后一层预测层外,每层output channel都检查是不是8的倍数,保证后续concate的时候不会出问题 45 | 46 | 4 common.py 里面是各种basic block, 除了bottlenect, CSP, concate层等,还有transformer 等层。 47 | 48 | 首先导入相关模块: 49 | ``` 50 | import tensorflow as tf 51 | import numpy as np 52 | import pandas as pd 53 | import cv2 54 | import matplotlib.pyplot as plt 55 | import os 56 | from sklearn.model_selection import train_test_split 57 | ``` 58 | 读取图片:target.txt的内容如下所示,前面对应图片名字,后面对应图片的类别 59 | ``` 60 | x=[] 61 | y=[] 62 | with open ('./target.txt','r') as f: 63 | for j,i in enumerate(f): 64 | path=i.split()[0] 65 | lable=i.split()[1] 66 | print('读取第%d个图片'%j,path,lable) 67 | src=cv2.imread('./suju/'+path) 68 | x.append(src) 69 | y.append(int(lable)) 70 | 71 | ``` 72 | 将数据归一化,并且划训练集和验证集 73 | ``` 74 | x=np.array(x) 75 | y=np.array(y) 76 | x.shape,y.shape 77 | y=y[:,None] 78 | x_train,x_test,y_train,y_test=train_test_split(x,y,stratify=y,random_state=0) 79 | #归一化 80 | x_train=x_train.astype('float32')/255 81 | x_test=x_test.astype('float32')/255 82 | 83 | y_train_onehot=tf.keras.utils.to_categorical(y_train) 84 | y_test_onehot=tf.keras.utils.to_categorical(y_test) 85 | 86 | ``` 87 | 搭建网络模型 88 | ``` 89 | model=tf.keras.Sequential([ 90 | tf.keras.Input(shape=(80,80,3)), 91 | tf.keras.layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'), 92 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 93 | tf.keras.layers.Conv2D(filters=64,kernel_size=(3,3),padding='same',activation='relu'), 94 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 95 | tf.keras.layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'), 96 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 97 | tf.keras.layers.Flatten(), 98 | tf.keras.layers.Dense(1000,activation='relu'), 99 | tf.keras.layers.Dropout(rate=0.5), 100 | tf.keras.layers.Dense(43,activation='softmax') 101 | ]) 102 | model.compile( 103 | loss='categorical_crossentropy', 104 | optimizer='adam', 105 | metrics=['accuracy'] 106 | ) 107 | train_history=model.fit(x_train,y_train_onehot,batch_size=100,epochs=8,validation_split=0.2,verbose=1, 108 | ) 109 | 110 | ``` 111 | 画图显示模型的loss和acc 112 | ``` 113 | la=[str(i) for i in range(1,9)] 114 | def show(a,b,c,d): 115 | 116 | 117 | fig,axes=plt.subplots(1,2,figsize=(10,4)) 118 | axes[0].set_title('accuracy of train and valuation') 119 | axes[0].plot(la,train_history.history[a],marker='*') 120 | axes[0].plot(train_history.history[b],marker='*') 121 | axes[0].set_xlabel('epoch') 122 | axes[0].set_ylabel('accuracy') 123 | 124 | aa=round(train_history.history[a][7],2) 125 | bb=round(train_history.history[b][7],2) 126 | 127 | axes[0].text(la[7],train_history.history[a][7],aa,ha='center',va='bottom') 128 | axes[0].text(la[7],train_history.history[b][7],bb,ha='center',va='top') 129 | #axes[0].set_xticks(la,['as','asd',3,4,5,6,7,8]) 130 | # for x1,y1 in zip(la,train_history.history[a]): 131 | # y1=round(y1,2) 132 | # axes[0].text(x1,y1,y1,ha='center',va='bottom',fontsize=10,c='b') 133 | 134 | axes[0].legend(['train_accuracy','val_accuracy']) 135 | 136 | axes[1].set_title('loss of train and valuation') 137 | axes[1].plot(la,train_history.history[c],marker='*') 138 | axes[1].plot(train_history.history[d],marker='*') 139 | axes[1].set_xlabel('epoch') 140 | axes[1].set_ylabel('loss') 141 | 142 | cc=round(train_history.history[c][7],2) 143 | dd=round(train_history.history[d][7],2) 144 | 145 | axes[1].text(la[7],train_history.history[c][7],cc,ha='center',va='top') 146 | axes[1].text(la[7],train_history.history[d][7],dd,ha='center',va='bottom') 147 | axes[1].legend(['train_loss', 'val_loss']) 148 | #axes[1].show() 149 | 150 | show('accuracy','val_accuracy','loss','val_loss') 151 | ``` 152 | 保存模型 153 | ``` 154 | model.save('traffic_model2.h5') 155 | ``` 156 | # 7.训练结果: 157 | ![results.png](8e1a04bd14d7d5f49f4627bd3da34123.png) 158 | 159 | 完整[源码&环境部署视频教程&数据集&自定义训练视频教程](https://s.xiaocichang.com/s/caf5a2) 160 | 参考博客[《Python基于YOLOv5的交通标志识别系统\[源码&技术文档&部署视频&数据集\]》](https://mbd.pub/o/qunma/work) 161 | 162 | # 8.参考文献: 163 | 【1】谢豆,石景文,刘文军,刘澍.[一种基于深度学习的交通标志识别算法研究[J]](http://yuxiqbs.cqvip.com/Qikan/Article/Detail?id=7106892593&from=Qikan_Article_Detail).电脑知识与技术:学术版,2022,18(6):116-118. 164 | 【2】王泽华,宋卫虎,吴建华.[基于改进YOLOv4网络的轻量化交通标志检测模型[J]](http://yuxiqbs.cqvip.com/Qikan/Article/Detail?id=7106890735&from=Qikan_Article_Detail).电脑知识与技术:学术版,2022,18(5):98-101. 165 | 166 | 167 | 168 | 169 | 170 | --- 171 | #### 如果您需要更详细的【源码和环境部署教程】,除了通过【系统整合】小节的链接获取之外,还可以通过邮箱以下途径获取: 172 | #### 1.请先在GitHub上为该项目点赞(Star),编辑一封邮件,附上点赞的截图、项目的中文描述概述(About)以及您的用途需求,发送到我们的邮箱 173 | #### sharecode@yeah.net 174 | #### 2.我们收到邮件后会定期根据邮件的接收顺序将【完整源码和环境部署教程】发送到您的邮箱。 175 | #### 【免责声明】本文来源于用户投稿,如果侵犯任何第三方的合法权益,可通过邮箱联系删除。 -------------------------------------------------------------------------------- /a04a71c82ea4fecb18eb7123c15277a5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/a04a71c82ea4fecb18eb7123c15277a5.png -------------------------------------------------------------------------------- /b618faf45cd351490d0362755e8e0cae.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/b618faf45cd351490d0362755e8e0cae.png -------------------------------------------------------------------------------- /efa812bb804f0fb161e3c69ed54531d2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/efa812bb804f0fb161e3c69ed54531d2.png -------------------------------------------------------------------------------- /f4422dfba3bbfb604826e4699346fbe4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qunshansj/traffic-sign-recognition-yolov5-python/b0581a4fc4b1413d3029340bd95d09658a118585/f4422dfba3bbfb604826e4699346fbe4.png -------------------------------------------------------------------------------- /import_tensorflow_as.py: -------------------------------------------------------------------------------- 1 | 2 | import tensorflow as tf 3 | import numpy as np 4 | import pandas as pd 5 | import cv2 6 | import matplotlib.pyplot as plt 7 | import os 8 | from sklearn.model_selection import train_test_split 9 | -------------------------------------------------------------------------------- /model_save_traffic_m.py: -------------------------------------------------------------------------------- 1 | 2 | model.save('traffic_model2.h5') 3 | -------------------------------------------------------------------------------- /model_tf_keras_Seque.py: -------------------------------------------------------------------------------- 1 | 2 | model=tf.keras.Sequential([ 3 | tf.keras.Input(shape=(80,80,3)), 4 | tf.keras.layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'), 5 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 6 | tf.keras.layers.Conv2D(filters=64,kernel_size=(3,3),padding='same',activation='relu'), 7 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 8 | tf.keras.layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'), 9 | tf.keras.layers.MaxPooling2D(pool_size=(2,2),strides=(2,2)), 10 | tf.keras.layers.Flatten(), 11 | tf.keras.layers.Dense(1000,activation='relu'), 12 | tf.keras.layers.Dropout(rate=0.5), 13 | tf.keras.layers.Dense(43,activation='softmax') 14 | ]) 15 | model.compile( 16 | loss='categorical_crossentropy', 17 | optimizer='adam', 18 | metrics=['accuracy'] 19 | ) 20 | train_history=model.fit(x_train,y_train_onehot,batch_size=100,epochs=8,validation_split=0.2,verbose=1, 21 | ) 22 | 23 | -------------------------------------------------------------------------------- /show.py: -------------------------------------------------------------------------------- 1 | 2 | la=[str(i) for i in range(1,9)] 3 | def show(a,b,c,d): 4 | 5 | 6 | fig,axes=plt.subplots(1,2,figsize=(10,4)) 7 | axes[0].set_title('accuracy of train and valuation') 8 | axes[0].plot(la,train_history.history[a],marker='*') 9 | axes[0].plot(train_history.history[b],marker='*') 10 | axes[0].set_xlabel('epoch') 11 | axes[0].set_ylabel('accuracy') 12 | 13 | aa=round(train_history.history[a][7],2) 14 | bb=round(train_history.history[b][7],2) 15 | 16 | axes[0].text(la[7],train_history.history[a][7],aa,ha='center',va='bottom') 17 | axes[0].text(la[7],train_history.history[b][7],bb,ha='center',va='top') 18 | #axes[0].set_xticks(la,['as','asd',3,4,5,6,7,8]) 19 | # for x1,y1 in zip(la,train_history.history[a]): 20 | # y1=round(y1,2) 21 | # axes[0].text(x1,y1,y1,ha='center',va='bottom',fontsize=10,c='b') 22 | 23 | axes[0].legend(['train_accuracy','val_accuracy']) 24 | 25 | axes[1].set_title('loss of train and valuation') 26 | axes[1].plot(la,train_history.history[c],marker='*') 27 | axes[1].plot(train_history.history[d],marker='*') 28 | axes[1].set_xlabel('epoch') 29 | axes[1].set_ylabel('loss') 30 | 31 | cc=round(train_history.history[c][7],2) 32 | dd=round(train_history.history[d][7],2) 33 | 34 | axes[1].text(la[7],train_history.history[c][7],cc,ha='center',va='top') 35 | axes[1].text(la[7],train_history.history[d][7],dd,ha='center',va='bottom') 36 | axes[1].legend(['train_loss', 'val_loss']) 37 | #axes[1].show() 38 | 39 | show('accuracy','val_accuracy','loss','val_loss') 40 | -------------------------------------------------------------------------------- /x_.py: -------------------------------------------------------------------------------- 1 | 2 | x=[] 3 | y=[] 4 | with open ('./target.txt','r') as f: 5 | for j,i in enumerate(f): 6 | path=i.split()[0] 7 | lable=i.split()[1] 8 | print('读取第%d个图片'%j,path,lable) 9 | src=cv2.imread('./suju/'+path) 10 | x.append(src) 11 | y.append(int(lable)) 12 | 13 | -------------------------------------------------------------------------------- /x_np_array_x_.py: -------------------------------------------------------------------------------- 1 | 2 | x=np.array(x) 3 | y=np.array(y) 4 | x.shape,y.shape 5 | y=y[:,None] 6 | x_train,x_test,y_train,y_test=train_test_split(x,y,stratify=y,random_state=0) 7 | #归一化 8 | x_train=x_train.astype('float32')/255 9 | x_test=x_test.astype('float32')/255 10 | 11 | y_train_onehot=tf.keras.utils.to_categorical(y_train) 12 | y_test_onehot=tf.keras.utils.to_categorical(y_test) 13 | 14 | --------------------------------------------------------------------------------