写点什么

用开源软件写的 57 行代码,PK 掉 8600 万的商业项目!

  • 2017-09-19
  • 本文字数:2798 字

    阅读完需:约 9 分钟

维多利亚警察局是澳大利亚维多利亚的主要执法机构。去年,发生在维多利亚的盗车数量达到了 1.6 万辆,价值 1700 万美元,因为发生了这些,我们的警察开始忙于测试各式各样的技术和解决方案,尝试去打击那些偷车贼。

为了防止那些欺诈性质的,即售卖被盗窃车辆,一家叫做 VicRoads ,提供了基于 web的服务,可以检查车辆的注册情况,该部门也投资了车辆牌照的扫描仪,一个固定的三脚架摄像头,用于扫描过往的车流,以自动识别被盗车辆。

请不要问我发生过什么,有那么一天下午,我突发奇想,我自己何不做一个车载的车牌扫描仪,功能就是如果车主的车被盗或未注册,车主将会自动得到通知。在理解了各个组件的工作情况之后,我试图将它们组合起来,验证一下是否可行。

在经过了一系列的Google 搜索之后,我发现维多利亚警察最近也在试用一个类似的设备,他们预计的推出成本在8600 万美元左右。一位精打细算的评论员指出:“这笔8600 万美元,是为220 辆汽车装备此设备,相当于每台设备花费390,909 美元。”

相信我可以做的比这个更好!

成功的标准

在开始做这个设备之前,我列举了如下的一些关于产品设计的几个关键需求。

图像必须在本地处理

将直播的视频流上传到中央服务器看起来是解决此问题的最差的选择。除了数据流量大,需要花费的宽带费用很高之外,网络的延迟将无法保证最后的结果。

虽然说处于数据中心的机器学习算法会越来越准确,我以为能够在本地处理就足够了。

能够处理低质量的图片

我既没有树莓派的相机,也没有USB 的摄像头,我拥有的仅仅是普通的行车记录仪,它可以随车即时使用,是样品数据的理想来源。另外还有一个好处,即行车记录仪代表车载摄像头的整体质量,具有普遍性。

需使用开源软件构建

依赖于专有软件,也就意味着每次你有需求变更或增强功能,都得另外付费,——而且这个过程永无止境。毫无疑问,开源软件是默认选项。

解决方案

大体上来说,我的方案就是从行车记录仪中读取图片,将之传送到本地设备,本地的设备安装有开源的牌照识别系统,然后去查询注册服务,然后返回结果并进行显示。

返回到安装在执法车辆中设备的数据包括车辆的制造厂商和型号(以验证是否只是车牌被盗),注册状态,如果是被偷的车辆的话,就会发出通知。

聪明的读者是不是觉得挺简单的?是的,它确实也没有那么的复杂。举例来说,牌照的处理可以交由一个叫做 openalpr 的程序库,这其实就是所涉及到的识别牌照上的字符全部:

复制代码
openalpr.IdentifyLicense(imagePath, function (error, output) {
// handle result
});

轻微警告 公开访问 VicRoads 的 API 还不可用,因此此处涉及到的车辆牌照检查的 web 只是一个原型,或许有人看不惯——这只是一个概念验证,我并没有黑进任何服务器。

下面就是我写的用作概念验证的略显粗糙的代码:

复制代码
// Open form and submit enquire for `rego`
function getInfo(rego) {
horseman
.userAgent('Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0')
.open(url)
.type('#registration-number-ctrl input[type=text]', rego)
.click('.btn-holder input')
.waitForSelector('.ctrl-holder.ctrl-readonly')
.html()
.then(function(body) {
console.log(processInfo(body, rego));
return horseman.close();
});
}
// Scrape the results for key info
function processInfo(html, rego) {
var $ = cheerio.load(html);
var vehicle = $('label.label').filter(function() {
return $(this).text().trim() === 'Vehicle:';
}).next().text().trim();
var stolen = $('label.label').filter(function() {
return $(this).text().trim() === 'Stolen status:';
}).next().text().trim();
var registration = $('label.label').filter(function() {
return $(this).text().trim() === 'Registration status & expiry date:';
}).next().text().trim();
return {
rego,
vehicle,
stolen,
registration
};
}

结果

我必须坦率的和大家说,结果着实令人吃惊。

我本以为开源的车辆牌照识别一定不怎么好用,另外,我甚至认为此程序未必正对澳大利亚的牌照进行过优化。

结果让我想到的意外,如它可以在较开阔的视野识别到车牌。

(图片说明:添加注释生效,尽管有强光发射、镜头失真,但是依然识别到了车牌。)

虽然解决方案有些瑕疵,即对于特殊字母的处理不够完美。

(图片说明:读牌照不够精准,将 M 读成了 H)

但是,还是可以接受的,大多数时候能够得出正确结果。

(图片说明:几帧之后,M 被正确识别,并具有更高的置信度)

正如你所看到的上面的两幅图,在多处理了几帧图像之后,可信度从 87% 上升到了 91%。

