写点什么

深度学习及 AR 在移动端打车场景下的应用

  • 2020-02-25
  • 本文字数:6490 字

    阅读完需:约 21 分钟

深度学习及AR在移动端打车场景下的应用

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

本文内容根据作者在美团 Hackathon 4.0 中自研的项目实践总结而成。作为美团技术团队的传统节目,每年两次的 Hackathon 已经举办多年,产出很多富于创意的产品和专利,成为工程师文化的重要组成部分。本文就是 2017 年冬季 Hackathon 4.0 一个获奖项目的实践总结。

前言

2017 年在移动端直接应用 AI 算法成为一种主流方向。Apple 也在 WWDC 2017 上重磅推出 Core ML 框架。准备 Hackathon 的过程中,我们就想能否基于 Core ML 的深度学习能力,结合 AR,做酷一点的产品。我们观察到在晚上下班时间,是公司的打车高峰时段,这时候经常会有一堆车在黑暗中打着双闪,你很难通过辨认车牌去找到你叫的专车,所以我们把产品定向为一个打车时帮助用户找到车的 App。


很快我们就把上面的想法落地实现了,开发了一个叫做 WhereAreYou 的简单 App 应用,相当于 AR 版本的微信共享位置,只要打开摄像头就可以看到小伙伴们的方位和远近。当然了,应用于打车场景下,就是让用户知道目标车辆从何驶来、距离多远。程序大概结构如图 1 所示:



图 1

远距离下使用 AR 帮助用户找到目标方位

我们用 Node.js 写了一个简单的服务,用户可以创建一个共享位置的 group,其他用户拿到 groupID 后可以加入这个组,接着程序会通过服务来共享他们各自的 GPS 信息,同一个 group 内的成员可以在地图上看到其他成员的位置。值得一提的是,我们添加了一个 AR 模式,成员点击 AR 按钮后可以进入,此时摄像头会被打开,如果同一个组的其他小伙伴方位距离此用户很近,屏幕上就会出现一个 3D 模型,告诉用户附近有某某小伙伴,距离此地的远近等信息。主要过程和效果如图 2 所示:



图 2


项目做到这里都很顺利,接下来就遇到了一些难点,主要是利用 ARKit 渲染模型的部分。其中有一个问题是如何把两个 GPS 空间上的方位反映到用户屏幕上,经过一些努力,我们终于攻克这个难关,这里可以分享一点干货:


  1. 首先考虑空间上的两个点 ,以 为原点,横轴代表纬度,纵轴代表经度,这样我们可以求得两点位于正北的偏角



图 3


  • 然后通过陀螺仪可以得到当前手机正方向的朝向



图 4


  • 之后只要将 3D 模型渲染在屏幕正中央俯视偏角 处就可以了。



图 5


那么问题来了,如何将一个 3D 模型显示在屏幕正中央 处呢?这里就用到了 ARKit 的 ARSCNView 中的模型渲染 API,跟 OpenGL 类似,ARSCNView 从创建之初会设置一个 3D 世界原点并启动摄像头,随着手机的移动,摄像头相当于 3D 世界中的一个眼睛,可以用一个观察矩阵[camera]表示。这样在屏幕正中央俯视偏角 处渲染一个 3D 节点的问题,其实就是如何才能把观测坐标转换为世界坐标的问题。我们首先将物体放在手机前 3 米处,然后直接根据下图所示公式就可求得最终坐标:



图 6


