由于该项目是针对中小学生竞赛并且是第一次举行,所以识别的目标交通标志仅仅只有直行、右转、左转和停车让行。

数据集:https://pan.baidu.com/s/1sLl0CadEutv3PQXhmqpCXw 提取码:mp2x

源代码:https://github.com/ccxiao5/Traffic_sign_recognition

整体流程如下:

数据集收集(包括训练集和测试集的分类)

图像预处理

图像标注

根据标注分割得到目标图像

HOG特征提取

训练得到模型

将模型带入识别算法进行识别

我的数据目录树。其中test_images/train_images是收集得到原始数据集。realTest/realTrain是预处理后的图像。dataTest/dataTrain是经过分类处理得到的图像,HogTest/HogTrain是通过XML标注后裁剪得到的图像。HogTest_affine/HogTrain_affine是经过仿射变换处理扩充的训练集和测试集。imgTest_hog.txt/imgTrain_hog.txt是测试集和训练集的Hog特征

一、图像处理

由于得到的数据集图像大小不一(如下),我们首先从中心区域裁剪并调整正方形图像的大小,然后将处理后的图像保存到realTrain和realTest里面。

图片名称对应关系如下:

img_label ={"000":"Speed_limit_5","001":"Speed_limit_15","002":"Speed_limit_30","003":"Speed_limit_40","004":"Speed_limit_50","005":"Speed_limit_60","006":"Speed_limit_70","007":"Speed_limit_80","008":"No straight or right turn","009":"No straight or left turn","010":"No straight","011":"No left turn","012":"Do not turn left and right","013":"No right turn","014":"No Overhead","015":"No U-turn","016":"No Motor vehicle","017":"No whistle","018":"Unrestricted speed_40","019":"Unrestricted speed_50","020":"Straight or turn right","021":"Straight","022":"Turn left","023":"Turn left or turn right","024":"Turn right","025":"Drive on the left side of the road","026":"Drive on the right side of the road","027":"Driving around the island","028":"Motor vehicle driving","029":"Whistle","030":"Non-motorized","031":"U-turn","032":"Left-right detour","033":"traffic light","034":"Drive cautiously","035":"Caution Pedestrians","036":"Attention non-motor vehicle","037":"Mind the children","038":"Sharp turn to the right","039":"Sharp turn to the left","040":"Downhill steep slope","041":"Uphill steep slope","042":"Go slow","044":"Right T-shaped cross","043":"Left T-shaped cross","045":"village","046":"Reverse detour","047":"Railway crossing-1","048":"construction","049":"Continuous detour","050":"Railway crossing-2","051":"Accident-prone road section","052":"stop","053":"No passing","054":"No Parking","055":"No entry","056":"Deceleration and concession","057":"Stop For Check"}

def center_crop(img_array, crop_size=-1, resize=-1, write_path=None):##从中心区域裁剪并调整正方形图像的大小。

rows =img_array.shape[0]

cols= img_array.shape[1]if crop_size==-1 or crop_size>max(rows,cols):

crop_size=min(rows, cols)

row_s= max(int((rows-crop_size)/2), 0)

row_e= min(row_s+crop_size, rows)

col_s= max(int((cols-crop_size)/2), 0)

col_e= min(col_s+crop_size, cols)

img_crop=img_array[row_s:row_e,col_s:col_e,]if resize>0:

img_crop=cv2.resize(img_crop, (resize, resize))if write_path is notNone:

cv2.imwrite(write_path, img_crop)return img_crop

然后根据得到的realTrain和realTest自动生成带有的xml文件

defwrite_img_to_xml(imgfile, xmlfile):

img=cv2.imread(imgfile)

img_folder, img_name=os.path.split(imgfile)

img_height, img_width, img_depth=img.shape

doc=Document()

annotation= doc.createElement("annotation")

doc.appendChild(annotation)

folder= doc.createElement("folder")

folder.appendChild(doc.createTextNode(img_folder))

annotation.appendChild(folder)

filename= doc.createElement("filename")

filename.appendChild(doc.createTextNode(img_name))

annotation.appendChild(filename)

size= doc.createElement("size")

annotation.appendChild(size)

width= doc.createElement("width")

width.appendChild(doc.createTextNode(str(img_width)))

size.appendChild(width)

height= doc.createElement("height")

height.appendChild(doc.createTextNode(str(img_height)))

size.appendChild(height)

depth= doc.createElement("depth")

depth.appendChild(doc.createTextNode(str(img_depth)))

size.appendChild(depth)

