迎难而上看浙商③|阿里巴巴董事局主席张勇:数字新基建的机遇来了,要抓住
选自towardsdatascience
作者:Robert Lucian Chiriac
机器之心编译
参与:王子嘉、思、一鸣
闲来无事,我们给爱车装了树莓派,配了T o m v摄像头、设计了客户端,搞定了实时车牌检测与识别系统。
怎样在不换车的前提下打造一个智能车系统呢?一段时间以来,本文作者 Robert Lucian Chiriac 一直在思考让车拥有x ` $ r N _ K q `探测和识别物体的能力。这个想法非常有意思,因为我们已经见y N ) z E D d B识过特斯拉的能力z y K : % Y,虽然没法马上买一辆特斯拉(不得不提一下,Model 3 现在看起来越来越有吸引力了),但他有了一个主意,可以努力实现这一梦H | W ~ v 4 7 r t想。
所以,作者用树莓派做到了,它放到车上可以实时检测车牌。
在接下来的内容里,我们将介绍项目中h _ ! 3 .的每个步骤,并提供 GitHub 项目地址,其中项目地址只f ] d b - 1是客户端工具,还其它数据集与预训练模型都可以在原博客结尾处找到。
项目地址:
https:/1 h ;/github.com/RobertLucian/cortex-license-plate-reader-client
下面,让我们看看作者 Robert Luc, 8 A F K 5 q gian Chiriac 是如何一步步打造一个好用的车载检测识} # 0 P K Y + b别系统。
放一张成品图镇楼。
第一步:确定项目范围
开始之前,我脑海里出现的第一个问题是这样一个系统应该能够做到什么。如果说我活到现在学到了什么,那就是循序渐进——从小处着手o E t d z - x永远是最好的策略。所以s = Z,除了基本的视觉任务,我需要的只是M M x T Y在开车时能清楚地识别车牌。这个识别过程包括两个步骤:
- 检测到车牌。
- 识别每个车 D X q d p D Z牌边界框内的文本。
我觉得如果我能完成这些任务,再做其他类似的任务(如确定碰撞风险、距离等)就会容易得H F k , j m 4多。我甚至可能可以创建一个向量空间来表示周围的环境—$ R w %—想想都觉得酷。
在确定这些细节8 { U之前,我知道我得先做到:
- 一个机器学习模型,以未标记的图像作为输入,从而检测到车牌;
- 某种硬件。简单地说,我需要连接了一个或多个摄像头的计算机系统来调用我的模型。
那就先从第一件事开始j / | J L & q吧——构建对象检测模型。
第二步:选择正确的模型
经过仔细研究,我决定x * z ^ X D用这些机器学习模型:
- YOLOv3- 这是当下最快~ 6 * Q c H w m O的模型之一,而且跟其他 SOTA 模型的 mAP 相当。我们用这个模型来检测物体;
- CRAFT 文本检测器 - 我们用它来检测图像中的文本;
- CRNN - 简单来说,它就是一个循环卷积神经网络模型。为了将检测到的字符按照正确的顺序排成单词,它必须是时序数据;
这三个模型是怎么通力V t % . C合作的呢?下面说的就是操作流程了:
- 首. L Z S先,YOLOv3 模型从摄像* U 4 H J机处接收r M f O x ?到一帧帧图像,然后在每个帧中找到车牌的边界框。这里不建议使用非常精确的Y A j 4 { h { Q &预测边界框——边界框比实际检测对象大一些会更好。如果太挤,可能会影响到后续进程的性能;
- 文本检测器3 j B k Y 6接收 YOLOv3 裁剪过的车牌J k ? p ;情可见:
博3 + 8 *客地址:https://www.robertlucian.com/2018/08/29/mobile-network-access-rpi/
然后我要开始设计外壳了——把它挂在汽车的后视镜上应该没问题,所以我最终设计了一个分i o k ? V q # I为两部分的支撑结构:
- 在后视镜的方向上,树莓派+ GPS 模块+ 4G 模块将保留下来。关于我使用的 GPS 和 4G 天线,你可以去看一下我关于 EC25-E 模块的文章;E * E 3 x 1 s
- 在另一侧U ^ 7 ,我用一个利用球关节活动的手臂来支撑 Pi CamerZ 1 t W 1 o ea
我会用我可靠S V b的 Prusa i3 MK3S 3D 打印机来打印这些零件,在原文文末也提供了 3D 打印参数。
图 1 :树莓派+4G/GPS 壳的外形
图 2:利用球关节活动臂支撑 Pi Camera
图 1 和图 2 就t r L / w 4 B是它们渲染时候# w 6 ; q的样子。注意这里的 c 型支5 8 2 ; ;架是可插拔的~ I ( 3 D O a | Z,所以树莓派的附件和 Pi Camera 的支撑物没有和支架一起打印出来。他们共享一个插座,插座上插着支架。如果某位读者W f 7 |想要复现这个项目,这是非常有用} y ] Z A莓派的嵌入式系统近照
显然,这些东西需要一些时间来建模,我需要做几次才能得到坚固的结构。我使用的 PETG 材料每层高度为 200 微米。PETG 在 80-90 摄氏度下可以很好地工作,并且对紫外线辐射的抵抗力很强——虽然没U { o . P = 作。这就是迁移学习的核心内容了——先用非常大的数据集来学习,然后再利用这n J *里面学到c h ps://githu( E 4 * ~b.com/ThorPham/License-plate-detection
因为我已经有了一个可以记录的硬件系统,所以我决定用我的系统在镇上转上几个小时,收集新的视频帧数据来对前面的模型进行微调。
我使用5 F , f 9 e % + ) VOTT 来对那些含有车牌的帧进行标注,最g t o i y :终创建了! o *一个包含 534 张图像的小数据集,这些图像中的车牌都有标记好的边界框。
数据集地址:https://github.com/RobertLucian/license-plV - eate-dataset
然后我又找到利用 Keras 实现 YOLOv3 网络的代码,并用它来训练我的数据集,然后将我的模型提交到这个 repo,这样别人也能用它。我最终在测试集上得到的 mAP 是 90%,考虑到我的数据集非常小,这个结果已经很好了。
- Ker2 d & o b Has 实现:https://github.com/experiencor/keras-yolo3
- 提交合并9 A 0 k 5 ` } u请求:https://githubB L H . h ; M q.comC P 2 J t a Q 6/experiencor/keras-yolo3/pull/244
CRAFT & CRNN
为了找到一个合适的网络来识别文本,我经过了无 i # P N 9 n数次的尝试。最后我偶然发现了 keras-ocr,它打包了 CRAFT 和 CRNN,非常灵活,而且有预训练过的模型,这太棒了。我决定不对模H i G R N _ n J型进行微调,让它们保持原样。
keras-ot b % E W l 4cr 地址:https://github.com/g : * # A _faustomorales/keras-ocr
最重要的是,用 keras-ocr 预测文本非常简单。基本上就是几行代码。你可以去该项目主页看看这y z c f S 是如何做到的。
第五步:部署我的车牌检测模型
模型部署主要有两种方法:
- 在本地进行所有的推理;
- 在云中进行推理。
这两种方法都有其挑战。第一个意味着有一个中心「大脑」计算机系统 * ) |,这很复! a + _杂,而且很贵。第二个面临的则是延迟和基础设施方面的挑战,特别是使用 gpu 进行推理。
在我的研究中,我偶然发现了一个名为 cortex 的开源项目。它是 AI 领域的新人,但作为 AI 开发工具的下一个发展方向,这无疑是8 - q D h 4 x K果这都称不上h . ] , 8 c U _ W优美简洁,那我就不知道该v l ^ , w r Z用什么词来形容它了:
因为这个计算机视觉系统不是为了实现自动驾驶而设计的,所以延迟对我来说不那么重要,我可以用 cortY y : m oex 来S I y解决这个问题。如果它是自动驾驶系统的一部分,那么使用云提供商提供的服务就不是一个好主意,至少现在不是。
部署带有 cortex 的= $ ( V 4 R U ML 模型只需:
- 定义 cortex.yaml 文件,它是我们的 api 的配置文件。每个 API 将处理一种类H K #型的任务。我~ Q x t ) b Z给 yolov3 的 API 分配的任务是检测给定帧上的车牌边i K c界框,而 crnn API 则是在 CRAFT 文本检测器和 crnn 的帮助下预测车牌号码;
- 定义每个 API 的预测器。基本上你T c o ]要做的就是在 cortex 中定义一个特定类的 predict 方法来接收一个有效负载(所有的 servy part 都已经被平台P k p k P w解决了),这个有效负载来可以来预测结果,然后返回预测结果。就这么简单!
这里有一个经典 iris 数据集的预测器示例,但因O M _为文章篇幅原因,具体细节在此就不W 9 , 做赘述了。项目链接里可以找到 cortex 使用这两个 api 的方法——这个项目% O x r p的所有其他资源都在本文的最后。
#&nbs6 A Fp;predictor.pyimport boto3
import picklelabels =
class&nb0 @ ) l _ *sp;PythonPredictor:
&n^ q z ^ ~ absp;H S S ` k # 0 w _def __init__(see J U _ h o q ?lf, config):
&7 o l * O AnbH | E p b x ~ Z Tsp; s3 = boto3.client(\Q L A @ j ] y"s3\")
h ? p . 4 [ t m s3U R D _ Z _.download_file(config, config, \"model.pkl\")? D ! 3 1 0
&nbsI ) G u m Bp; self.ms 0 i j ^ 5 )odel = u P o / P;pickle.lo: y ! D Lad(open(\"model.pkl\", \"rbI ) F\"))&$ U , O f 5 ) ]nbsp; &nbsc f ` Op;d9 s v 6 k ! R Gef predict(self, payload):
 L % ^ / / h 6 q; &nbJ h p & q 2 # ssp; measurements = [
&n9 2 F x 7bsp;  4 q K;  , M O y - j v ; payload,
pF n zayload,
payload,
/ { + payload,
] label_id&nS 3 | w J A * , &bsp;=&nbW P q 2 E ) esp;self.model.predict()
l } $ ! W K P ^ D return&nbs9 5 ` h - w mp;labels为了做预测,你只需要像下面这样使用 curl 就行了:
curl! N n J t ~ 3 http://***.amazonaws.com/iris-classifier \N k { n p s j\
&nT e W Y A L / Tbsp; ^ H = Y W-X POST [ 9 | 4 c-H \"Content-Type: application/jsF i M | 0 1 gon\{ r U | y D 2 + x" \\
&m [ 9 J 4 0 ( v C ) $ / ~,但它至少证明了一点——它可以通过增加视频的分辨率或通过减少摄像机的视场或通过微调来更精确。至于 GPb d CU 需求数太高的问题,这可以通过优化来解决。例如,在模型中使用混合精度/全半精度 (FP16/BFP16)。一般来说,让V ` 1 4 1 { R f u模型使用混合精度对精度的影响很小,所以我们并没有~ V Q 9 / T G e做太多的权衡。
总而言之,如果所有的优化都到位,那么将 gpu 的数量从 20 个减少到一个实际上是可行的。如果进行了适当的优化,甚至一个 gpu 的资源都用不完。
原S x v c文地址:https://towardsdatascience.com/i-built-a-diy-license-plate-reader-wiS + / 6 z @ I Ath-a-raspberry-pi-and-machine-learning-7e428d3c7401