基于深度学习的车牌识别(YOLOv5和CNN)

基于深度学习的车牌识别(YOLOv5和CNN)

目录

一、综述

二、车牌检测

一、综述

本篇文章是面向的是小白,想要学习深度学习上的应用,本文中目前应用了YOLO v5和CNN来对车牌进行处理,最终形成一个完整的车牌信息记录,如果我写的有什么不对或者需要改进的地方,可以私信给我。

我们假设已经获得包含有车牌的照片,那么我们

第一步:是车牌的检测获取车牌的那部分。

第二步:就是对车牌进行拆分成各个字符。

第三步:对于一张车牌的每个字符我们使用CNN得到的模型去预测每个字符

最终得到车牌信息。

二、车牌检测

概括

车牌检测的方法有许多,最初我用的是原始的图像形态学对图像的处理(基于opencv的形态学操作),发现这样的方法不能很好的应用到所有的车牌中。那么我在学习的过程中,其实已经有许多其他方法来实现。比如目标检测,它就是一个很好的方法,主要是可以把这样的方法应用到更多更广泛的应用场景。

目标领域中主要分为如下两个——One-stage和two-stage算法

他们的区别可以查看 目标检测算法基础介绍

首先YOLO系列下的模型都是属于One-stage,在One-stage包括SSD也是很常用的一种方法。

YOLOv5学习视频查看 火爆全网的YOLOv5目标检测项目 从P41开始学习就可以了。

我们这部分有几个前提必须准备好。

1.训练需要的车牌图片数据

车牌数据 我的来自于 中科大建立的CCPD数据集,其他的不要说,总之在学习阶段说一个不错的数据,论文和数据集下载地址:github.com/detectRecog… 以下说数据说明

截屏2022-06-10 22.23.27.png

2.安装YOLOv5模型 YOLO的安装可以直接 去GitHub上下载:github.com/ultralytics… 如果是第一次使用其他人模型,第一次都会有不知所措,但一旦掌握了其中一个,其他是类似的。比如图像分割中的U-net,ocr模型中PaddlePaddleOCR都是差不多的用法。

(1) YOLO文件中需要修改某些文件

在我的目录中,我将YOLO下载到与car文件夹的同目录下

我们需要关注YOLO文件夹下的几个文件,这是我的文件目录

截屏2022-06-10 21.02.39.png

我们要自己首先一个yaml文件来配置YOLO模型,图中化横线的文件 car.yaml

以下是我的简单的配置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 path:图片数据的根目录

train:训练集的绝对路径,这里存放是所有图片的绝对路径

val: 验证集的绝对路径,与train一样

nc:分类个数

names:列表类型 所有类别名字 license plate 车牌

(2)预使用模型 YOLO已经给出以下模型 我们可以在他们这些模型的基础上进行训练自己的模型

截屏2022-06-10 21.10.29.png

我使用的是占内存比较小,准确率不错的yolov5s.yaml 详细其他模型有什么区别可以去官网去查看:github.com/ultralytics…

yolo5s.yaml 文件我们需要简单的进行修改,从而满足我们自己项目的需求

截屏2022-06-10 21.15.32.png

在我的项目中只有一个车牌需要关注,所以我们需要将nc的个数改为1,其他参数我们不需要修改。

好,YOLO文件夹下内容,暂时不需要修改了。

图片数据分析

数据的目录是如图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们简单的使用 ccpd_base 文件夹,图片很多,考虑电脑实际情况,我只选取其中任意的5000张照片来作为数据源。

ccpd_base文件内容如下

截屏2022-06-10 14.59.57.png

先建立文件夹结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

markdown
复制代码
carimages放入数据集照片5000张labels等会儿说到

详细查看第一个图片名字

数据中有详细的解释文件名字的意思 截屏2022-06-10 15.03.57.png

第一张图片名字是:01-86_91-298&341_449&414-458&394_308&410_304&357_454&341-0_0_14_28_24_26_29-124-24.jpg