我开始对此方案有了足够的信心,对于双关语的处理,可以通过提高样本率可以提高准确性,然后按最高置信度来排序。或者,在接受验证注册号之前,设置一个阈值,如仅接受大于 90%的置信度的图片。

当然,这些都是可通过修改代码来让软件更加的完善,而且还可以使用本地的数据来训练车辆识别软件。

8600 万美元的问题

公平地说,我完全不知道不知道 8600 万美元都花在了哪里?我也不会说训练本地的机器学习开源软件,为了提高准确性,而毋需花费额外的金钱,或者是使用试验性质的 BlueNet 系统。

我还可以预估出来,这些预算还会包括替代旧的数据库和应用程序,从而能够支持每辆车,每秒中的被频繁的查询,以达到低延时的效果。

换句话说,每辆车花费 ~$391k 是很奢侈的,尤其是如果 BlueNet 不是特别准确,而且还没有大型的系统扩展,以及升级相关依赖的系统。

未来的应用

尽管这个系统,很容易被人认为是奥威尔式的“永远在线”的牌照网络监视,但是此项技术仍然有很多正面的意义。可以想象一下,这个系统可以扫描到前方的被盗窃的车辆,然后会发送信息给丢失爱车的车主或家人,信息包括车辆目前的位置和要去往的目的地,车主找回自己爱车的几率就会大很多。

特斯拉早已经实现了接收 OTA 更新功能的相机和传感器,—— 想象一下,这是多么强大的一组守护者。Uber 和 Lyft 的司机若配置了此设备,那么就可以覆盖更大范围的,让偷车贼无处可遁。

使用开源技术和现成的组件,似乎有可能提供一个提供更高回报率的解决方案 - 投资远低于 8600 万美元。

关于作者

Tait Brown,自称是一名 UX 设计师和开发者,会做一些和用户体验有关的事情,并乐意分享 tweet。

查看英文原文 How I replicated an $86 million project in 57 lines of code


感谢杜小芳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-09-19 19:006654
用户头像

发布了 33 篇内容, 共 12.4 次阅读, 收获喜欢 13 次。

关注

评论

发布
暂无评论
发现更多内容

架构实战营第一模块课程总结

Vic

架构实战营

架构实战营第一模块命题作业

Vic

架构实战营

Java 代理使用与原理

Yangjing

cglib JDK代理 代理原理

全面升级! 星环科技基础软件再升级 赋能数字中国建设

星环科技

社交出海,应如何突破安全与合规困局? | 精选案例

亚马逊云科技 (Amazon Web Services)

NoCode 实战 | 零代码应用开发,轻松搞定任务跟踪管理难题(下)

亚马逊云科技 (Amazon Web Services)

iOS 面试策略之代码考查到offer的比较和选择

iOSer

ios 面试

架构实战营模块一作业

En wei

架构实战营

Java 并发基础(三):再谈 CountDownLatch

看山

Java并发

通过校企合作,我们打造了一个培养应用型人才的“梦工场” | 精选案例

亚马逊云科技 (Amazon Web Services)

亚马逊云科技发布中国业务战略!

亚马逊云科技 (Amazon Web Services)

Java 并发基础(二):主线程等待子线程结束

看山

Java并发

理查德·斯托曼:为了自由,我决定写一个GNU操作系统(下)

开源青年

开源 开源青年 开源文化 人物志

KAIFA 的「AMI 智能计量系统解决方案」出海记 | 精选案例

亚马逊云科技 (Amazon Web Services)

大数据计算时数据倾斜问题及解决方案

五分钟学大数据

大数据 4月日更

优雅编程:JavaScript代码优化常见的3个小技巧

devpoint

map reduce 空值运算符 filter 扩展运算符

模块1

Chris Cheng

架构实战营

crudapi零代码开发平台应用场景和成功案例

crudapi

RESTful API sdk crud crudapi

Amazon SageMaker Debugger 推出模型分析功能啦 | 新服务上线

亚马逊云科技 (Amazon Web Services)

理查德·斯托曼:我能发起“自由软件”运动全靠那台打印机(上)

开源青年

开源 #人物志 开源青年 开源文化

架构实战营-M01H

赤色闪电

架构实战营

deno + Vite 会碰撞出什么样的火花呢?

Viktor

deno vite

Spark数据倾斜解决方案实战(一)

小舰

4月日更

亚马逊云科技大中华区企业业务拓展总经理凌琦:云计算赋能芯片设计和制造

亚马逊云科技 (Amazon Web Services)

Java 并发基础(四):再谈 CyclicBarrier

看山

Java并发

人人矿场帮助用户轻松获取算力

DT极客

中文文档持续迭代,内容更丰富,入口更简明!

Rancher

开源软件运动|网景公司|大教堂与集市

开源青年

开源 开源青年 开源文化 人物志

快速学一遍vue的状态管理模式 -- Vuex

空城机

JavaScript Vue 大前端 4月日更 vuex

K8S行业调研报告出炉:混合云、边缘计算走向主流

Rancher

模块一:课后作业

黄先生

架构实战营

用开源软件写的57行代码,PK掉8600万的商业项目!_语言 & 开发_李建盛_InfoQ精选文章