今天给各位分享成品网站源码分享app免费版的知识,其中也会对成品app源码推荐进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
选自towardsdatascience
作者:RobertLucianChiriac
机器之心编译
参与:王子嘉、思、一鸣
闲来无事,我们给爱车装了树莓派,配了摄像头、设计了客户端,搞定了实时车牌检测与识别系统。
怎样在不换车的前提下打造一个智能车系统呢?一段时间以来,本文作者RobertLucianChiriac一直在思考让车拥有探测和识别物体的能力。这个想法非常有意思,因为我们已经见识过特斯拉的能力,虽然没法马上买一辆特斯拉(不得不提一下,Model3现在看起来越来越有吸引力了),但他有了一个主意,可以努力实现这一梦想。
所以,作者用树莓派做到了,它放到车上可以实时检测车牌。
在接下来的内容里,我们将介绍项目中的每个步骤,并提供GitHub项目地址,其中项目地址只是客户端工具,还其它数据集与预训练模型都可以在原博客结尾处找到。
项目地址:
https://github.com/RobertLucian/cortex-license-plate-reader-client
下面,让我们看看作者RobertLucianChiriac是如何一步步打造一个好用的车载检测识别系统。
放一张成品图镇楼。
第一步:确定项目范围
开始之前,我脑海里出现的第一个问题是这样一个系统应该能够做到什么。如果说我活到现在学到了什么,那就是循序渐进——从小处着手永远是最好的策略。所以,除了基本的视觉任务,我需要的只是在开车时能清楚地识别车牌。这个识别过程包括两个步骤:
检测到车牌。识别每个车牌边界框内的文本。
我觉得如果我能完成这些任务,再做其他类似的任务(如确定碰撞风险、距离等)就会容易得多。我甚至可能可以创建一个向量空间来表示周围的环境——想想都觉得酷。
在确定这些细节之前,我知道我得先做到:
一个机器学习模型,以未标记的图像作为输入,从而检测到车牌;某种硬件。简单地说,我需要连接了一个或多个摄像头的计算机系统来调用我的模型。
那就先从第一件事开始吧——构建对象检测模型。
第二步:选择正确的模型
经过仔细研究,我决定用这些机器学习模型:
YOLOv3-这是当下最快的模型之一,而且跟其他SOTA模型的mAP相当。我们用这个模型来检测物体;CRAFT文本检测器-我们用它来检测图像中的文本;CRNN-简单来说,它就是一个循环卷积神经网络模型。为了将检测到的字符按照正确的顺序排成单词,它必须是时序数据;
这三个模型是怎么通力合作的呢?下面说的就是操作流程了:
首先,YOLOv3模型从摄像机处接收到一帧帧图像,然后在每个帧中找到车牌的边界框。这里不建议使用非常精确的预测边界框——边界框比实际检测对象大一些会更好。如果太挤,可能会影响到后续进程的性能;文本检测器接收YOLOv3裁剪过的车牌。这时,如果边界框太小,那么很有可能车牌文本的一部分也被裁掉了,这样预测结果会惨不忍睹。但是当边界框变大时,我们可以让CRAFT模型检测字母的位置,这样每个字母的位置就可以非常精确;最后,我们可以将每个单词的边界框从CRAFT传递到CRNN模型,以预测处实际单词。
有了我的基本模型架构草图,我可以开始转战硬件了。
第三步:设计硬件
当我发现我需要的是一种低功耗的硬件时,我想起了我的旧爱:树莓派。因为它有专属相机PiCamera,也有足够的计算能力在不错的帧率下预处理各个帧。PiCamera是树莓派(RaspberryPi)的实体摄像机,而且有其成熟完整的库。
为了接入互联网,我可以通过EC25-E的4G接入,我以前的一个项目里也用过它的一个GPS模块,详情可见:
博客地址:https://www.robertlucian.com/2018/08/29/mobile-network-access-rpi/
然后我要开始设计外壳了——把它挂在汽车的后视镜上应该没问题,所以我最终设计了一个分为两部分的支撑结构:
在后视镜的方向上,树莓派+GPS模块+4G模块将保留下来。关于我使用的GPS和4G天线,你可以去看一下我关于EC25-E模块的文章;在另一侧,我用一个利用球关节活动的手臂来支撑PiCamera
我会用我可靠的Prusai3MK3S3D打印机来打印这些零件,在原文文末也提供了3D打印参数。
图1:树莓派+4G/GPS壳的外形
图2:利用球关节活动臂支撑PiCamera
图1和图2就是它们渲染时候的样子。注意这里的c型支架是可插拔的,所以树莓派的附件和PiCamera的支撑物没有和支架一起打印出来。他们共享一个插座,插座上插着支架。如果某位读者想要复现这个项目,这是非常有用的。他们只需要调整后视镜上的支架就可以了。目前,这个底座在我的车(路虎Freelander)上工作得很好。
图3:PiCamera支撑结构的侧视图
图4:PiCamera支撑结构和RPi底座的正视图
图5:预计的相机视野
图6:内置4G/GPS模块、PiCamera,树莓派的嵌入式系统近照
显然,这些东西需要一些时间来建模,我需要做几次才能得到坚固的结构。我使用的PETG材料每层高度为200微米。PETG在80-90摄氏度下可以很好地工作,并且对紫外线辐射的抵抗力很强——虽然没有ASA好,但是也很强。
这是在SolidWorks中设计的,所以我所有的SLDPRT/SLDASM文件以及所有的STLs和gcode都可以在原文末找到。你也可以用这些东西来打印你自己的版本。
第四步:训练模型
既然硬件解决了,就该开始训练模型了。大家应该都知道,尽可能站在巨人的肩膀上工作。这就是迁移学习的核心内容了——先用非常大的数据集来学习,然后再利用这里面学到的知识。
YOLOv3
我在网上找了很多预先训练过的车牌模型,并没有我最初预期的那么多,但我找到了一个在3600张车牌图上训练过的。这个训练集并不大,但也比什么都没有强。除此之外,它也是在Darknet的预训练模型的基础上进行训练的,所以我可以直接用。
模型地址:https://github.com/ThorPham/License-plate-detection
因为我已经有了一个可以记录的硬件系统,所以我决定用我的系统在镇上转上几个小时,收集新的视频帧数据来对前面的模型进行微调。
我使用VOTT来对那些含有车牌的帧进行标注,最终创建了一个包含534张图像的小数据集,这些图像中的车牌都有标记好的边界框。
数据集地址:https://github.com/RobertLucian/license-plate-dataset
然后我又找到利用Keras实现YOLOv3网络的代码,并用它来训练我的数据集,然后将我的模型提交到这个repo,这样别人也能用它。我最终在测试集上得到的mAP是90%,考虑到我的数据集非常小,这个结果已经很好了。
Keras实现:https://github.com/experiencor/keras-yolo3提交合并请求:https://github.com/experiencor/keras-yolo3/pull/244
CRAFT&CRNN
为了找到一个合适的网络来识别文本,我经过了无数次的尝试。最后我偶然发现了keras-ocr,它打包了CRAFT和CRNN,非常灵活,而且有预训练过的模型,这太棒了。我决定不对模型进行微调,让它们保持原样。
keras-ocr地址:https://github.com/faustomorales/keras-ocr
最重要的是,用keras-ocr预测文本非常简单。基本上就是几行代码。你可以去该项目主页看看这是如何做到的。
第五步:部署我的车牌检测模型
模型部署主要有两种方法:
在本地进行所有的推理;在云中进行推理。
这两种方法都有其挑战。第一个意味着有一个中心「大脑」计算机系统,这很复杂,而且很贵。第二个面临的则是延迟和基础设施方面的挑战,特别是使用gpu进行推理。
在我的研究中,我偶然发现了一个名为cortex的开源项目。它是AI领域的新人,但作为AI开发工具的下一个发展方向,这无疑是有意义的。
cortex项目地址:https://github.com/cortexlabs/cortex
基本上,cortex是一个将机器学习模型部署为生产网络服务的平台。这意味着我可以专注于我的应用程序,而把其余的事情留给cortex去处理。它在AWS上完成所有准备工作,而我唯一需要做的就是使用模板模型来编写预测器。更棒的是,我只需为每个模型编写几十行代码。
如下是从GitHubrepo获取的cortex运行时的终端。如果这都称不上优美简洁,那我就不知道该用什么词来形容它了:
因为这个计算机视觉系统不是为了实现自动驾驶而设计的,所以延迟对我来说不那么重要,我可以用cortex来解决这个问题。如果它是自动驾驶系统的一部分,那么使用云提供商提供的服务就不是一个好主意,至少现在不是。
部署带有cortex的ML模型只需:
定义cortex.yaml文件,它是我们的api的配置文件。每个API将处理一种类型的任务。我给yolov3的API分配的任务是检测给定帧上的车牌边界框,而crnnAPI则是在CRAFT文本检测器和crnn的帮助下预测车牌号码;定义每个API的预测器。基本上你要做的就是在cortex中定义一个特定类的predict方法来接收一个有效负载(所有的servypart都已经被平台解决了),这个有效负载来可以来预测结果,然后返回预测结果。就这么简单!
这里有一个经典iris数据集的预测器示例,但因为文章篇幅原因,具体细节在此就不做赘述了。项目链接里可以找到cortex使用这两个api的方法——这个项目的所有其他资源都在本文的最后。
34;setosa&34;versicolor&34;virginica&34;s3&34;bucket&34;key&34;model.pkl&34;model.pkl&34;rb&34;sepal_length&34;sepal_width&34;petal_length&34;petal_width&34;Content-Type:application/json&39;{&34;:5.2,&34;:3.6,&34;:1.4,&34;:0.3}'
然后你会收到类似setosa这样的反馈,非常简单!
第六步:开发客户端
有了cortex来帮我进行部署之后,我就可以开始设计客户端了——这算是比较棘手的部分。
我想到了以下架构:
从PiCamera以可接受的分辨率(800×450或480×270)收集帧速率为30FPS的帧,并将每个帧推入一个公共队列;在一个单独的进程中,我将从队列中取出帧,并将它们分发给不同线程上的多个工作站;每个工作线程(或者我称之为推断线程)都会向我的cortexAPI发出API请求。首先,一个请求到我的yolov3API,然后,如果有任何车牌检测到,另一个请求会带着一批裁剪的车牌发到我的crnnAPI。预测的车牌号码将以文本格式返回;将每个检测到的牌照(带不带识别后的文本都可以)推到另一个队列,最终将其广播到浏览器页面。同时,还将车牌号码预测推到另一个队列,以便稍后将其以csv格式保存到磁盘;广播队列将接收一组无序的帧。consumer的任务是先把它们放在一个非常小的缓冲区(几个帧的大小),每次广播一个新的帧给client重新排序。这个consumer在另一个进程上单独运行,它还必须尝试保持队列的大小固定为指定值,以便以一致的帧速率显示帧。显然,如果队列大小下降,那么帧率的下降是成比例的,反之亦然;与此同时,在主进程中还会运行另一个线程,从另一个队列获取预测和GPS数据。当客户端收到终止信号时,预测、GPS数据和时间也会被转存到csv文件中。
下图是客户端与AWS上的云api之间的关系流程图。
图7:基于cortex提供的云api与客户端流程图
在我们的例子中,客户端是树莓派,推理请求发送到的云api由AWS上的cortex提供。
客户端的源代码也可以在其GitHub中找到:https://github.com/robertlucian/cortex-licens-plate-reader-client
我必须克服的一个挑战是4G的带宽。最好减少此应用程序所需的带宽,以减少可能的hangups或对可用数据的过度使用。我决定让PiCamera使用一个非常低的分辨率:480×270(我们这里可以用一个小分辨率,因为PiCamera的视野非常窄,所以我们仍然可以很容易地识别车牌)。
不过,即使是在这个分辨率下,每一帧的JPEG大小也是大约100KB(0.8MBits)。乘以每秒30帧就得到3000KB,也就是24mb/s,这还是在没有HTTP开销的情况下,这是很多的。
因此,我用了一些小技巧:
将宽度减少到416像素,也就是YOLOv3模型所需要的大小,而且尺度显然是完好无损的;将图像转换为灰度图;移除图片顶部45%的部分。这里的想法是车牌不会出现在车架的顶部,因为汽车不会飞,对吧?据我所知,删除45%的图像并不影响预测器的性能;再次转换图像为JPEG,但此时的质量变低了很多。
最终得到的帧的大小大约是7-10KB,这是非常好的。这相当于2.8Mb/s。但是考虑到响应等所有的开销,它大约是3.5Mb/s。对于crnnAPI,裁剪过的车牌根本不需要太多空间,即使没有进行压缩,它们的大小也就是2-3KB左右一个。
总而言之,要以30FPS的速度运行,推理api所需的带宽大约是6Mb/s,这个数字我可以接受。
结果
成功了!
上面这个是通过cortex进行实时推理的例子。我需要大约20个装备了gpu的实例才能顺畅地运行它。根据这一组gpu的延迟,你可能需要更多的gpu或是更少的实例。从捕获帧到向浏览器窗口广播帧之间的平均延迟约为0.9秒,考虑到推断发生在很远的地方,这真是太神奇了——到现在我还是觉得惊讶。
文本识别部分可能不是最好的,但它至少证明了一点——它可以通过增加视频的分辨率或通过减少摄像机的视场或通过微调来更精确。
至于GPU需求数太高的问题,这可以通过优化来解决。例如,在模型中使用混合精度/全半精度(FP16/BFP16)。一般来说,让模型使用混合精度对精度的影响很小,所以我们并没有做太多的权衡。
总而言之,如果所有的优化都到位,那么将gpu的数量从20个减少到一个实际上是可行的。如果进行了适当的优化,甚至一个gpu的资源都用不完。
原文地址:https://towardsdatascience.com/i-built-a-diy-license-plate-reader-with-a-raspberry-pi-and-machine-learning-7e428d3c7401
OK,本文到此结束,希望对大家有所帮助。