AidLux · 2023年04月17日 · 四川

零基础边缘端智慧社区训练营 | Lesson 3

5个课时完成智慧社区AI实战项目!

欢迎大家来到AidLux零基础边缘端智慧社区训练营~

这节课我们会带大家一起完成一个车牌检测识别的项目,其中会用到车牌检测+车牌识别的项目。

因在不同的业务场景中,车牌识别的算法方案是不一样的。

比如在加油站的车牌识别场景中,车占整个图片的比例较小时,则建议在车牌检测前,增加一个车的检测模块。在检测到车后,再对车进行车牌的检测和识别。
ca9b5d75d928b33b151325dda27902f9.png

而在智慧社区或者停车场场景中,相机一般按照在正对车牌的位置,车牌占据图片的比例较大,这样则建议直接对车牌做检测和识别。

这里车牌检测选择常用的yolov5,车牌识别使用的是LPRNet。
569e1ac4964ec0d1ce0600bf0ce776c9.png

所以在本节课我们将训练两个模型,车牌检测的yolov5模型和车牌识别的LPRNet模型,在开始这次课程前,我们先了解下本节课程的内容框架:

1 车牌数据集的下载和说明
2 车牌数据集的整理
3 训练测试环境搭建
4 服务器的训练车牌的检测和识别模型
5 PC端的测试和pipeline推理

(操作演示视频和开发所需资源物料包可在“AidLux”公众号后台回复“训练营”获取)

1. 车牌数据集的下载和说明

因为我们需要训练模型,首先要准备数据集,考虑到智慧社区中,在社区内很少出现工程车辆,所以只需要覆盖大部分的蓝牌和绿牌的场景即可。

最普遍的开源车牌数据集是中科大的CCPD数据集,官网链接是:

https://github.com/detectReco...

中科大车牌数据集有CCPD2019和CCPD2020,其中CCPD2019主要为蓝牌,CCPD2020为绿牌。其中蓝牌是燃油车,绿牌是电动车。

这里我们主要用CCPD2019的蓝牌来作为我们的任务。

大家可以通过官网链接的百度网盘进行下载:
2ff89464c872012f63706656247769d7.png

从官网上下载CCPD2019数据集,得到的文件是这样的。
67584dc52154d346905802f14dd55f48.png

里面有6个文件夹,统计如下:
image.png

打开文件夹,每张图片的标签通过文件名展示。

图片命名:

“0019-1_1-340&500_404&526-404&524_340&526_340&502_404&500-0_0_11_26_25_28_17-66-3.jpg”
60d753abdcf5efa3730458bf365875b0.png

解释:

0019:车牌区域占整个画面的比例;

1_1:车牌水平和垂直角度, 水平1°, 竖直1°

340&500_404&526:标注框左上、右下坐标,左上(154, 383), 右下(386, 473)

404&524_340&526_340&502_404&500:标注框四个角点坐标,顺序为右下、左下、左上、右上

0_0_11_26_25_2_8:车牌号码映射关系如下: 第一个0为省份 对应省份字典provinces中的’皖’,;第二个0是该车所在地的地市一级代码,对应地市一级代码字典alphabets的’A’;后5位为字母和文字, 查看车牌号ads字典,如11为M,26为2,25为1,2为C,8为J 最终车牌号码为皖AM21CJ

省份:[“皖”, “沪”, “津”, “渝”, “冀”, “晋”, “蒙”, “辽”, “吉”, “黑”, “苏”, “浙”, “京”, “闽”, “赣”, “鲁”, “豫”, “鄂”, “湘”, “粤”, “桂”, “琼”, “川”, “贵”, “云”, “藏”, “陕”, “甘”, “青”, “宁”, “新”]

地市:[‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’,‘X’, ‘Y’, ‘Z’]

车牌字典:[‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’,‘Y’, ‘Z’, ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’]

后面我们需要先对图片的标签解析,解析完后才能对其进行训练。

车牌识别的方案主要有两种:

一种是粗粒度的:车牌检测+车牌识别;

另外一种细粒度的:车牌检测+车牌矫正+车牌识别。

后一种方法相对于前一种方法增加车牌矫正的部分,这部分主要考虑在场景中车牌在区域中出现的角度变化,如果是车牌与相机是相对平行的,则不需要矫正。

如果角度过大,则需矫正,这里面一般车牌的水平度和垂直度超过15°,建议增加矫正环节。

