多模型融合车辆检测算法(基于合成数据的实时三维车辆姿态估计)
多模型融合车辆检测算法(基于合成数据的实时三维车辆姿态估计)我们先扫描一种颜色,然后再测试类似的颜色(即扫描白色,然后测试浅蓝色)。在某些情况下,识别起了作用。效果虽然并不完美,但也许如果我们能扫描一整套基础色,就可以稳定识别出我们可能看到的任何颜色的汽车。接下来在真车上试验。试验表明,在真车上识别效果会有些不同。即使在同一辆车上进行扫描和测试,结果也不可靠。有时,识别出的汽车可能会以多种形式稍微旋转或平移。我们推测,车身油漆反光导致扫描识别车辆特征变得困难(Apple说明书中特别提到反光物体不适合3D识别)。ARKit有扫描和识别刚性三维物体的程序接口,这似乎很有用。把程序并内置到ARKit中,就不用花时间开发扫描识别功能了。于是,我们主要关注车辆颜色的识别。我们购买了不同颜色的车模以测试ARKit的颜色识别效果。在开始之前我们做了哪些尝试我们测试了下面几种现有的三维物体姿态快速估计方案。苹果的ARKit三维物体识别
项目概况
我们的客户对能自动够捕获更高质量车辆照片的AR应用程序很感兴趣。本文重点介绍一种用于汽车姿态估计的技术。在该应用中,引导用户站在距汽车一定角度和距离的位置,以标准化方式拍摄最佳照片。当用户处于正确位置时,将自动捕获高分辨率照片。
我们需要一种方法来大致确定用户与所拍摄车辆的空间相对位置。但这只是一个初版程序,我们只有几个星期的时间给出解决方案。为了缩短开发时间,该程序暂时只适用于特定车型。
目标与局限
• 在较短的时间内建立可行的解决方案
• 几乎实时的车辆姿态估计(<150 ms)
• 适用范围为具有不同颜色或配置的特定车型
• 应用程序能捕获高质量照片
在开始之前我们做了哪些尝试
我们测试了下面几种现有的三维物体姿态快速估计方案。
苹果的ARKit三维物体识别
ARKit有扫描和识别刚性三维物体的程序接口,这似乎很有用。把程序并内置到ARKit中,就不用花时间开发扫描识别功能了。于是,我们主要关注车辆颜色的识别。我们购买了不同颜色的车模以测试ARKit的颜色识别效果。
我们先扫描一种颜色,然后再测试类似的颜色(即扫描白色,然后测试浅蓝色)。在某些情况下,识别起了作用。效果虽然并不完美,但也许如果我们能扫描一整套基础色,就可以稳定识别出我们可能看到的任何颜色的汽车。接下来在真车上试验。试验表明,在真车上识别效果会有些不同。即使在同一辆车上进行扫描和测试,结果也不可靠。有时,识别出的汽车可能会以多种形式稍微旋转或平移。我们推测,车身油漆反光导致扫描识别车辆特征变得困难(Apple说明书中特别提到反光物体不适合3D识别)。
第三方SDK
我们也测试了一些其他SDK,结果和ARKit类似。一些库需要特定的“初始化模板”或匹配用户位置来追踪三维物体。这并不理想,因为我们想引导用户到某些位置,因此识别需要从各种各样的角度或位置进行。
照片质量
我们尝试过的ARKit和SDK的另一个缺点是照片的质量和分辨率。使用ARKit可捕获的最高分辨率为1920x1440。同时ARKit对焦点和曝光的控制也非常局限。由于我们的目标就是需要捕捉高质量的车辆照片,因此,除了高分辨率外,我们还希望对聚焦和曝光进行精确控制。
建立基于神经网络的姿态估计程序
由于使用第三方解决方案没有成功,加上照片质量不佳,我们决定自己做一套方案,该方案可以配合苹果的AVFoundation相机使用。我们选择了神经网络算法,因为这是姿态估计的最前沿技术,并且有很多开源项目和研究可以利用。
姿势估计方法
对于给定图像,我们如何预测图像中对象的三维姿态?一种常见的方法是基于对象的标准模型来预测一组已知点的图像位置。例如,给定一张汽车照片,它的左大灯在哪里?这种特征点足够多,我们就可以估计汽车相对于相机的三维姿态。
网络架构
如今,神经网络算法在处理各种任务上显示出惊人的准确性,加上网络架构和硬件性能的不断提升,神经网络算法也能够在移动设备上实时运行。
最近,我们遇到了一些基于CPM和堆叠式沙漏架构(stacked hourglass architectures)的动态人体姿态估计项目。
https://github.com/edvardHua/PoseEstimationForMobile
https://github.com/tucan9389/PoseEstimation-CoreML
这些项目包含许多有用的信息,可用于在移动设备上训练和运行你的姿态估计程序。
他们使用的CPM网络基于MobileNetV2,可以输出14个身体部位(左肘,右膝等)的二维热图。
利用它,我们基本上可以获取每个关键点层的最大激活位置,然后使用OpenCV的SolvePnP方法估算车辆姿态。下图是我们使用最终的神经网络程序对车辆照片进行可视化分析,以及姿态估计。由于输出的热图分辨率有限,因此匹配并不完美。我们的模型输出的热图分辨率为192x192,因此限制了单次估计精确度。
其他方法和资源
我们刚刚用了CPM法来实现快速启动和运行,但还有其他方法可以解决此问题。有一种基于关键点的方法,是直接输出关键点的二维坐标。这使得它只能用于一辆车的评估,但对于我们来说也够用。受Hart Woolery手势估计算法的启发,我们在MobileNet上又加了几层点,即可最终输出1x28组关键点坐标。我们惊喜地发现,效果很好。如果有更多时间,我们可能会进一步研究这个方法,因为它比我们选择的CPM模型要快一些。
如果你在寻找人体姿势估计方法,请查看Jameson Toole最近关于fritz.ai人体姿势估计的文章:https://heartbeat.fritz.ai/pose-estimation-on-ios-with-fritz-60c8e5f7d195
还有一种方法是直接输出汽车的姿态参数,而不用经过中间的2d关键点(请参见BoxCars MultiBin)。由于时间紧迫,我们没有严格评估过前面说的这些方法,但是这些方法似乎确实好用。
查找汽车数据库
选定了网络架构,下一步就是找数据训练它。人体姿势估计的数据有很多(COCO DensePose MPII Overview of body pose datasets),但是带标注的车辆数据却很少见。也有一些数据库(Apollo,PASCAL 3d ),但它们似乎都有局限。大多数数据库都是针对自动驾驶汽车的,因此和大街上行驶的汽车有很大的差异,这可不是我们要研究的对象。 PASCAL 3D有3D汽车模型注释,但基本是从网络照片中收集的老车型。由于我们有所针对的目标车型,因此无需用其它车型照片训练(要是有更多时间,我们希望算法能适用更多车型)。还有一些数据库只允许用于非商业性项目。因此,我们尝试使用合成数据,把车辆直接整合到我们所希望的测试环境中。
建立合成车辆数据库
当无法获得机器学习所需的大量训练数据时,合成数据会派上用场。由于视频游戏行业的发展,我们可以利用Unity或Unreal等图形引擎进行渲染,以及最初为游戏而开发的3d资源。 尽管我们无法获得像光线追踪那样的渲染质量,但数据产生的速度、数量以及低廉的成本使其非常有吸引力。我们选择用Unity,因为比较有经验,时间也比较紧张。
Unity甚至给合成数据的常见需求提供了便于上手的demo程序。我们最近也简要介绍过如何使用SceneKit训练AR足球游戏中的脚部分割算法。
收集车辆3D模型
幸运的是有很多高质量的3D汽车模型。 对于非常高质量的模型,你可能要花几百美元购买,但是有很多便宜或免费的模型可以直接从Unity asset store购买:
https://assetstore.unity.com/3d/vehicles/land
我们收集了大约10个形状与目标车型相似的汽车模型,还有两种我们正在测试的车型。
标注
准备好模型后,下一步便是标注姿态识别所需的关键点。由于人体姿势算法需要14个关键点,我们也按这个来,以减少对这个pipeline的修改。此步骤需要建立14个空的参数对象,并为每种汽车模型定位它们:
通过命名每个关键点GameObject(例如left_back_wheel),在渲染过程中,我们就可以在保存标注数据时在GameObject中搜索关键点。我们也用深度测试来存储关键点是否被遮挡,但是最终并没有在训练中使用。
在数据库中创建变体
用合成数据训练时,一个大问题是模型是否可以推广到真实世界的图像。这是一个活跃且不断发展的研究领域,有许多有趣的方法。苹果公司的机器学习团队发表了一篇有趣的文章,使用GAN技术提高合成眼图像的真实感。我们选择的方法是域随机化。通过在训练数据集中创建大量变化,模型可在无需微调的情况下推广到目标数据集(现实世界)。
为了实现这一点,我们尝试在渲染图像之前尽可能使场景各元素随机化。这里一个主要问题是该程序会在意3D汽车模型上的一些次要细节,而这些细节不需要拓展到真实汽车的照片上。有一个经常被提及的轶事(可能不是真事):研究人员只用坦克被拍照的时间来训练坦克探测器。无论这个例子是真是假,训练数据和测试数据来自不同数据集时,都需要注意:确保转移到新数据。
车型变种
对于每一个车型,我们都在车身次要细节上设置了一些变化。诸如油漆反射率,车牌位置和牌号,玻璃颜色,轮毂款式和位置以及其他一些东西。我们还对车身进行了轻微缩放。
环境和背景
一开始,我们搭建和购买了一些场景,包含建筑物和真实的三维结构。获取高质量的真实照片十分困难,而且可能会很贵、很耗时。幸运的是,我们找到了一个很棒的网站https://hdrihaven.com / ,它提供了高分辨率的免费环境地图。这是我们必需的360 HDR全景图,可以在你的目标物体后面进行渲染,可以为场景中的对象提供光照和反射。我们还使用渲染脚本来改变反射和曝光强度。
利用skybox,我们创造了一个简单的平面作为汽车下面的地面。将不同的材质应用到地面上,偶尔将其全部隐藏在一起,产生了各种场景:
后处理效果
Unity有一个 “后处理堆栈(Post Processing Stack)”的功能,基本上是针对3D场景的照片墙过滤器。这些效果可能包括模糊、颜色分级等。你可以通过Package Manager或asset store将其添加到场景中,具体取决于你的Unity版本。除了内置的后期处理堆栈之外,我们还从asset store下载了另一组过滤器,名为SC post Effects Pack,价格为25美元。以下用后处理过滤器处理后的效果图:
后处理的效果很微米,可能难以发现。能看出来的是景深,噪点,云影,环境光遮挡,边缘高光,色相偏移和黑线条。我们可以随机调整这些参数以实现更多变化。
整合到一起
把变量都放到一起,我们最终得到如下图像:
即使这些看起来还不像真实的街道场景,但背景和照明的多种变化也会迫使程序提取所有照片中一直不变的车辆特征。如果仅使用街道场景,程序可能会将街道场景的元素纳入到车辆特征里;期望汽车本身始终具有一定的阴影和照明特征。
创建一个小型校验数据库
我们对数据库偏差的关注迫使我们手动标注了一些实车照片的关键点。手动逐个标注14个关键点相当耗时,尤其是对于被遮挡的关键点。为了加快速度,我们构建了一个非常基本的wxPython应用程序,它只需要为每个图像标记几个关键点。为此,我们使用OpenCV的SolvePnP来拟合给定了几个初始关键点的3D汽车模型,然后将其他关键点投影到图像中。标注好后,我们使用imgaug库实现随机图像强化。值得庆幸的是,imgaug支持随图像一起转换关键点,因此不必手动变换点位置。强化后,我们得到大约1500张图像来验证我们的程序。
好用吗?
对于我们测试的一组已知车型,第一轮测试的结果非常好。我们本以为应该需要在训练中加入更多真实的图像,或者更多地依赖于迁移学习,但最终证明不需要这样做。即使在大量汽车上进行测试,也能得到合理的结果(见视频)。这个模型还不能完美地应用于其他类型的车辆,因为这是把刚性的三维模型匹配到其它具有不同尺寸的汽车上。确实有给柔性车辆模型标记关键点的相关文献,因此我们可能会进一步研究,探索更通用的车辆识别程序。
代码
我们的计划是,如果我们有时间整理和训练更多的车型,我们将发布部分pipeline。目前,我们已经上传了一个iOS应用程序的demo代码,该应用程序使用ARKit显示估计的汽车姿态(记住,该模型是在固定视点范围和汽车模型上训练的):https://github.com/laanlabs/CarPoseDemo
作者:AIRX
原文链接:【AR三维物体识别跟踪】基于合成数据的实时三维车辆姿态估计
来源:AIRX社区微信公众号