美文网首页
手把手教你如何利用树莓派和机器学习3D打印DIY一个车牌读取器

手把手教你如何利用树莓派和机器学习3D打印DIY一个车牌读取器

作者: 图像算法 | 来源:发表于2020-03-03 22:02 被阅读0次

    作者一直特斯拉迷,特斯拉的自动驾驶能力非常的酷,虽然没钱买,近来一直想让汽车能够检测和识别物体的想法,所以只能自己动手尽力一半实现该梦想。

    作者记录了项目中的每个步骤。

    步骤1.确定项目范围

    首先要考虑的是系统应该有什么。作者一直相信小做起总是最好的策略:循序渐进。所以,除了明显的车道保持任务(每个人都已经完成了)之外,作者只考虑在驾驶时清楚地识别车牌。识别过程包括两个步骤:

    车牌检测

    识别每个车牌边界内的文本

    如果我们能做到这一点,那么其他任务应该相当容易(比如确定碰撞风险、距离等)。甚至可以创建环境的矢量空间表示,这可能是一个不错的选择。

    在过分担心细节之前,我们需要知道两件事:

    一种以未标记图像为输入并检测车牌的机器学习模型。

    硬件。简言之,我们需要一个计算机系统,可以链接到一个或多个摄像头来查询我们的模型。

    首先,我们着手建立正确的目标检测模型。

    步骤2.选择正确的模型

    经过仔细研究,笔者决定采用以下机器学习模式:

    YOLOv3这是迄今为止速度最快的模型,它的地图可以与其他探测物体的高级模型相媲美。

    文本检测器用于检测图像中的文本。

    CRNN基本上是一个递归卷积神经网络(CNN)模型。卷积神经网络必须是递归的,因为它需要能够以正确的顺序排列检测到的字符以形成单词。

    这三种模式将如何协同工作?操作流程如下:

    首先,YOLOv3模型检测从摄像机接收到的每个帧中每个车牌的边界框。建议不要非常精确地预测边界框,最好包含比检测到的对象更宽的边界。如果太窄,可能会影响后续进程的性能。这是对下面模型的补充。

    CRAFT文本检测器接收来自YOLOv3的裁剪后的车牌。现在,如果裁剪后的帧太窄,很可能会丢失部分车牌文本,预测将失败。然而,当边界框较大时,我们可以让工艺模型检测字母的位置。这给了我们每个字母一个非常精确的位置。

    最后,我们可以将工艺中每个单词的边界框传递给我们的CRNN模型来预测实际单词。

    有了基本的模型架构,我们就可以把它移到硬件上。

    第三步.硬件设计

    我们需要低功耗的硬件,如树莓派。它有足够的计算能力以相当大的帧速率预处理帧,并且有一个Pi摄像机。Pi相机是树莓派的实际相机系统。它有一个很棒的支持库,而且非常成熟。

    在网络接入方面,我们可以提供EC25-E 4G接入,也可以嵌入GPS模块。关于Raspberry Pi接入4G网络的文章可以在这里阅读:

    https://www.robertlucian.com/2018/08/29/mobile-network-access-rpi/

    我们先从外壳开始,把它挂在汽车的后视镜上。它应该工作得很好。让我们设计一个由两部分组成的支撑结构:

    覆盆子Pi+GPS模块+4G模块将放置在后视镜的一侧。以上文章可以在EC25-E模块上查看,查看所选的GPS和4G天线。

    另一方面,圆周率摄像机是由一个带有球关节的手臂固定的。

    这些支架或外壳使用可靠的Prusa i3 MK3S 3D打印机打印。

    图1 树莓派+4G/GPS防护罩的外壳

    图2 带有球形接头用于定向的Pi摄像机支架

    图1和图2显示了呈现时的结构。请注意,C-mount是可插入的,因此覆盆子Pi case和Pi camera支持不会随mount一起打印。他们有一个插有支架的插座。如果读者决定复制项目,这将非常有用。你只需要调整后视镜支架就可以在车上工作了。目前,这个展台在一辆路虎自由客汽车上运行良好。

    图3 Pi 相机支撑结构的侧视图

    图4 Pi相机的支撑结构和RPi支架的前视图

    图5 摄像机视野的富有想象力的表示

    图6 包含4G / GPS模块、Pi摄像头和树莓派的嵌入式系统的特写照片

    显然,这些模型需要一些时间,需要多次迭代才能得到一个坚实的结构。使用200微米高的PETG材料层,PETG可以在80-90摄氏度下很好地工作,并且具有很强的抗紫外线辐射能力。虽然不如阿Sa,但它有很高的强度。

    这是在SolidWorks中设计的,因此所有SLDPRT/SLDASM文件以及所有STL和gcode都可以在下面的链接中找到,或者您可以使用它们打印版本。

    https://www.dropbox.com/sh/fw16vy1okrp606y/AAAwkoWXODmoaOP4yR-z4T8Va?dl=0

    第四步.训练模特

    一旦你有了硬件,你就可以开始训练模型了。

    最好不要重新发明轮子,尽可能多地重用工作。这都是关于转移学习利用其他非常大的数据集的分析。几天前,作者读到一篇关于转移学习的相关文章,文章中提到哈佛医学院的一个附属团队能够对模型进行微调,以预测“从胸部X光”的长期死亡率,包括非癌性死亡他们只有一个只有50000张标签图片的小数据集,但是他们使用的预训练模型(Inception-v4)大约有1400万张图片。这比原来的模型花费更少的训练时间和金钱,但是获得的精度仍然很高。

    YOLO3

    很多经过预训练的车牌模型都可以在网上找到,但没有预想的那么多,但其中一个已经训练了约3600幅车牌图像。虽然不多,但总比没有强。此外,它还使用了Darknet的预先训练模型进行训练。我们可以用这个模型:

    https://github.com/ThorPham/License-plate-detection

    作者用VOTT注释了收集的帧(当然还有车牌)。最终的结果是一个由534幅图像组成的小数据集,其边界标记为车牌。数据集链接如下:

    https://github.com/RobertLucian/license-plate-dataset

    然后作者找到了YOLOv3网络的Keras实现。使用它来训练数据集,然后将模型预发布到此存储库,以便其他人也可以使用它。测试集得到的映射为90%,考虑到数据集很小,这是很好的。

    CRNN和CRNN

    在无数次试图寻找一个好的网络来识别文本之后,作者偶然发现了keras ocr,一个打包的灵活版本CRAFT和CRNN。还有他们预先训练过的模特。这项工作非常有效,作者决定不微调模型,让它保持原样。

    最重要的是,使用keras ocr预测文本非常简单。基本上只是几行代码。查看他们的主页了解如何操作:

    https://github.com/faustomorales/keras-ocr

    第五步.部署我的车牌探测器模型

    模型部署有两种主要方法:

    在本地进行所有推理。

    在云中推断。

    两种方法都具有挑战性。

    第一种方法是拥有一个庞大的“大脑”计算机系统,既复杂又昂贵。第二个问题是延迟和基础设施挑战,特别是使用gpu进行推理。

    在这项研究中,作者偶然发现了一个名为cortex的开源项目。它对游戏来说是很新的,但是作为人工智能开发工具的下一个发展方向,它确实有意义。

    基本上,cortex是一个将机器学习模型部署为生产web服务的平台。这意味着我们可以专注于我们的应用程序,剩下的留给Cortex。在这种情况下,它在AWS上执行所有配置,我们只需要使用模板模型编写一个预测器。非常方便,只需为每个模型编写几十行代码。

    这是从GitHub存储库中提取出来的终端中的皮层:

    https://GitHub.com/cortexlabs/cortex

    如果这不美观也不简单,不知道怎么称呼它:

    因为自动驾驶仪不使用这种计算机视觉系统,所以潜伏期对我们来说并不重要,所以我们可以使用大脑皮层。如果它是自动驾驶系统的一部分,那么使用通过云提供商提供的服务不是一个好主意,至少现在不是。

    使用cortex部署机器学习模型只需要两件事:

    定义cortex.yaml文件,这是我们的API的配置文件。每个API处理一个任务。我们指定的yolov3 API用于检测给定帧上的车牌边界框,crnn API用于使用CRAFTtext检测器和crnn预测车牌号。

    为每个API定义预测值。基本上,在cortex中定义了一种特定的预测方法来接收有效载荷(平台已经处理了所有的服务部件),使用有效载荷来预测结果,然后返回预测结果。就这么简单!

    下面是一个经典iris数据集的预测器示例,但它没有详细说明作者是如何做到的(并保持文章的适当长度)。这两个api的cortex实现的链接可以在它们的资源库中找到:这个项目的所有其他资源都在本文的末尾。

    https://github.com/cortexlabs/cortex/tree/master/examples/tensorflow/license-plate-reader

    然后进行预测,你只需要像这样使用curl:

    预测响应看起来像是简单!

    第6步.开发客户端

    我们可以考虑以下架构:

    以适当的分辨率(800x450或480x270)从Pi相机以30 FPS的速度收集帧,并将每个帧放入一个公共队列中。

    在一个单独的进程中,我们从队列中提取帧并将它们分发到不同线程上的多个工作线程。

    每个工作线程(或推断线程)向cortexAPI发出一个API请求。首先,向我们的yolov3API发送一个请求,然后,如果检测到任何许可证,则使用一批裁剪的许可证向我们的crnn API发送另一个请求。响应将包括文本格式的预测车牌号。

    将检测到的每个车牌(带或不带可识别文本)推到另一个队列中,并最终将其广播到浏览器页面。同时,车牌号预测被推送到另一个队列中,然后保存到磁盘(csv格式)。

    广播队列将接收一组无序的帧。它的使用者的任务是通过每次向客户机广播新的帧时将它们放在一个非常小的缓冲区(几个大小的帧)中来重新排序。使用者正在另一个进程上运行。用户还必须尝试将队列上的大小保持为指定的值,以便以一致的帧速率(即30 FPS)显示帧。显然,如果队列大小减小,则帧速率的减小是成比例的,反之亦然,当队列大小增大时,它成比例地增大。最初,作者想实现一个滞后函数,但意识到它会给流一个非常波动的感觉。

    同时,另一个线程正在主进程中运行,它从另一个队列和GPS数据中提取预测。当客户端接收到终止信号时,预测、GPS数据和时间也将被转储到csv文件中。

    下面是与AWS上的Cloud API相关的客户端流程图

    图7 客户端流程图以及随cortex设置的云API

    在我们的例子中,客户端是一个Raspberry-Pi,发送推断请求的Raspberry-Pi和云api由cortex在Amazon Web服务AWS上提供。

    客户端的源代码也可以复制到其GitHub存储库中:

    https://github.com/RobertLucian/cortex-license-plate-reader-client

    我们必须克服的一个特殊挑战是4G带宽。最好减少此应用程序所需的带宽,以减少潜在的挂起或过度使用可用数据。作者决定在Pi相机上使用一个非常低的分辨率:480x270(我们可以使用较小的分辨率,因为Pi相机的视野非常狭窄,所以我们仍然可以很容易地识别车牌)。即使在这种分辨率下,该帧的JPEG大小在10位时仍约为100KB。乘以每秒30帧,得到3000KB,大约24Mb/s,没有HTTP开销,这太大了。

    相反将宽度减小到416像素,这正是YOLOv3模型调整图像大小的宽度。比例显然保持不变。

    将图像转换为灰度。

    删除了图像顶部的45%。当时的想法是,车牌不会出现在车架上,因为这辆车没有在飞行中。据作者所知,裁剪45%的图像不会影响预测器的性能。

    再次将图像转换为JPEG格式,但质量较低。

    生成的帧大小约为7–10KB,非常好。这相当于2.8Mb/s。但是加上所有开销,大约是3.5Mb/s(包括响应)。

    对于crnn-API,即使不应用压缩技术,裁剪后的车牌也不会花很多钱。它们的大小约为2-3KB。

    总之,要以30FPS的速度运行,推理API所需的带宽大约为6Mb/s,这个数字是我们可以接受的。

    结果

    通过大脑皮层进行推理的实时示例。我需要大约20个GPU配置的实例才能顺利运行。根据集群的延迟,您可能需要更多或更少的实例。从捕获一帧到将其广播到浏览器窗口的平均等待时间约为0.9秒,考虑到推断发生在很远的地方,这是非常棒的。

    文本识别部分可能不是最好的,但至少可以证明,通过提高视频的分辨率、减小摄像机的视野或对其进行微调,可以使精度更高。

    对于数量较多的gpu,可以通过优化来减少。例如,将模型转换为使用混合/全半精度(FP16/BFP16)。一般来说,让模型使用混合精度对精度的影响最小,因此我们不会做出太多的权衡。

    T4和v100gpu具有特殊的张量核,在半精度类型矩阵乘法上具有超快速的设计。在T4上,半精度加速度大约是单精度运算的8倍,在V100上,它是单精度运算的10倍。这是一个数量级的差异。这意味着,转换为使用单精度/混合精度的模型可以将推理时间减少8倍,而在V100上,每次减少十分之一。

    作者没有将模型转换为使用单精度/混合精度,因为这超出了项目的范围。就笔者而言,这只是一个优化问题。当Cortex版本0.14发布时(具有真正的多进程支持和基于队列的自动伸缩),作者可能会使用它,因此我们也可以利用多进程web服务器。

    总而言之,如果所有优化措施都得到实施,那么将集群大小从20个GPU实例减少到一个实例实际上是可行的。通过适当的优化,甚至不可能使用单个GPU最大化实例。

    为了使成本更容易接受,在AWS上使用弹性推理可以将成本降低75%,这是非常好的。从视觉上看,您可能有一个管道来实时处理流。不幸的是,Cortex还不支持弹性推理,但由于它已经应用于雷达,我们可以在不久的将来看到它的支持。

    注:YOLOv3和CRNN模型可以通过对更大的数据集(大约50-10万个样本)进行微调而得到很大改进。到那时,您甚至可以进一步减小帧的大小,以减少数据的使用,而不降低准确性:“补偿某处,以便能够将它带到其他地方”。将所有这些模型结合起来使用半精确类型(可能还有弹性推理)可以形成一个非常高效/经济的推理机。

    资源

    3D打印支架的所有SLDPRT / SLDASM / STL / gcode。

    https://www.dropbox.com/sh/fw16vy1okrp606y/AAAwkoWXODmoaOP4yR-z4T8Va?dl=0

    该项目的客户端代码:

    https://github.com/RobertLucian/cortex-license-plate-reader-client

    该项目的cortex实现在这里找到:

    https://github.com/cortexlabs/cortex/tree/master/examples/tensorflow/license-plate-reader

    Keras的YOLOv3模型库:

    https://github.com/experiencor/keras-yolo3

    CRAFT文本检测器+ CRNN文本识别器的库:

    https://github.com/faustomorales/keras-ocr

    车牌的数据集:

    https://github.com/RobertLucian/license-plate-dataset

    Keras(license_plate.h5)和SavedModel(yolov3文件夹/ zip)格式的YOLOv3模型:

    https://www.dropbox.com/sh/4ltffycnzfeul01/AACe85GoIzlmjEnIhuh5JQPma?dl=0

    更多论文地址源码下载地址:关注“图像算法”微信公众号

    相关文章

      网友评论

          本文标题:手把手教你如何利用树莓派和机器学习3D打印DIY一个车牌读取器

          本文链接:https://www.haomeiwen.com/subject/segllhtx.html