这里考虑到智慧社区的车与相机位置可以相对平行固定,故采用前一种方法,而其他如加油站场景中,摄像头因为要兼顾多种场景,不一定能做到平行,需要对车牌矫正后识别,效果更好。
b24e76472613d5a8e0c7422c8cc7e018.png

(1)粗粒度车牌识别:前者我们需要两个标签,车牌两角围成的矩形框做车牌检测训练,车牌号码标签做车牌识别训练。

(2)细粒度车牌识别:后者则需要加上一个标签,即车牌的四个角以及倾斜角,用于车牌矫正训练。

这里我们用的是公开数据集,如CCPD数据集。虽然数据量满足要求,但是其数据集不均衡问题严重。

因为中科大在安徽采集数据较多,其中“皖”字占整个数据集汉字的90%,所以如果是对智慧社区定制化开发,需考虑社区所在的地理位置,针对性采集数据,或者模拟数据,优化模型。

2. 车牌数据集的整理

因为要做两个任务,车牌检测、车牌识别。

所以将车牌数据集整理分成两个部分:一是整理成检测任务需要的数据集,二是整理成车牌识别任务需要的数据集。

首先,我们将所有子文件夹中的图片均放在同一个文件夹中。

如果直接用cp命令,因复制文件较多会报错,所以采用

find file/ -name "*.jpg" | xargs -i cp {} destination_path 命令去复制:

(1)首先通过mkdir CCPD_base 创建CCPD_base文件夹,

(2)然后将从官网中下载的CCPD文件夹内的子文件夹的图片均复制到CCPD_base文件夹里(注意:这里复制的子文件夹里面的图片,而不是子文件夹):

将ccpd_blur、ccpd_challenge、ccpd_db、ccpd_fn、ccpd_weather五个文件夹,都拷贝到CCPD_base文件夹中:
cffdebf55380965fedd15d0ef274fbc0.png

注意:这里没有将ccpd_np文件夹复制进去,因为np是未上牌的新车,没有标签(如果因为手误复制进去也没关系,后期我们会对其过滤)。

复制完后,我们在ccpd_base文件夹下面查看文件个数:

ls -l |grep "^-"|wc -l
36cc92d224fe0cfe6fb48fea1083737c.png

可以看到,里面一共有84280个图片文件,这里我们发现只有图片文件,没有标注文件,这个数据集是将车牌的标注信息都以文件名的方式标注,所以,后面我们需要对文件名解析,完成车牌数据的标签制作。

2.1 车牌检测数据集

对于检测任务,考虑数据集庞大和防止出错,我们会将其分成两个步骤。
(1)简单验证:先将几张图片标签转成yolo文件,并通过yolo转成voc xml格式,用labelimg打开校验。
(2)批量转换:确认转换的方式没有问题后,将所有标签直接转换成yolo格式保存。
其中转成yolo格式的代码如下,即大家下载第三节课资源中的tools/ParaseData.py
85917d5655cdfd89d6a8ba7e92dcbf31.png

Yolo转voc xml格式的代码如下:
8dc20162c325553d61ff398aa1bd979f.png
a0ee05657daa6b1c89b871c97fe52b93.png
3712403cdbc8627f863759708ece09f6.png

上面的整个代码不需要调整,主要修改下面代码中的图片和txt的路径:
02e3d4fddda52fe15abeb6687ed18293.png

(1) 简单验证
我们先新建一个images文件夹,然后从图片集中随机找出几张图片,放到images文件夹中。

在上方的代码中,将imaged_dir,修改成images的路径,将validation 改成True,将txt_dir, xml_dir改成你所保存的路径。

运行python后,可以得到两个文件夹,一个是labels文件夹,一个是xml_labels文件夹。
a5a3fff03489c2bf279e24bbf8fc0bc8.png

在第一次在images文件夹下面放入几张车牌图片,将Validation设置成True,运行 python label.py后,会生成以下文件夹:

其中labels文件夹里存储的为对应图片的车牌检测标注框的yolo格式的txt标签文件,主要用于训练用。

xml_labels文件夹里面存储的为对应图片的车牌检测标注框的voc格式的标签文件,主要用于可视化车牌标注框的标注,看是否解析正确。(注:因为后期制作,将文件夹名字改了,实际上这里的images对应着上述的ccpd_base文件夹)
db31d2efc2c2f6b1659f87027b098161.png

用labelimg打开images文件夹,并查看xml_labels结果,对labelimg的安装和使用不了解的,可以看江大白的前次课程:
deeaa26da0b88ca7a9e0329738021c67.png