less
复制代码1) 01为区域,2) 86_91 对应两个角度, 水平86°, 竖直91°3) 298&341_449&414对应边界框坐标:左上(298, 341), 右下(449, 414)4) 458&394_308&410_304&357_454&341对应四个角点坐标5) 0_0_14_28_24_26_29-124-24为车牌号码 映射关系如下: 第一个为省份0 对应省份字典皖, 后面的为字母和文字, 查看ads字典.如0为A, 22为Y....

现在对于我们这个阶段我们用到四个点的坐标。

代码如下 Car_Model:

ini
复制代码
import os
import numpy as np
# 访问图片获得图片名字的字符
def load_files(path, cuted=False): # cuted=False 可以不需要写total_info = []car_numbers = []   # 车牌号码angels = []         # 倾斜角度areas = []          # 区域positions = []      # 车牌四个角的位置areas_positions = []  # 车牌左上和右下区域位置for i, j, names in os.walk(path):# 假设现在已经获得了路径# 首先要删除前面没有用的路径,现在获得的是一个strfor name in names:if len(name) < 50:continueif cuted is True:path = name.split("-", 5)areas.append(path[0])angels.append(path[1])areas_positions.append(path[2])positions.append(path[3])car_numbers.append(path[4])else:total_info.append(name)if cuted is True:    # 其他情况下可能需要得到每段信息,可以不需要total_info.append(areas)total_info.append(angels)total_info.append(areas_positions)total_info.append(positions)total_info.append(car_numbers)total_info.append(names)return total_info

因为YOLO对于图片有要求,我们要对图片相关对文件进行一定的改变。

通常我们需要对图片进行标注,通常使用labelme工具来进行图片标注 以下是常用图片标注工具的对比,对于目标检测我们使用labelme就可以了。

blog.csdn.net/sinat_29957…

这个标注是把图片中的车牌框选出来,从而成为一个json文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

框中的数据就是一个车牌左上点(x1,y1)和右下点数据(x2,y2),我们需要取出这些数据出来。

但对于我们的中科大CCPD数据而言,这些数据已经写在文件名字中了,我们只需对名字进行处理,满足YOLO的一个要求。

文件名Car_data.py

ini
复制代码
import os
import Car_Model
import numpy as np
from PIL import Image
DATA_PATH = "/Users/pengpeng/Resources/Python/ccpd_base/car"# 处理文件名中的4个点坐标,并且满足YOLO要求
def process_position(data, data_name):for name, title in zip(data[3], data_name):yolo_data = []bounding_boxes = name.split("_", 4)real_positions = []image_name = []title1 = title.split('.', 2)image_name.append(title1[0])# 获得4个点数据for bbox in bounding_boxes:values = bbox.split("&", 1)for index in range(len(values)):values[index] = int(int(values[index]))real_positions.append(values)real_positions = np.int0(np.array(real_positions))# 得到整个最大的值Xs = [i[0] for i in real_positions]Ys = [i[1] for i in real_positions]x1 = abs(min(Xs))x2 = abs(max(Xs))y1 = abs(min(Ys))y2 = abs(max(Ys))'''YOLO要求这个框满足以下要求(1)需要这个框的中心坐标位置,宽度(width)和高度(height)(2)每个值必须在0-1之间的小数,所以需要进行归一化(3)还需要对每个框进行标注属于哪一个分类, 按照 分类 x, y,w,h 这五个值进行写入(4)需要对一张照片所有的框进行新建一个txt文件,存取以上内容'''# 获得图片信息,获得图片大小分别是width和heightimg_path = DATA_PATH+"/images/"+titleimg  = Image.open(img_path)imgSize = img.sizeimg_width = imgSize[0]img_height = imgSize[1]# 进行归一化,直接把这些内容copy就可以了dw = 1. / img_width # 1/wdh = 1. / img_height  # 1/hx = (x1 + x2) / 2.0 - 1  # 物体在图中的中心点x坐标y = (y1 + y2) / 2.0 - 1  # 物体在图中的中心点y坐标w = x2 - x1  # 物体实际像素宽度h = y2 - y1  # 物体实际像素高度x = x * dw  # 物体中心点x的坐标比(相当于 x/原图w)w = w * dw  # 物体宽度的宽度比(相当于 w/原图w)y = y * dh  # 物体中心点y的坐标比(相当于 y/原图h)h = h * dh  # 物体宽度的宽度比(相当于 h/原图h)# 把这五个值写入到文件中yolo_data.append([0, x, y, w, h])yolo_data = np.array(yolo_data)# 保存bbox的图片信息np.savetxt(os.path.join(DATA_PATH, f'labels/{title1[0]}.txt'),yolo_data,fmt=['%d', '%f', '%f', '%f', '%f'])if __name__ == '__main__':total_infos = Car_Model.load_files(DATA_PATH, True)title = Car_Model.load_files(DATA_PATH, False)process_position(total_infos, title)

