高德地图首席科学家任小枫视觉智能在高德地图的应用

2019杭州云栖大会上,高德地图技术团队向与会者分享了包括视觉与机器智能、路线规划、场景化/精细化定位、时空数据应用、亿级流量架构演进等多个出行技术领域的热门话题。现场火爆,听众反响强烈。我们把其中的优秀演讲内容整理成文并陆续发布出来,本文为其中一篇。 高德地图首席科学家任小枫在高德技术专场分享了题为《视觉智能连接真实世界》的演讲,本文根据现场内容整理而成(在不影响原意的情况下对文字略作编辑),更多视觉智能技术的实现细节请关注后续系列文章。 以下为演讲内容的简版实录: 我今天主要给大家介绍视觉及相关技术如何在高德落地,如何帮助连接真实世界。连接真实世界这句话并不只是我个人的想法,而是高德地图的使命,我们的使命是“连接真实世界,让出行更美好”。 首先,简单介绍下高德地图,有超过1亿的日活用户,超过4亿的月活用户,高德地图不光提供导航,也提供出行相关的其他服务,涵盖了信息服务、驾车导航、共享出行、智慧公交、智慧景区、骑行、步行、长途出行等应用场景。 高德地图做的事情是建立人和真实世界的关系,人要跟真实世界建立联系,地图是基础,地图之上还有更多的信息可以获取。 视觉是连接真实世界的桥梁 视觉是连接真实世界的桥梁。为什么?从人的信息获取角度来看,80%的内容是通过视觉获取到的。从人的信息处理来看,人的大脑30%-60%用于视觉感知。从机器的角度,视觉是非常重要的通用感知手段。 人类感知真实世界的方法,还有很多其他方式,例如传感器、LT...但是,作为通用的手段,我一直觉得视觉是第一选择,通用,信息量非常大,可以远距感知,也可以做到实时。 还有一个原因,人类真实世界里(各种元素)80%以上是为了视觉而设计。有的时候,我们对真实世界太过于熟悉,可能不会太在意。但是看一下周围的标志和信息,包括认识的事物,都是根据视觉设计和获取。 因为人类获取信息的主要方式是通过视觉,所以真实世界的设计也是基于视觉。大家可以想象下,如果获取信息的主要方式是通过嗅觉,那这个世界会非常不一样。基于这些,回到我们在做的事情,大家一定不会奇怪,地图信息的获取和建立,绝大部分也是来自于视觉。 视觉技术@高德地图-地图制作 视觉技术在高德地图的应用有很多不同的方式,如下图所示: 左边是地图制作,有常规地图和高精地图,高精地图对应于未来的无人驾驶。右边是跟导航体验相关的,我们在做的一些跟定位相关的工作,也在利用视觉技术希望使导航变得更加便利。因为时间关系,今天只给大家介绍常规地图和导航相关的部分。 地图服务从哪里来,首先要采集资料,目前绝大部分是通过相机和视觉的方式采集信息。真实世界很大,全国有几百万公里道路,再加上其他信息,人工方式目前是处理不过来的,很大程度上需要用自动识别,通过算法识别资料。当然有时候算法没办法做到100%,还需要人工修正,从而制作成地图数据库,来支持地图数据服务。 地图制作任务,常规地图任务通常分为两大类,一类是道路相关,一类是POI挂牌识别。这两类任务都需要较多的视觉技术。例如,在道路标志识别上,算法要做的就是把道路上的标志一个一个全部找出来,同时识别标志的类型和内容。 道路标志有100多种。如果只是处理这些标志,其实并不是那么复杂。现实中,有时候需要用低成本的方式采集数据,这时如何保证图像质量就是需要考虑和解决的问题。 采集信息的时候,有时候图片会有畸变、反光、遮挡等情况,先不说分辨率压缩的问题,成像本身取决于镜头的质量和成本、天气条件、光线等因素,有时候采集回来的图像中差的图很多。这时候就不只是单纯去解决一个理想当中的算法问题,也需要处理很多实际情况。 给大家举几个例子,下面左边的图是实际采集的图像,会有各种各样的问题。大家对相机有些了解的话,知道相机有内参和外参,内参是焦距、中心、畸变。外参是位置、角度,这些都会影响成像效果。 对于识别问题来说,这些相机参数不会造成太大问题,但是如果需要做一些跟几何、位置相关的计算,这时候相机畸变和内外参不准就会造成很大的问题。我们通过把多源数据放在一起做匹配,基本可以解决这个问题。右边是一个实际例子,相机的畸变纠正角度,有一些斜的被纠正过来了,很大的提高了后面的算法处理。 另一个例子,图像质量。有的图质量比较差,但是没办法丢掉,还是有有用的信息。有的原始图像,放大之后非常模糊。如果这时采用图像增强的方法,可以把这张图变得更清楚。改善原始数据的质量,有很多可用的方法。比如提高识别算法精度,提高人工效率,也可以用它做模糊的检测,对比一下增强前后,可以知道哪些是模糊,哪些是不模糊。 刚才举的只是交通标志的例子。还有一个有趣的问题,就是感知电子眼。电子眼很小,而小目标的检测是一个有挑战的问题,在研究领域大家也比较关注。大家可以感受下,拿一张图,如果是太小的东西,放大之后就看不清了,还不如远景。那怎么能比较精确的找到这么小的电子眼呢? 通常方式就是放大区域,因为这个东西太小了,光找这个目标比较难,找到区域放大,引入周边的信息。这些信息可以帮助更好的找到这个小目标,放的再大一点,才能看到其他相关的信息来帮助电子眼的智能检测。 但是放的太大也会有问题,放的太大会引入很多无关的信息。从技术上来说有一些解决方法,现在视觉技术上用的比较多的有一个注意力机制,画一个大框,机器自己会学哪块重要哪块不重要,帮助更好的聚焦到目标本身。当然,尽量会用一些先验信息,比如本身的分布、高度、大小。 光检测还不够,很多时候真实世界在变。很多时候要分辨出哪些变了哪些没变。以前检测出一个电子眼,新的资料又检测出一个电子眼,需要知道这两个是否是同一个。 如何判断?因为这张图表达的不一样,如果仔细看,确实可以看到背景的建筑、架设类型都差不多。需要用算法来判断到底是不是,这就牵涉到目标检测、车道归属、架设类型分析,还要做场景匹配。通过这些,很大程度上可以判断这是一个什么场景,从而判断两张图的元素是不是同一个。 刚才说的是道路,下面是几个跟POI相关的例子。POI的牌子,可以分成好多不同类型,有牌坊式、挂牌式、门脸式等。不仅POI各种各样,非POI其实也各种各样。如果只是检测文字的话,你会发现真实世界里的很多不是POI,有的只是标牌、标语、广告、对联、交通标志等。所以,要区分出POI和非POI。 有很多其他的复杂场景,这里不一一举例了,有些可能平时也不太能想到,比如三维挂牌,它不是一个平的牌子,在街角,可能是一个水果超市,沿着街角弯曲过来。这类牌子很难在一张图里完全检测出来,即使检测出来,一不小心就会分成两块牌子,所以真实世界的复杂性还是会造成更多的问题。 面对这么多复杂性,需要去分析具体场景的情况。很多时候最后的结果往往不是一个算法就能解决所有的问题,需要各种算法的融合。比方说,如果是文字,需要做检测,文字本身也需要做检测和识别。位置的话,需要做一些三维方面的推断。很多时候资料获取到以后也有模糊和遮挡的部分,也要做判断。 每一个判断不是单一办法就可以解决,不是光靠一个模型就能够做到最好的效果,需要的是两个甚至更多的模型,从不同的角度去解决问题,才能够达到更好的效果,这是在数据积累的基础之上。 上面列举的一些问题有一定的复杂性,跟所有的问题一样,越做到后面越难,我们现在还在做,这些算法很大程度上决定了地图制作的效率和触达到用户的地图质量,这些是非常重要的核心问题。 POI也不光是以上介绍的只需要判断是不是POI或者文字识别,很多时候还需要做版面的内容理解。如果一个牌子,需要知道这个牌子上的信息,有时候会有主名称,有时候会有分店,有时候没有,有没有联系方式、营业范围,这些都需要用算法去做。 视觉技术@高德地图-导航 以上介绍的是在地图制作方面有很多的复杂性,需要用视觉算法或者其他算法来处理。接下来分享下在导航方面的。 先说下自己的一个体会。前段时间在西班牙休假,欧洲的环岛特别多,谷歌(地图)导航经常提示我,进了弯道之后从第三个出口出去,我当时特别郁闷,因为要数口子,经常你也不知道那个到底算不算出口,所以走错了好几次。我在国内没开过车,国内的交通更复杂,例如在北京的西直门,有时候可以直接右拐,有时候需要转一个810度的圈。 我们希望对导航的方式做一个比较大的变化,让它变成所见即所得的场景。如果有算法能够直接告诉人们往哪边走,对人来说是更加有用的,能够让开车更加简单,导航变得更加直接。 很多汽车现在都会有摄像头,不管是前端还是后端,很多时候可以获取到视频数据。我们把AI算法计算出的效果叠加在视频上,告诉人们到底该怎么走。 高德在今年4月份发布了AR导航产品,这个产品里有一项是实景增强,它会告诉你应该保持在这条线上继续往前开或者转弯,会有压线的提示,会有箭头告诉你前面右转。 这个产品中,除了引导之外,还有别的功能。例如,也加入了前车的碰撞预警功能,会估计前车的距离和速度,这将帮助大家安全驾驶。其他事物也可以用更加直观的方式展示,例如限速,电子眼,跟斑马线相关的,如果看到前方有人,也会做出提示。 以上的功能看起来可能不那么难,但要实现起来很难。为什么?因为我们希望这是每个人马上就能实用的功能,所以要做到很低的成本。这和自动驾驶系统不一样。从传感器的角度,我们要做的是单个传感器,而且是低成本的相机。从计算的角度来说,自动驾驶系统可能会用一个几百瓦的专用芯片,而对于我们来说,所需要的算力大概只是普通手机的五分之一。 给大家看一个AR导航的例子,这是实际算法的输出,这个例子里面有车辆的检测,车道线的分割,和引导线的计算等。刚才提到了,高性能(低算力)是一个主要挑战,那我们在开发算法的时候就要充分考虑计算效率,包括各种手段,比如模型压缩,小模型训练优化,检测和跟踪的结合,多目标的联合模型,和传统GPS导航的融合,等等,需要几件事情在一个模型里做。 真实世界是非常复杂的,要做到高质量、高效的地图制作,或者做到精准的定位导航,在视觉方面还有很多工作要做。希望通过以上介绍,大家对视觉技术在高德地图中的应用,在出行领域的应用,有了更多的了解,也对高德的使命有了更多了解。 我们在很多时候需要去连接真实世界或者是理解真实世界,才能够让出行更美好。希望能够尽快的把这些做好,让大家实际应用高德APP的时候,能够感受到技术进步带来的体验变化。我今天就讲到这里,谢谢大家。 本文作者:高德技术小哥 阅读原文 本文为云栖社区原创内容,未经允许不得转载。