(2)批量转换
这样在确认标签的解析没有问题后,将validation设置成False,修改图片路径和保存txt路径:
6f64955518a3e3f46bdec45f20b0bf17.png

将image_dir 和txt_dir设置成训练验证的数据集路径,运行后结果如下:
c2c33f79871fb2d956da074dd80eddfd.png
d109cbe73e9129e0116b6b4b79f3a78e.png

为了让后面的yolov5框架更好的解析代码,这里将图片文件夹命名为images,txt的标签文件夹命名为labels:
4584d4c77a27d5833c4a89c76df759d7.png

(3)随机挑选
考虑后期训练时长等因素,这里将八万多张的数据,大刀从里面随机抽取1w张来做为训练集,方便大家将整个流程先走完。

后期如果觉得效果不好,可以按照同样的步骤把8w张数据重新训练。
随机抽取代码如下,即代码文件中的tools/cp10000.py:
f6c7a7c767bfc9723ee8f6788169b742.png

2.2 车牌识别数据集

上面我们了解了对抗防御的场景应用,接下来我们再了解一下目前主流对抗防御的总体分支与逻辑:

对于任务二,需对车牌号码做解析,在tools/ccpd2lpr.py文件下,将路径换成自己的路径:
6c729584a8ef3bb762645bf5acf641b3.png

运行python ccpd2lpr.py 后:
df60fb6efbe034114b0e3e7b5831cc3c.png

则表示已经完成数据集的整理。

在image_rec文件夹下生成以车牌号为文件名的图片集:
be30737fb00fb056d4de391d47ec96bd.png

3. 训练测试环境搭建

在对数据集完成预处理后,我们带大家一起训练模型。

对于检测模型,我们选用工业界比较常用的yolov5框架,对车牌识别,选用比较成熟的LPRNet架构。

3.1 云服务器的注册

考虑到有的同学没有GPU训练,为了完整的走完整个流程,我们可以在AutoDL平台上使用云服务器。官网地址为:https://www.autodl.com/home

首先点击右上角的”注册有礼”按钮进行注册。
94c6178934e4ca2fe97bc9d61e2ac892.png

在注册完成后,点击左上角的”算力市场”,会看到有很多地区和空闲的GPU型号,每个GPU型号的算力不同,大家可以根据自己的需要选择。在注册会员时,会赠送10元的代金券,在训练模型时,应该是足够的。
67965d84454384cf8915f1e7340e20b8.png

3.2 云服务器的网盘数据上传

先不着急创建服务实例,因为创建后,会按创建的时间计费,而我们的准备工作还没做完。

在创建服务器前,我们需要将代码和数据上传到云网盘上,这样做的目的是上传到云网盘上的数据在实例服务结束后,不会被销毁。

而如将代码和数据放到创建的实例服务上的话,在实例服务结束后,该服务被销毁,在里面的数据也会一起被销掉。

这里使用的是北京A区的GPU与网盘。
9d48847623671754eedb3881e2afec60.png

在右上角可以看出网盘支持的字样,则说明该gpu服务器的网盘是可用的。

点击右上角的控制台按钮,进入我的管理。
65c93860da53091beaa3a078fc991e55.png

点击左侧的我的网盘,选择北京A区→初始化网盘:
437086935288916ef099d43af0ebe279.png

在初始化网盘后,点击上传按钮,将我们数据集和训练测试代码上传上去。

(1) 车牌检测的数据集

为了方便上传,将车牌检测的数据集压缩成ccpd10000.zip,大家下载的Lession3_code文件夹中,大刀已经将其压缩,plate_detection_data.zip中主要包含了车牌检测训练所需的数据。

(2) 车牌识别的数据集

将车牌识别的数据集压缩成data_plate_recognization.zip,也放在了Lession3_code文件夹下了。data_plate_recognization.zip中包含了车牌识别训练所需要的数据。

(3) 车牌检测+识别的训练代码

将code_plate_detection_recognization的训练代码,压缩成code_plate_detection_recognization.zip代码。

里面是车牌检测和车牌识别的训练、验证和测试代码。
f8c83995401e1df2de8621819d0603b1.png

3.3 云服务器的创建实例

以上,我们的准备工作算完成了,现在开始创建云服务器实例,返回左上角的“算力市场”,如这里,我们选择了与网盘区域相同的北京A区1张RTX3090的卡,下端会显示该区域有哪些可用:
c196c5b329c6b9965e625455ac8eef7f.png