with open(xmlfile,"w") as f:

doc.writexml(f, indent="\t", addindent="\t", newl="\n", encoding="utf-8")

/home/xiao5/Desktop/Test2/data/realTest/PNGImages

000_1_0001_1_j.png

640

640

3

然后对realTrain和realTest的图片进行标注,向默认XML添加新的信息(矩形信息)。

PNGImages

021_1_0001_1_j.png

C:\Users\xiao5\Desktop\realTest\PNGImages\021_1_0001_1_j.png

Unknown

640

640

3

0

Straight

Unspecified

0

0

13

22

573

580

处理完后利用我们添加的矩形将图片裁剪下来并且重命名进行分类。主要思路是:解析XML文档,根据标签进行分类,如果是直行、右转、左转、停止,那么就把它从原图中裁剪下来并重命名,如果没有那么就认为是负样本,其中在处理负样本的时候,我进行了颜色识别,把一张负样本图片根据颜色(红色、蓝色)裁剪成几张负样本,这样做的好处是:我们在进行交通标志的识别时,也是使用的颜色识别来选取到交通标志,我们从负样本中分割出来的相近颜色样本有利于负样本的训练,提高模型精度。

def produce_proposals(xml_dir, write_dir, square=False, min_size=30):##返回proposal_num对象

proposal_num ={}for cls_name inclasses_name:

proposal_num[cls_name]=0

index =0for xml_file inos.listdir(xml_dir):

img_path, labels=parse_xml(os.path.join(xml_dir,xml_file))

img=cv2.imread(img_path)##如果图片中没有出现定义的那几种交通标志就把它当成负样本

if len(labels) ==0:

neg_proposal_num= produce_neg_proposals(img_path, write_dir, min_size, square, proposal_num["background"])

proposal_num["background"] =neg_proposal_numelse:

proposal_num= produce_pos_proposals(img_path, write_dir, labels, min_size, square=True, proposal_num=proposal_num)if index%100 ==0:print ("total xml file number =", len(os.listdir(xml_dir)), "current xml file number =", index)print ("proposal num =", proposal_num)

index+= 1

return proposal_num

为了提高模型的精确度,还对目标图片(四类图片)进行仿射变换来扩充训练集。

defaffine(img, delta_pix):

rows, cols, _=img.shape

pts1=np.float32([[0,0], [rows,0], [0, cols]])

pts2= pts1 +delta_pix

M=cv2.getAffineTransform(pts1, pts2)

res=cv2.warpAffine(img, M, (rows, cols))returnresdefaffine_dir(img_dir, write_dir, max_delta_pix):

img_names=os.listdir(img_dir)

img_names= [img_name for img_name in img_names if img_name.split(".")[-1]=="png"]for index, img_name inenumerate(img_names):

img=cv2.imread(os.path.join(img_dir,img_name))

save_name= os.path.join(write_dir, img_name.split(".")[0]+"f.png")

delta_pix= np.float32(np.random.randint(-max_delta_pix,max_delta_pix+1,[3,2]))

img_a=affine(img, delta_pix)

cv2.imwrite(save_name, img_a)

二、HOG特征提取

处理好图片后分别对训练集和测试集进行特征提取得到imgTest_HOG.txt和imgTrain_HOG.txt

def hog_feature(img_array, resize=(64,64)):##提取HOG特征

img=cv2.cvtColor(img_array, cv2.COLOR_BGR2GRAY)

img=cv2.resize(img, resize)

bins= 9cell_size= (8, 8)

cpb= (2, 2)

norm= "L2"features= ft.hog(img, orientations=bins, pixels_per_cell=cell_size,

cells_per_block=cpb, block_norm=norm, transform_sqrt=True)returnfeaturesdef extra_hog_features_dir(img_dir, write_txt, resize=(64,64)):##提取目录中所有图像HOG特征

img_names=os.listdir(img_dir)

img_names= [os.path.join(img_dir, img_name) for img_name inimg_names]ifos.path.exists(write_txt):

os.remove(write_txt)

with open(write_txt,"a") as f:

index=0for img_name inimg_names:

img_array=cv2.imread(img_name)

features=hog_feature(img_array, resize)

label_name= img_name.split("/")[-1].split("_")[0]

label_num=img_label[label_name]

row_data= img_name + "\t" + str(label_num) + "\t"

for element infeatures:

row_data= row_data + str(round(element,3)) + " "row_data= row_data + "\n"f.write(row_data)if index%100 ==0:print ("total image number =", len(img_names), "current image number =", index)