下面是在 ARSCNView 每次重新渲染回调中设置模型位置的逻辑:


 func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {     guard let renderLocations = self.netGroupInfo?.locations?.filter({ (userLocation) -> Bool in       return userLocation.userId != GroupMenberManager.sharedInstance.getCurrentUserID()     }) else {       return     }     DispatchQueue.main.async {       guard let camera = self.sceneView.pointOfView else { return }       //当前用户定位       let currentLocation = UserLocation()        currentLocation.latitude = GroupMenberManager.sharedInstance.userLatitude       currentLocation.longitude = GroupMenberManager.sharedInstance.userLongitute       // 循环处理当前组内其他成员       for renderLocation in renderLocations {        // 两点间距离公式求得距离用来控制3D模型字体大小,直观的反应距离的远近         let distance = currentLocation.distanceFrom(renderLocation)        // 求得两个用户间的坐标关系         let angle = currentLocation.angleFrom(renderLocation)        // 根据上述公式求得3D模型要渲染的最终位置 compassAngle为实时获取的陀螺仪指南针方向         var position = SCNVector3(x: 0, y: 0, z: -3).roateInHorizontalPlaneBy(angle: self.compassAngle - angle)         position = camera.convertPosition(position, to: nil)        //稳定在水平上         position.y = 0;        //更新位置         self.virtualObjectManager.findVirtualObject(renderLocation.userId ?? "")?.scnNode.position = position        //根据距离更新模型文字和大小         self.virtualObjectManager.findVirtualObject(renderLocation.userId ?? "")?.changeNodeTextAnSize(text: renderLocation.userTitle, distance: distance)       }     }   }
复制代码


写了一个周末差不多把上面功能完成,这个时候对于参赛获奖是没有任何底气的。因为其实这个点子并不十分新颖,技术难点也不够。最主要的痛点是,我们真机联调测试的时候发现,在 10m 范围内 GPS 定位的精度完全不可靠,屏幕中渲染的点位置经常错乱。我们之前知道近距离 GPS 定位会不准,却没想到 3D 模型在屏幕上对误差的反应这么敏感,这样的话比赛时现场演示是绝对不行的。


既然 GPS 近距离定位不准无法解决,我们决定在近距离时放弃 GPS 用另一种方式提醒用户目标在哪里。

近距离下使用 AI 算法找到目标

我们做了一个设想,就是让程序在 10 米范围能够智能地去主动寻找到目标,然后在手机屏幕上标注出来。


之后我们对视觉算法在移动端实现的现状进行调研,发现随着近几年计算机视觉飞跃式发展,网上各种开源图片分类识别算法有很多,加上 2017 年年初 Apple 推出了非常靠谱的 Core ML,所以在短时间内实现一个移动端的“目标发现”算法是可行的。


在确定 WhereAreYou 需要添加的功能后,我们立足于打车找车这个问题进行调研开发,最后终于实现了一个稳定、高效、实时的基于多种 CNN 模型混合的车辆发现跟踪算法,下面 GIF 可以看到效果。



图 7


在使用完 Core ML 之后,真心觉得它确实如 Apple 在 WWDC 2017 上所言,性能十分优越。由此可以预见之后几年,在移动端直接应用 AI 算法的优秀 App 会层出不穷。


扯远了,上点干货吧!


在说我们的《基于多种 CNN 模型混合的车辆发现跟踪算法及其移动端实现》之前,先说一下 Apple 的 Core ML 能帮我们做到哪一步。


Core ML 是一个可以让开发者很容易就能在应用中集成机器学习模型(Machine Learning Models)的应用框架,在 iOS、watchOS、macOS 和 tvOS 上都可以使用它。Core ML 使用一种新的文件格式(.mlmodel),可以支持多种类型的机器学习模型数据,比如一些深度神经网络算法(CNN、RNN),决策树算法(boosted trees、random forest、decision trees),还有一些广义的线性模型(SVM、Kmeans)。Core ML models 以.mlmodel 文件的形式直接集成到开发应用中,文件导入后自动生成对应的工具类可直接用于分类识别等 AI 功能。


我们知道通过 Keras、Caffe、libsvm 等开源学习框架可以生成相应的模型文件,但这些模型文件的格式并不是.mlmodel。Core ML Tools 可以对这些文件进行转换,生成.mlmodel 文件,将目前比较流行的开源学习框架训练出的模型直接应用在 Core ML 上,如图 8 所示:



图 8


coremltools 本身是一个 Python 工具包,它可以帮我们完成下面几件事情:


  • 第一点就是刚刚提到的将一些比较出名的开源机器学习工具(如 Keras、Caffe、scikit-learn、libsvm、XGBoost)训练出来的模型文件转换为.mlmodel。

  • 第二点是提供可以自定义转换的 API。打个比方,假设 Caffe 更新到了 Caffe 3.0,本身模型的文件格式变了,但 coremltools 还没来及更新,这时就可以利用这些 API 自己写一个转换器。

  • coremltools 工具本身可以使用上述所说的各种开源机器学习工具训练好的模型进行决策。


看到这里是不是内心很澎湃?是的,有了这个工具我们可以很方便地把训练好的模型应用到 Apple 设备上,所以赶紧安装吧!步骤很简单,机器上有 Python(必须是 Python 2.X)环境后执行 pip install -U coremltools 就好了。


那如何进行转换呢?举一个例子:


我们可以到Caffe Model Zoo上下载一个公开的训练模型。比如我们下载 web_car,这个模型可以用于车型识别,能够区分奔驰、宝马等诸多品牌的各系车型约 400 余种。下载好 web_car.caffemodel、deploy.prototxt、class_labels.txt 这三个文件,写一个简单的 Python 脚本就可以进行转换了。


import coremltools
# 调用caffe转换器的convert方法执行转换coreml_model = coremltools.converters.caffe.convert(('web_car.caffemodel', 'deploy.prototxt'), image_input_names = 'data', class_labels = 'class_labels.txt')
# 保存转换生成的分类器模型文件coreml_model.save('CarRecognition.mlmodel')
复制代码


coremltools 同时还提供了设置元数据描述的方法,比如设置作者信息、模型输入数据格式描述、预测输出张量描述,较为完整的转换脚本如下:


import coremltools
# 调用caffe转换器的convert方法执行转换coreml_model = coremltools.converters.caffe.convert(('googlenet_finetune_web_car.caffemodel', 'deploy.prototxt'), image_input_names = 'data', class_labels = 'cars.txt')
# 设置元数据coreml_model.author = 'Audebert, Nicolas and Le Saux, Bertrand and Lefevre Sebastien'coreml_model.license = 'MIT'coreml_model.short_description = 'Predict the brand & model of a car.'coreml_model.input_description['data'] = 'An image of a car.'coreml_model.output_description['prob'] = 'The probabilities that the input image is a car.'coreml_model.output_description['classLabel'] = 'The most likely type of car, for the given input.'
# 保存转换生成的分类器模型文件coreml_model.save('CarRecognition.mlmodel')
复制代码


上面所说的“可以让开发者很容易地在应用中集成机器学习模型”是什么意思呢?是指如果你有一个 CarRecognition.mlmodel 文件,你可以把它拖入到 Xcode 中:



图 9


Xcode 会自动生成一个叫做 CarRecognition 的类,直接使用其预测方法就好了。比如对一个汽车图片做识别,像这样:


let carModel = CarRecognition()let output = try carModel.prediction(image: ref)
复制代码


基于上述 Core ML 提供的功能结合一些开源模型算法我们完成了《基于多种 CNN 模型混合的车辆发现跟踪算法及其移动端实现》。


首先说一下大概的算法流程,还记得本文一开始在图 1 中提到的 WhereAreYou 程序结构图吗?现在我们在 AR 模块中添加主动寻找目标的功能。当目标 GPS 距离小于 50 米时,算法被开启。整个识别算法分为目标检测、目标识别以及目标追踪。当摄像头获取一帧图片后会首先送入目标检测模块,这个模块使用一个 CNN 模型进行类似 SSD 算法的操作,对输入图片进行物体检测,可以区分出场景中的行人、车辆、轮船、狗等物体并输出各个检测物体在图片中的区域信息。


我们筛选所有汽车目标,将对应物体的图片截取后送入目标识别模块,对车型进行识别。之后拿到识别出的车型跟车主上传的车型进行对比,如果车主的车型跟识别出的结果一致,就将当前帧和目标区域送入目标跟踪模块,并对当前车辆进行持续跟踪。当然如果跟踪失败就从头进行整个过程。具体如图 10 所示:



图 10


下面说一下为什么要结合这三种算法进行“寻找车主汽车”这个任务:


大家应该还记得刚刚介绍 coremltools 的时候举的一个例子,在例子中我们在 Caffe Model Zoo 下载了一个车型识别的算法模型。没错,我们这个结合算法其目标识别模块中用的车型识别正是这个模型。最初调研时,在 caffe 上找到这个开源模型很开心,觉得把这个模型下载好后转换一下应用到工程中就完事了。结果发现,实际上将拍摄到的整幅图片送入这个模型得到的识别正确率几乎为零。分析原因是因为这个模型的训练数据是汽车的完整轮廓,而且训练图片并无其它多余背景部分。而现实中用户不可能只拍汽车,场景中汽车只是很小的一个区域,大部分还是天空、马路、绿化带等部分,整幅图片不做截取直接进行处理识别率当然不行。所以只有先找到场景中的车在哪,然后再识别这个是什么车。


在一副图片中标定场景中出现的所有车辆的位置,其实就是 SSD 问题(Single Shot MultiBox Detector),进一步调研可以了解到近几年基于 CNN 的 SSD 算法层出不穷,各种论文资料也很多。其中要数康奈尔大学的 YOLO 算法尤为出名。更重要的是原作者提供了一个他训练好的模型,这个模型在 GitHub 上就可以下载,没错我们结合算法其目标检测中的模型算法就是使用的这个→_→ 。


YOLO 算法的一个特性就是其检测识别速度十分快,这是由其网络结构和输入结构决定的。YOLO 模型输出张量结构决定了在屏幕上如何截取对应图片区域,这里简单介绍一下,概念不严谨之处还请各位不吝赐教。如图 11 所示,YOLO 算法将输入图片分为 13 × 13 个小块,每张图片的各个小块对应到其所属物体的名称和这个物体的范围。打个比方图 11 中狗尾巴处的一个小块对应的是狗和这个狗在图片中的位置(dog、x、y、width、height),算法支持 20 种物体的区分。通过网络预测得到的张量为 13 × 13 × 125。


其具体意义是一张图片中所有小块(共 13 × 13 个)每次预测得到 5 组结果,每组结果对应一个矩形区域信息(x、y、width、height)代表本小块所属的目标区域,同时给出这个区域确信是一个目标的概率(confidence,这里的“确信是一个目标”是指 20 种物体任意一个即可),还有 20 种物体各自的确信概率。即 125 = 5 × 25(x、y、width、height、confidence、Class1Confidence、Class2Cconfidence……)。了解这点后我们就不难截取最终识别结果所对应的图片区域了(当然只选取置信率比较高的前几个)。



图 11


图 12 展示了 YOLO 高效地执行结果,图 13 展示了 YOLO 目标检测与车辆识别结合后的执行效果。



图 12



图 13


算法到此时可以算是差不多了,但从图 13 中还是可以看到一些问题:


识别的结果并不是每帧图片都是对的,而且也并不是每帧图片都能检测出场景中的每一个车辆。这样就会导致在屏幕上标注车辆位置提示用户时会出现断断续续。经过调研后我们又加入了目标跟踪的模块。目标跟踪的任务比较好理解,输入一帧图片和这张图片中的一个区域信息,要求得出下一帧中这个区域对应图像所在位置,然后迭代此过程。目标跟踪算法在深度学习火起来之前就比较成熟了,文献和开源实现都比较多,我们选用 CoreML 官方提供的跟踪模块进行处理,实验效果发现还不错,最终结果如上(图 7)所示。


各个模块执行时间统计如下:



图 14

总结

《基于多种 CNN 模型混合的车辆发现跟踪算法及其移动端实现》这个项目由于时间原因还有很多缺陷,诚如当时评委意见所说的那样“核心算法都是使用网上现有模型,没有自己进行训练”,此算法可以提高优化的地方有很多。比如添加车辆颜色、车牌等检测提高确认精度,优化算法在夜间、雨天等噪声环境下的表现等。


最后,通过这个项目的开发实现让我们知道在移动端应用 CNN 这样的学习算法已经十分方便,如图 15 这样构建的移动端 AI 程序的执行速度和效果都很不错。希望我们的 WhereAreYou 项目就像能够帮助用户更快找到车一样,给前端工程师提供多一些灵感。相信未来前端工程师能做的可以做的需求会越来越有趣!



图 15

参考文献

作者简介

  • 大卫,美团前端 iOS 开发工程师,2016 年毕业于安徽大学,同年加入美团到店餐饮事业群,从事商家移动端应用开发工作。


公众号推荐:

AIGC 技术正以惊人的速度重塑着创新的边界,InfoQ 首期《大模型领航者AIGC实践案例集锦》电子书,深度对话 30 位国内顶尖大模型专家,洞悉大模型技术前沿与未来趋势,精选 10 余个行业一线实践案例,全面展示大模型在多个垂直行业的应用成果,同时,揭秘全球热门大模型效果,为创业者、开发者提供决策支持和选型参考。关注「AI前线」,回复「领航者」免费获取电子书。

2020-02-25 20:32667

评论

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

人物 | 从程序员到架构师,我是如何快速成长的?

安势信息

程序员 职场 架构师 程序员进阶 人物访谈

七日算法先导(六)——堆排序,桶排序

工程师日月

8月月更

API接口是什么?API接口常见的安全问题与安全措施有哪些?

郑州埃文科技

API接口管理 非对称加密 md5 令牌桶算法

你知道 Vue scoped 原理吗?这波你在第几层?

掘金安东尼

面试 前端 8月月更

富媒体在客服IM消息通信中的秒发实践

得物技术

前端 即时通讯 客服 富媒体 大文件传输

国际计费系统基于Sharding-Proxy大数据迁移方案实践

京东科技开发者

数据库 系统 数据迁移

看漫画MHGmhgui,Python爬虫之神奇的eval,附赠一个压缩模块

梦想橡皮擦

Python 爬虫 8月月更

自从我使用HiFlow场景连接器后,在也不用担心成为“落汤鸡”了

叶秋学长

Hiflow

美的数字化平台 iBUILDING 背后的技术选型

TDengine

数据库 tdengine database

《数字经济全景白皮书》银行业智能营销应用专题分析 发布

易观分析

金融 银行 白皮书 智能营销

electron 应用开发优秀实践

vivo互联网技术

前端 Web Electron 桌面开发

对话跨国消费品牌DPO:数据安全合规从何做起?8.11直播见!

奇点云

数据治理 数据安全 数据合规

前端该如何优雅地 Mock 数据

CRMEB

web前端培训课程怎么选择

小谷哥

开源一夏 |最好用的脚本语言--JavaScript

叶秋学长

开源 前端 js 8月月更

java软件培训费用怎么算

小谷哥

一文看懂大数据生态圈完整知识体系

博文视点Broadview

MySQL索引的B+树到底有多高?

转转技术团队

MySQL 索引

使用 ABAP 编程语言的 System CALL 接口,直接执行 ABAP 服务器所在操作系统的 shell 命令

汪子熙

Linux unix SAP abap 8月月更

浅谈一线互联网大厂中算法岗的分类

码农鬼仔

数据挖掘 AI 算法工程师 校招 机器学习/深度学习

集群部署spark、Hadoop环境

峥岳

hadoop spark hive

研发需求的验收标准应该怎么写? | 敏捷实践

LigaAI

程序员 产品经理 敏捷开发 研发管理 开发流程

MySQL传统方案和通过SSH连接哪个好?

了不起的程序猿

MySQL 数据库 java程序员 :MySQL 数据库

在北京参加UI设计培训到底怎么样?

小谷哥

收到人生第一笔五位数工资

Amazing_eve

#开源

OpenSSF的开源软件风险评估工具:Scorecards

SEAL安全

开源 开源安全 软件供应链安全 开源合规 开源工具包

程序员的专属浪漫——用3D Engine 5分钟实现烟花绽放效果

HarmonyOS SDK

大数据培训课程如何选?

小谷哥

java培训中心有哪些

小谷哥

StratoVirt 中的虚拟网卡是如何实现的?

openEuler

开源 openEuler Open Source 内核态 虚拟网卡

七日算法先导(七)——字符串

工程师日月

8月月更

深度学习及AR在移动端打车场景下的应用_文化 & 方法_美团技术团队_InfoQ精选文章