选择某个服务器,点击蓝色的“1卡可租”按钮,进入页面:
75ba004ad584e0da830b7ae474a34f90.png

这里的镜像可以配置基础镜像,如pytorch1.7.0/python3.8/cuda11.0。当然这里面有配置热门镜像如yolov5,选择yolov5镜像。

点击立即创建,这时右上角可能会有弹窗:
30bd11cb603b8fad0efe904f038ab921.png

如果出现这种问题,则返回上个页面重新选择北京A区的算力后,按照上述步骤,继续创建直至创建完成,会跳转到下一个页面:
172f892ad4b49e12ccac69cbf81858c5.png

等到状态栏从“创建中”→“开机中”→“运行中”,则可以开始运行了。
7b81665c78db6df7b6e404c7f96ff4f7.png

点击快捷工具栏中的JupyterLab,进入控制页面。

点击“其他”下面的“终端”按钮,就会打开一个终端页面。
63f2fc6cf3aa540e9fe636eab1fd5abf.png

如果需要多个终端,则需要点击左上角的“+”号键,和上个步骤相同,增加几个终端页面,这里新增了3个终端页面。
2b2880d6cf20f56fa1e8c29204a28386.png

进入终端页面后,显示有系统盘、数据盘和网盘三个盘,我们的数据放在网盘中。

运行cd /root/autodl-nas进入网盘,我们刚刚存放在网盘里面的数据就保存在里面。
c2f24cc6ae93abbf36015e9b45832a48.png

使用unzip 命令解压三个文件夹:
d235eaac677f0c4ea7ca5f13d07607fb.png

解压后的目录如下:
9e7cc0c649b006465f49f648e0db1e66.png

4. 服务器训练车牌的检测和识别模型

4.1 数据集的划分:

解压完成后,我们就有了车牌检测的代码和数据,现在传入的数据已经是yolov5格式txt标签数据,除此之外,我们需要对传入的数据完成train:val的划分。

首先检测数据集目录下,pwd命令获取当前目标的路径,选择路径,crtl+c复制。
312dedafb78a255be4ffbad61396d402.png

第二步,进入代码目录下的tools文件夹下,vim split_train_val.py:
393d1294bf197cc6d6a12a1908b17429.png

按“a”键,左下角出现INSERT,
0920a1d4b33894635abcb03768345fc4.png

进入编辑模式,按键盘上的上下键,跳转到需要修改的地方,将上述ctrl+C的目录,ctrl+v粘贴到指定位置:
4b16a7fbdadbfc563c9cb2a30a83cadc.png

再通过先按ESC退出键,再通过”:wq!”四个按键保存文件强制退出,跳出编辑页面。

通过python split_train_val.py命名运行:
18a881457476f37d3e1348febf7bcd73.png

进入到目标检测的数据集里,看2007_train.txt和2007_val.txt两文件是否生成:
14ea3112b0b1555f21932e7f7c942c8f.png

Txt里保存了训练集和验证集的图片路径, 通过cat 2007_val.txt查看:
e4ea3ebf58a2fab8ab14f69061a28afc.png

4.2 车牌检测训练配置设置
(1)修改训练数据集参数

进入code环境下,配置参数,首先是数据参数,在data文件夹下面打开ccpd.yaml文件,vim进入plate.yaml文件中,修改训练集和验证集路径,和类别数以及类别标签。
5bb868e7e58fe6ce4f71277a8698d2ae.png
0f52b08ecc375bbe660c89708f8d5d31.png

(2)修改网络参数配置
364f757b0101949aecf401b57e43a1a9.png

(3)修改训练参数配置
e24247675a970ecd83afe925accd2a43.png
0c7999d2ed1957b58e2f418171b557bf.png

4.3 训练车牌检测模型

输入 python tools/train_yolov5.py
5497d63d1053d25fda141e46e23f868e.png

报错如下:
ed0732eac65046adaa9b873ce3c055a5.png

将tools 文件夹下面的train_yolov5.py的代码移动到主目录下面,运行python train_yolov5.py:
e288a775e7ae19b96b2e412ca1fc0c55.png

又报错:
6ba030441dc6fa994f7c20f2845247ef.png

修改yolo.py 文件下的代码:
27e211ea04e7352ce3c5097233a816f3.png

增加红框一行:
8f3cefd5c4fd8784365ec895cec1bb8b.png

再次运行:
32aa7df469bbc237c738619116401067.png

点击左侧栏中runs 目录下面的任务文件夹,即可看到训练完后的模型
ab1bd994456b35d1184ce142d52347e2.png