另一文件processing_character.py

目的是将图片的绝对路径写入train.txt 和test.txt中

ini
复制代码
import os
import random# train所占的比例 70%
train_percet = 0.7# 文件绝对路径 Mac电脑与windows电脑的地址不同,它类似与Linux的地址
path = "/Users/pengpeng/Resources/Python/ccpd_base/car"# car文件夹下的images文件夹
images = "images"# 新建的train.txt和test.txt
names = ["train", "test"]# 访问images文件夹并把绝对地址写入train和test文件中
images_path = os.path.join(path, images)
images_path = os.listdir(images_path)
total_labels = []
for label in images_path:# 因为Mac电脑比较特殊,在每个文件中都有一个名字叫.DS_Store的隐藏文件,必须排除掉这个文件if label ==".DS_Store":continuetotal_labels.append(label)# 按照之前的概率,对数据进行随机
num = len(total_labels)
digit = range(num)
trd = int(num * train_percet)
ted = int(num * (1-train_percet))
trdr = random.sample(digit, trd)  # train_digit_random 
tedr = random.sample(trdr, ted)   # test_digit_random# 分别写入以下两个文件中
ftrain = open(path+'/train.txt', 'w')
ftest = open(path+'/test.txt', 'w')# 根据随机进行分成train和test比例 这个是按照机器学习对train和test进行安排,当然可以按照自己对要求进行调整
for i in digit:name_path = path + "/" + images + "/" + total_labels[i] + "\n"print(name_path)if i in trdr:ftrain.write(name_path)else:ftest.write(name_path)
# 写完文件,要关闭文件
ftrain.close()
ftest.close()

按照顺序执行完以上三个,我们可以得到以下文件包含它的相应内容

截屏2022-06-10 21.50.24.png 截屏2022-06-10 21.50.03.png

截屏2022-06-10 21.50.12.png

完成到这里,我们车牌的检测就已经完成了大半了。

接着是打开我们的terminal或cmd 找到yolo的根目录,我这使用的是anconda的虚拟环境

截屏2022-06-10 21.55.27.png

在命令行上输入以下命令

css
复制代码
python train.py --data car.yaml --cfg models/yolov5s.yaml --weights weights/yolov5s.pt --batch-size 10 --epochs 3
# --data 后面是刚刚写的配置文件 以yolo为根本目录找的文件
# --cfg 使用配置,然后对这个文件进行修改
# --weights 使用模型的权制
# --batch-size 批量大小
# --epochs 简单理解为运行次数

因为使用的是mac m1pro 不能使用pytorch的gpu ,按照现在的2022 6月份 是不能使用的,只能使用cpu。计算时间很长,计算3次的时间是2个小时吧(不记得了)

最终进行简单的炼丹,也能达到一个还行的结果 val_batch0_pred.jpg

这些结果会最终得到一个文件夹存在以下中

截屏2022-06-10 22.15.35.png

这样我们简单的得到一个自己的车牌检测模型。

接着我们要做的就是预测我们检测车牌的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/417424.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

路飞项目--02

补充&#xff1a;axios封装 # 普通使用&#xff1a;安装 &#xff0c;导入使用 const filmListreactive({result:[]}) axios.get().then() async function load(){let responseawait axios.get()filmList.resultresponse.data.results } # 封装示例&#xff1a;请求发出去之前…