index+= 1

三、模型训练

利用得到的HOG特征进行训练模型得到svm_model.pkl

defload_hog_data(hog_txt):

img_names=[]

labels=[]

hog_features=[]

with open(hog_txt,"r") as f:

data=f.readlines()for row_data indata:

row_data=row_data.rstrip()

img_path, label, hog_str= row_data.split("\t")

img_name= img_path.split("/")[-1]

hog_feature= hog_str.split(" ")

hog_feature= [float(hog) for hog inhog_feature]#print "hog feature length = ", len(hog_feature)

img_names.append(img_name)

labels.append(label)

hog_features.append(hog_feature)returnimg_names, np.array(labels), np.array(hog_features)def svm_train(hog_features, labels, save_path="./svm_model.pkl"):

clf= SVC(C=10, tol=1e-3, probability =True)

clf.fit(hog_features, labels)

joblib.dump(clf, save_path)print ("finished.")

四、交通标志识别及实验测试

交通标志识别的流程:颜色识别得到阈值范围内的二值图、然后进行轮廓识别、剔除多余矩阵。

defpreprocess_img(imgBGR):##将图像由RGB模型转化成HSV模型

imgHSV =cv2.cvtColor(imgBGR, cv2.COLOR_BGR2HSV)

Bmin= np.array([110, 43, 46])

Bmax= np.array([124, 255, 255])##使用inrange(HSV,lower,upper)设置阈值去除背景颜色

img_Bbin =cv2.inRange(imgHSV,Bmin, Bmax)

Rmin2= np.array([165, 43, 46])

Rmax2= np.array([180, 255, 255])

img_Rbin=cv2.inRange(imgHSV,Rmin2, Rmax2)

img_bin=np.maximum(img_Bbin, img_Rbin)returnimg_bin'''提取轮廓,返回轮廓矩形框'''

def contour_detect(img_bin, min_area=0, max_area=-1, wh_ratio=2.0):

rects=[]##检测轮廓,其中cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_NONE 存储所有的边界点

##findContours返回三个值:第一个值返回img,第二个值返回轮廓信息,第三个返回相应轮廓的关系

contours, hierarchy=cv2.findContours(img_bin.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)if len(contours) ==0:returnrects

max_area= img_bin.shape[0]*img_bin.shape[1] if max_area<0 elsemax_areafor contour incontours:

area=cv2.contourArea(contour)if area >= min_area and area <=max_area:

x, y, w, h=cv2.boundingRect(contour)if 1.0*w/h < wh_ratio and 1.0*h/w

rects.append([x,y,w,h])return rects

然后加载模型进行测验

if __name__ == "__main__":

cap=cv2.VideoCapture(0)

cv2.namedWindow('camera')

cv2.resizeWindow("camera",640,480)

cols=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))

rows=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

clf= joblib.load("/home/xiao5/Desktop/Test2/svm_model.pkl")

i=0while (1):

i+=1ret, img=cap.read()

img_bin=preprocess_img(img)

min_area= img_bin.shape[0]*img.shape[1]/(25*25)

rects= contour_detect(img_bin, min_area=min_area)ifrects:

Max_X=0

Max_Y=0

Max_W=0

Max_H=0for r inrects:if r[2]*r[3]>=Max_W*Max_H:

Max_X,Max_Y,Max_W,Max_H=r

proposal= img[Max_Y:(Max_Y+Max_H),Max_X:(Max_X+Max_W)]##用Numpy数组对图像像素进行访问时,应该先写图像高度所对应的坐标(y,row),再写图像宽度对应的坐标(x,col)。

cv2.rectangle(img,(Max_X,Max_Y), (Max_X+Max_W,Max_Y+Max_H), (0,255,0), 2)

cv2.imshow("proposal", proposal)

cls_prop=hog_extra_and_svm_class(proposal, clf)

cls_prop= np.round(cls_prop, 2)

cls_num= np.argmax(cls_prop)##找到最大相似度的索引

if cls_names[cls_num] is not "background":print(cls_names[cls_num])else:print("N/A")

cv2.imshow('camera',img)

cv2.waitKey(40)

cv2.destroyAllWindows()

cap.release()