在训练完成后,打开我的网盘,下载训练的pt模型至本地。
bdb42de21864a3eb44cd86d2a4d0011a.png

4.4 训练车牌识别模型:

1. 训练集和测试集划分

首先image_rec识别数据集目录下,通过。

第二步,进入代码目录下的tools文件夹下,vim split_train_val.py:
393d1294bf197cc6d6a12a1908b17429.png

按“a”键,左下角出现INSERT,
0920a1d4b33894635abcb03768345fc4.png

进入编辑模式,按键盘上的上下键,跳转到需要修改的地方,将上述ctrl+C的目录,ctrl+v粘贴到指定位置,将detection改成False
a3a7fad944049918a417372e036f13ef.png

再通过先按ESC退出键,再通过”:wq!”四个按键保存文件强制退出,跳出编辑页面。

通过python split_train_val.py命名运行:
18a881457476f37d3e1348febf7bcd73.png

进入到数据集里,看train和val两文件夹是否生成:
58f0508eafc3c339bc042b4282efe653.png

进入train 文件夹下面,查看发现生成7923张训练集
158b1996f0d7f360c9b0df4dde954ec5.png

  1. 配置训练参数,vim train_lprnet.py ,主要修改训练和验证的文件夹目录,其他的参数按需修改。
    2b7dde4284b1420616121358951f75d7.png

训练模型:

运行python train_lprnet.py :
dbffad16b1e35260fa21884f83e8c29f.png

出现以上的情况则表示开始训练后,在训练后在weights 文件夹下面会有lprnet_best.pth的权重文件。

5. PC端的测试和pipeline推理

为了完成车牌检测的测试,这里在PC端,大刀在windows系统下,在一个无环境的电脑上安装推理环境,因为电脑的硬件限制,这里使用的是cpu做推理。

Vscode打开代码detect_yolov5.py文件,修改配置参数:

主要修改228行的权重文件路径,229行的测试数据集路径:
0b45d4c659df45a3b6b24892e9d006d7.png

点击上面的“终端”,点击“运行任务”:
b214974760562776e93b657c2f83d89e.png

发现右下角出现弹窗,为python没有安装:
cc0e596aa30e912f6806886738f5dc88.png

点击左侧栏上的拓展按钮,在拓展商店里安装python:
e171e853b50e35c0425d05113a49e7d1.png

安装成功的python显示如下:
c1a0d1d59faa3a72c22a73884a49a9b4.png

在终端窗口,继续运行:
6addb6e1ce1e1d51791e2ab553e6aaa3.png

安装库:

Pip install –r requirement –i https://pypi.mirrors.ustc.edu...(因为硬件上无gpu,如果有的话需要安装cuda版本后,安装torch-gpu)

安装完后,修改detect_yolov5.py中的路径后:
5e03c69d5956dd114da0e6ad7aa93a36.png

在终端输入python detect_yolov5.py文件后:
bd0e1b3c2a7a67b3968173e82caed7be.png

输出结果在demo/detect_results 里面的结果,可以看到车牌检测的结果:
1e682f8d1b49681b5717b67c7eec3261.png

这里需要说明一下test_lprnet.py,车牌识别作为车牌检测的下游任务,其输入图片需要将检测到的裁剪车牌。
416e43ac36f27f7afdbb29eff3bf2d33.jpg

同理,通过python detect_torch_pipeline测试车牌识别的整体效果。
42f5775b35798efbee1fbf26ab47121e.png
c597f15fd9f11f4231ed3e498aeaaa0c.png

6.课堂小结

以上为车牌检测和识别的前期数据集整理、训练和推理测试部分,在工作中,大家如果训练车牌检测和识别,主要的要修改的点会花在数据集的匹配和预处理,在模型训练过程中主要是对一些超参的调优,同时后面在对bad case分析后的算法迭代,希望对大家有帮助。

下一节课,我们将对上述pc端推理的车牌识别,在移动Android端完成部署,我们下节课见。

大家可以在AidLux公众号后台回复“训练营”,获取本次(智慧社区)训练营所需物料资源包,以及智慧安防、智慧交通训练营全部课程内容及对应资源包。

也可以添加AidLux小助手好友,申请加入AI开发者交流群,群内有AidLux工程师和江大白、Rocky等众多AI行业专家,可以给予技术指导以及进行交流互动。
d20fee1ebecbda16b5148e607e77c1a3.jpg

推荐阅读
关注数
5
内容数
54
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息