昨天IN2写了伊利诺伊大学的Marco Cavallo关于如何利用谷歌街景数据制作3D点云城市模型的文章,估计被标题吸引看到最后的同学会非常气愤:留图不留种,XXXXX。 其实,IN2昨天下午正好有事儿,于是先把上篇做好给大家看下,你们要的“种”其实都在下篇,这篇文章里有好几个算法公式,IN2会尽最大努力翻译的靠谱,但是依然不能保证绝对正确。所以,觉得自己鸡肠文不错或者特有钻研精神的技术同学,请务必去看英文原文,然后帮IN2指出错误,谢谢鸟。 书接上文 计算深度地图 现在我们有了全景图片,接下来需要做的是提取对应的深度地图。Google Maps REST API允许用户从下面这个链接 ?output=json&cb_client=maps_sv&v=4&dm=1&pm=1&ph=1&hl=en&panoid=PANORAMAID 获得一个深度图像的JSON代码(representation)、其中包含了全景图片中每个像素从相机到最近表面的距离信息。通过处理这些数据,并将其转化成无符号8位整数的阵列( array of unsigned 8-bit integers)后,j2直播,我们就能获得标题信息(Header Information)并获得有用的数据,例如参考平面数字(number of referenced planes)。 事实上,在512×256网络上的每一个像素都对应了众多平面(Planes)中的一个,通过Normal Vector和其到摄像机的距离而定。所以,要想计算出一个像素的深度,我们必须决定从摄影机中心发出的光线和相对对应平面的交叉点。将其重复到所有平面,我们能够将深度地图制成512×256元素的32位浮动阵列(32-bit float array of 512×256 elements),这个要比我们的RGB全景图片分辨率低多了。 至于计算,对于每个点我们考虑它相关的平面,将其距离计算如下:
算法1:深度地图计算 公式中的“indeces”包含了每个像素相关平面的阵列,为了能获得一个代表单平面w∗ h vector的更简便的图片,例如,我们可以创造colored canvas,其中宽度为w、高度为h,而每个像素可以被定义为:
算法2:深度地图可视化 这时候会的出一个下图类似的图片
创造点云 现在我们已经有了每个像素的深度信息,我们需要创建点云同时将每一个点还原至之前获得的全景图片的色彩。考虑到 npoints =w∗h points,我们定义2个npoints ∗3 漂浮阵列包含了3D空间位置和每个点的色彩。现在,我们必须考虑全景图片中的一点本来来一个球星图片,所以我们必须使用下列公式将其重新投射到空间中:
算法3:点云创建 注意,除了重新投射,在2D中还原像素的位置也是必要的,因为你需要从彩色全景图片中获得色彩信息,因为全景图片的分辨率是不同的。 合成点云 利用Google Street View API提供的不同地址间的链接,我们得到了相信全景图片的标识点和地理信息。所以,我们现在可以以新的地点坐标重复之前的步骤,用全景图片创造3D场景并能够丰富此前我们用个点创建的场景,或者重建一个真实世界的场景。我们这个项目来说,会使用两个界限:两个全景图片间的最短距离以及深度信息的重复。可以将第一个载入的全景图片想象成一个数的根部,然后以一种广度优先的方式(breadth-first)进行探索。 平均来说,我们注意到谷歌的深度地图通常包含现实世界的200-300米的距离,所以我们决定以1:1的比例来重建场景。我们将第一个点云的中心坐标设为(0,0,0),然后我们根据真实世界到全景位置的距离,按照offset proportional来加入其他的数据。利用一些几何和近似值,我们可以用这样一个算法来计算[x,z]平面的distance vector:
算法4:Offset距离运算 除了这个转化,这个点云需要根据从谷歌街景中提取的Heading特定信息来沿着垂直Y轴来旋转,然后才得到了一个近似于如图的效果。
评估 投射以及位置精确度 (责任编辑:本港台直播) |