October 17, 2019 · 1 min · jiezi

大规模手机定位采集系统设计

一、业务场景分析基本的业务需求可分为两大部分,第一部分是手机端间隔一定时间上报一次位置信息,第二部分是后台系统可以实时看看手机设备当前所在的位置,并绘制轨迹。总之就是用户安装了此应用,就相当于给自己装上了一个跟踪器,所到之处,都将有所记录。我们先来保守计算一组数据,假定用户基数为10万,每隔5秒上报一次位置信息,而这5秒期间,地图SDK大概会给出2次定位数据,由此得出,一次上报的瞬时峰值大概是20万条数据,一天将会达到300多万的数据。这样的QPS已经算是很高了,当然,绝大多数情况下是不会触顶的。另外一方面,后台系统在查询的时候,也面临着一个巨大的挑战:如何从海量的数据中找寻符合条件的那一部分?查询的条件无非是围绕三个维度展开的:时间、对象和区域。类似“查询某块地理位置栅栏内的所有用户在一段时间内的位置信息”,这就是一个典型的查询业务需求,涵盖了三个维度的条件。当然,还有一些距离的测算和排序的需求也是在所难免的。综上所述,我们要解决两个难点:1、上报用户的实时位置信息; 2、处理海量数据的读写请求。以上两个难点是任何LBS应用不得不攻克的,这是支撑业务发展的关键点。二、抽象的系统架构我们可以将整个请求链接进行拆解,分别用对应的策略解决这部分的难题:1、客户端收集数据。这一部分有四个基本要求:准实时,不丢数据,低功耗,高效率。2、网关限流。主要为了避免涌入大量无效请求,消耗系统资源,拖跨服务器。3、负载均衡。为了应对不断增长的访问量,服务实例必须支持横向扩展,多个实例之间按照一定的策略进行负载均衡。4、异步化读写数据。需要借助中间件,起到削峰的作用,这一部分的设计会重点阐述。5、数据存储层高可用。采集的数据不要求强一致性,依据CAP理论,满足AP两个条件即可。解决办法通常是集群化,避免单点故障,进而实现程序上的读写分离策略。三、技术选型接下来是针对上述五大部分在技术实现上的考量。目前客户端是苹果机和安卓机,未来很可能会接入友商的车载OS。在网络状况良好的时候,可以实时采集,实时上报,倘若网络状况不好,也不会丢数据,采用MMAP实现本地缓冲区。当然,为了上报效率,综合考虑还是按批次上传,过于频繁的上报也会致使耗电量攀升。网关限流和负载均衡交给了nginx,学习和开发成本低,重要的是效果很好,并且能够达到服务横向扩展的目的。我们使用了nginx基于ip地址的限流策略,同一个ip在1秒钟内最多允许3个请求,burst=5,为了应对突然的流量的爆发,还有一个nodelay参数,我们选择不加了,意味着请求队列和缓冲区都被塞满之后,直接返回503错误码,不再等待了。目前,是1个master进程,5个worker子进程,此外,超时时间、最大连接数以及缓冲区的设置值得斟酌,服务器性能好的话,可以设置得高一些。负载均衡的策略不是基于权重的设置,而是使用的最少连接 (least_conn),因为在我看来,每个服务实例都是可以被同等对待的,哪台空闲,就优先请求哪台。如果非要在此基础上设置一个weight,那就把性能高的服务器设置成较高的权重。为了应对大量的位置上报请求,必然需要引入消息队列。因为技术团队一直在使用RabbitMQ,并且一番压测后,表现依然坚挺,所以成为了我们的不二选择。此外,为了减轻存储层的压力,在数据落盘前有一个缓冲机制,是典型的主从双Buffer缓冲池,避免与存储层频繁交互,占用过多connection,提高了存储层的工作效率,但是缓冲池Flush的时候,会带来一次“IO尖刺”,可以调整缓冲池的Threshold,把“IO尖刺”控制在一个合理的范围内。最后,也是最引人关注的是存储层的选型。我们面临的选择比较多,我们预研了4种有可能的方案:MySQL,Redis,PostGIS,MongoDB。MySQL的方案有两条路可走,第一是使用纯SQL进行计算,很明显这条路子受限于数据量,随着数据量的增大,计算量剧增,系统性能急剧下降。第二是使用MySQL的Spatial Indexes,但是这类空间索引是MySQL5.7版本引入的,不巧的是,我们用的是阿里云RDS,MySQL版本是5.6.16,不得不放弃MySQL的方案。基于Redis GeoHash的方案,在性能方面是没任何问题的,但是有一个重大的缺憾,就是非常受限于距离查询,而无法方便的匹配另外的附加属性,也就是上述三维需求(时间、对象、区域)中,只能满足区域查询的需求,若想进一步过滤,还需要借助其他的存储技术。留下来的PostGIS和MongoDB是现在比较通用的解决方案。PostGIS的专业性很高,是地图服务商的首选,对OGC的标准支持得非常全面,提供的函数库也十分丰富。当然,MongoDB也不赖,3.0版本引入的WiredTiger存储引擎,给MongoDB增色了不少,性能和并发控制都有了较大幅度的提升。单就LBS应用来说,两者都可以很好的满足各方面的业务需求,性能也不是我们首要考虑的因素,因为两者的可扩展性都很强,不容易触及瓶颈。最后我们选择了MongoDB,是因为技术团队对此接受程度更高,MongoDB本来就是公司技术栈中的一员。PostGIS相对来说学习成本较高,因为Postgresql是一种关系型数据库,如果只接入普通的数据类型,其实相当于是维护了另一种MySQL,完全没必要,但是如果想用上GIS相关数据类型,现有的ORM框架支持得并不友好,开发效率低,维护成本高。四、异步读写设计出于对用户体验的考虑,不能因为读写速度慢让用户傻傻的等待,这类问题有一个通用的解决方案:异步化。异步化的写请求很好实现,如前述所说,通过消息中间件来解决此问题,对于客户端的位置上报请求,不需要强一致性,能确定数据被塞入消息队列中即可。除此之外,还在消息队列和存储层之间加入了双Buffer缓冲池,用以增加flush的效率。上图中的Buffer-1和Buffer-2共同组成一个循环队列,每次只有一个Buffer用了缓冲数据。图中的Flush Point表示每个Buffer达到一定的阈值(Threshold)后,将会触发数据落盘,并且会在此刻切换Buffer。图中所示的阈值是50%,可以根据实际情况上下调整。值得注意的是,在Flush Point,应该是先切换Buffer,再flush数据,也就是在flush的同时,还能接收上报的位置信息。如果要等待flush完毕再切换,将会导致流量过渡不平滑,出现一段时间的队列拥塞。接下来要解决大量读请求,应对这种问题,有一个不二法门就是:拆。非常类似“分表”的思想,但是在这个场景下,没有传统意义上“分表”所带来的诸多副作用。“分表”有一个规则,比如按Hash(user_id)进行“横向分表”,按照常用字段进行“纵向分表”。受到Hadoop关于资源管理的启发,在此位置采集系统中,使用了“元数据”来代替分表规则,这里的“元数据”相当于NameNode,是管理数据的数据,将散落在不同位置的数据集中化管理。如上图所示,按城市级别进行分库,每个城市的位置数据相对独立,体现在客户端的功能就是“切换城市”。“分表”意即分成多份Collection,以一天为最小粒度,因为一个城市的当天数据通常是“最热”的,众多查询请求都需要这份数据,分页,聚合,排序等需求都不是问题了,因此一天一个Collection是比较合理的切分。当然,如果一天的数据量过少,可以适当延长数据切分的周期。那么,如果查询请求的时间段跨天了,该怎么办呢?这时候,“元数据”就发挥威力了。查询请求分为两部分,第一个是定位元数据,就是在meta data中找寻符合条件的所有Collection(s),为了尽可能缩小查询范围,需要指定一定的时间区段,这个也是有现实意义的。所有的位置数据被分为了三种等级:Hot,Cold,Freeze,Hot等级通常是指当天的数据,读写最频繁的部分;Cold等级被界定为过去一个月内的数据,应对的各类查询和分析的需求;Freeze等级是已归档的数据,没有特殊情况不会被解冻。通过时间区段拿到N个Collection(s)后,附加上其他的查询条件,循环N次,成功循环一次,就渲染一次获取到的数据,直到循环结束。上述N>1的业务场景只可能出现在后台管理系统,也就是移动端不会出现跨天的业务需求,提供的API都是针对Hot级别的数据。如果一旦出现了这种情况,可以限制时间区段,比如只能获取两天内的数据。五、总结本文详细阐述了手机定位采集系统的设计,整个系统的复杂性集中在了数据的存储和呈现,我在此文中都给出了相应的解决方案。除此之外,整个采集系统还会有其他的功能模块,诸如日志采集与分析,实时监控等,限于篇幅,不再逐一叙述了。以下是扩展阅读,对于理解整个系统会有所帮助,建议阅读之。1、细说双Buffer缓冲池2、物联网设备网关系统架构设计扫描下方二维码,进入原创干货,搞“技”圣地。

April 9, 2019 · 1 min · jiezi