python识别简单训练模型_Python3+OpenCV实现简单交通标志识别相关推荐

  1. 【交通标志识别】基于matlab GUI BP神经网络交通标志识别系统(含语音报警)【含Matlab源码 2240期】

    ⛄一.BP神经网络交通标志识别简介 道路交通标志用以禁止.警告.指示和限制道路使用者有秩序地使用道路, 保障出行安全.若能自动识别道路交通标志, 则将极大减少道路交通事故的发生.但是由于道路交通错综复 ...

  2. 【交通标志识别】基于模板匹配算法实现限速交通标志识别附matlab代码

    1 简介 为实现限速交通标志的快速准确识别,采用模板匹配对限速交通标志进行识别.首先图像进行倾斜校正,并在HSV颜色空间进行分割,提取感兴趣区域(ROI),然后利用垂直投影分割字符,最后通过和模板字符 ...

  3. 人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练

    人工智能深度学习框架MXNet实战:深度神经网络的交通标志识别训练 MXNet 是一个轻量级.可移植.灵活的分布式深度学习框架,2017 年 1 月 23 日,该项目进入 Apache 基金会,成为 ...

  4. YOLOv4目标检测实战:中国交通标志识别

    课程目标:掌握使用YOLOv4进行TT100K数据集上的中国交通标志识别 课程链接:https://edu.csdn.net/course/detail/29362 课程演示环境:Ubuntu 需要学 ...

  5. Python3+OpenCV实现简单交通标志识别

    由于该项目是针对中小学生竞赛并且是第一次举行,所以识别的目标交通标志仅仅只有直行.右转.左转和停车让行. 整体流程如下: 数据集收集(包括训练集和测试集的分类) 图像预处理 图像标注 根据标注分割得到 ...

  6. 基于OpenCV的交通标志识别

    前几天看新闻得知微软为美国执法机关研发了一套基于AI识别,追踪并提取编辑视频中出现的人脸的算法,只要输入一段带人脸信息的视频文件,运行后即可输出一段所有人脸已被提取并且按要求编辑好的视频文件.当然该算 ...

  7. Opencv交通标志识别

    文章目录 前言 效果预览 数据集下载地址 训练模型 模型预测 项目结构及源码下载 前言 本文使用的数据集包含43种交通标志,使用opencv以及卷积神经网络训练模型,识别交通标志,使用pyqt5制作交 ...

  8. opencv交通标志识别_教你从零开始做一个基于深度学习的交通标志识别系统

    教你从零开始做一个基于深度学习的交通标志识别系统 基于Yolo v3的交通标志识别系统及源码 自动驾驶之--交通标志识别 在本文章你可以学习到如何训练自己采集的数据集,生成模型,并用yolo v3算法 ...

  9. Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow)

    项目介绍 TensorFlow2.X 搭建卷积神经网络(CNN),实现交通标志识别.搭建的卷积神经网络是类似VGG的结构(卷积层与池化层反复堆叠,然后经过全连接层,最后用softmax映射为每个类别的 ...

最新文章

  1. python字符串应用
  2. webstorm中配置svn
  3. java线程池参数面试题,附赠复习资料
  4. python配置opencv镜像安装
  5. 机房线路故障,引发多家公司不能上网,和自己de经历有感
  6. 小米“祭出” AIoT 神器!| 技术头条
  7. python中int的用法归类
  8. 深入浅出设计模式 ------ Prototype(原型模式)之深度克隆
  9. FTTP/FTTH理想解决方案(组图)
  10. Himawari-8数据下载及命名
  11. matlab学霸表白公式,【爱情物理学】520来了,看看理科学霸们创意的表白方式
  12. 红米K30S至尊纪念版和小米10至尊纪念版的区别
  13. 刮刮奖效果的简单实现
  14. SECTION 15 函数和函数式编程(二)
  15. (四十二)模态框的使用
  16. htc 8x android,颠覆之作的探究,HTC 8X拆解多图欣赏
  17. 动画一:过渡(超详细!)
  18. 安霸Alberto Broggi :计算机视觉技术驱动自动驾驶的发展 | 2019 AI+智能汽车创新峰会...
  19. 团队第一次作业(软工C#造梦厂)
  20. Echarts图设置好了但是在页面无法显示问题

热门文章

  1. (22)通过代码修改PTE实现挂物理页
  2. 生成有控制台的WIN32程序
  3. Python PIL库总结
  4. 2021夏季每日一题 【week4 完结】
  5. Spring RabbitMQ使用
  6. JavaScript的鼠标事件
  7. python 组合数据类型_【Python】组合数据类型
  8. 【LeetCode每周算法】两数相加
  9. IntelliJ IDEA 编译错误,提示 Compilation failed: internal java compiler error或java compiler failed
  10. 算法--微软面试:指定数字在数组中出现的次数