AP5101C 高压线性 LED恒流驱动器 DFN2*2 LED灯汽车雾灯转向灯

产品描述 AP5101C 是一款高压线性 LED 恒流芯片 &#xff0c; 简单 、 内置功率管 &#xff0c; 适用于6- 100V 输入的高精度降压 LED 恒流驱动芯片。电流2.0A。AP5101C 可实现内置MOS 做 2.0A,外置 MOS 可做 3.0A 的。AP5101C 内置温度保护功能 &#xff0c;温度保护点为 130 …

linux编译源码,安装valgrind

目录 1 下载源码 2 在虚拟机上解压 3 进入解压的目录&#xff0c;执行make 4 安装 5 检查安装是否成功 本文参考了内存检查工具valgrind介绍、安装与使用-CSDN博客 1 下载源码 我到Valgrind: Current Releases 下载了valgrind 3.22.0源码 2 在虚拟机上解压 我使用的虚…

Leetcode 用队列实现栈

题目&#xff1a; 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int pop() 移除并…

脱离于ASP.NET 和Visual Studio编辑Razor脚本

Razor Pad是一个编辑Razor脚本的工具&#xff0c;脱离于ASP.NET 和Visual Studio。 github地址&#xff1a;GitHub - RazorPad/RazorPad: RazorPad is a quick and simple stand-alone editing environment that allows anyone (even non-developers) to author Razor templat…

智慧工地解决方案及案例:PPT全文26页,附下载

关键词&#xff1a;智慧工地解决方案&#xff0c;智慧工地建设&#xff0c;智慧工地整体架构&#xff0c;数字化工地&#xff0c;智慧工程 一、智慧工地建设对传统建筑业的影响 1、提高了施工效率和质量&#xff1a;智慧工地建设采用了先进的信息技术和管理方法&#xff0c;可…

统计学-R语言-4.6

文章目录 前言列联表条形图及其变种---单式条形图条形图及其变种---帕累托图条形图及其变种---复式条形图条形图及其变种---脊形图条形图及其变种---马赛克图饼图及其变种---饼图饼图及其变种---扇形图直方图茎叶图箱线图小提琴图气泡图总结 前言 本篇文章是对数据可视化的补充…

Linux下安装docker

1、查看系统版本 Docker支持64位版本的CentOS 7和CentOS 8及更高版本&#xff0c;它要求Linux内核版本不低于3.10。查看Linux版本的命令这里推荐两种&#xff1a;lsb_release -a或cat /etc/redhat-release。 显然&#xff0c;当前Linux系统为CentOS7。再查一下内核版本是否不低…

【vite】找不到模块“vite”或其相应的类型声明

今天在用vite搭建项目时&#xff0c;在vite.config.ts文件中 ts报错找不到模块“vitejs/plugin-vue”或其相应的类型声明。 原因&#xff1a;项目中缺少了相应的依赖包或 TypeScript 类型声明。可以按照以下步骤进行检查&#xff1a; 1. 确保安装了相应的依赖包 如果在pack…

KubeSphere 核心实战之二【在kubesphere平台上部署redis】(实操篇 2/4)

文章目录 1、登录kubesphere平台2、redis部署分析3、redis容器启动代码4、kubesphere平台部署redis4.1、创建redis配置集4.2、创建redis工作负载4.3、创建redis服务 5、测试连接redis 在kubesphere平台上部署redis应用都是基于redis镜像进行部署的&#xff0c;所以所有的部署操…

python爬虫知识点:5种线程锁

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 线程安全 线程安全是多线程或多进程编程中的一个概念&#xff0c;在拥有共享数据的多条线程并行执行的程序中&#xff0c;线程安全的代码会通过同步机制保证各个…

spingboot 集成identityserver4身份验证

一、新建项目&#xff1a;com.saas.swaggerdemo 详情见&#xff1a;spring-boot2.7.8添加swagger-CSDN博客 在之前项目基础上添加如下依赖 <dependency><groupId>com.nimbusds</groupId><artifactId>nimbus-jose-jwt</artifactId><version&…