下载 App
    Web前端
    专注前端开发,关注用户体验

从前端工程师到 AR 工程师

柏子阿里巴巴集团的高级前端工程师。

为了入门 AR,我做了一个简单的图像识别的 Demo,将不同的图片对准检测区域,会出现不同天气效果,效果如下图:


AR Demo 和  github 地址 (PC网站,不推荐手机使用)

玩这个 Demo 的时候需要一个有摄像头的电脑和手机,将鼠标移动到天气图标上会有二维码,用手机扫描二维码进入天气图标网页,将图标对准屏幕的黑色区域进行扫描就可以出现对应的动画。

这是一个 Marker Base 的 AR 程序,Marker Base 就是识别一个特定的图像(高级的二维码...),而高级的AR 可能是 Marker Less 的,比如识别环境中的车,房子,行人。目前由于技术限制,大部分AR都是 Marker base 的。

其实我觉得 AR 比 VR 更困难,VR 只需要给用户“输出”一个虚拟世界,而 AR 还需要根据用户 “输入”的现实世界,“输出”虚拟的效果。“输出”动画对于前端来说已经是轻车熟路,但是如何处理用户“输入”的现实世界是很大的技术挑战。虽然现代 JS 引擎已经很快了,但是在处理摄像头传入的图像数据任务时,单线程的 JS 的马车远远落后于同时代的 Native 火箭。

在 WebRTC 技术的支持下,我们可以拿到摄像头的数据并且把它绘制成图片,一旦用 JS 处理像素,噩梦就开始了。AR 应用对计算速度要求极高,动画至少要30帧才能被用户勉强接受,也就是说,要在 34ms的时间内,完成图像处理-->图像识别-->动画渲染。这三个操作都是 CPU 密集运算,如果全部用 JS 来做,肯定无法在一般配置的电脑上保证帧数。这时就要拿出 WebGL 和 WebWorker 一起来加速了。

图像识别的第一步都是图像处理,彩色图片中包含太多无用的信息,同时摄像头在连续拍摄的时候有噪点,需要把主要信息提取出来,并且尽可能降噪。

转换成黑白的算法有很多,但是基于 GPU 计算的话,大多还是边缘检测,边缘特征的点会被标记成白色,另外再对图中的白点大小进行筛选,太小的白点可能是摄像头的噪点。这样两步操作用 WebGL 来做60帧毫无压力。


接下来把黑白的图片像素读取出来进行图像识别,用 GPU 实现的图像识别还真的很少见,这里我选用了第三方的神经网络 (ConvNetJS) 进行图像识别。对于前端来说,神经网络还是一个比较陌生的词语。大概就是机器学习的一种算法,如果探索精神不是特别强,可以把它当成一个工具而不用了解具体实现,就像你用React不需要知道具体怎么将 jsx 转化成 DOM。接下来主要讲一下怎么用神经网络进行识别。

“机器学习”一般和“大数据”同时出现,我们建立一个神经网络之后,将分类好的图片传入神经网络后,神经网络会根据图片分类自动调整参数,当传入的图片足够多的时候,神经网络就能学习出正确的参数来区分图片类型。

整个训练过程也在网页中进行,首先对每种 Maker 图像进行取样,JS对这些样本进行旋转,缩放和位移的变化生成大量的图片训练集,训练完成后的神经网络就可以用作识别图像。当我们改变 Maker 图片后,可以重新训练新的神经网络。

任何一张图片传入神经网络之后一定会被进行分类,这会导致当用户没有提供任何Maker时,神经网络错误地进行分类,所以训练的时候增加了一个异常类,这类图片可以是任何数据。


一个样本变化后的训练集


当神经网络训练好之后,我们可以通过 JSON 来进行保存和加载。为了保证页面的渲染帧数,神经网络识别图像的算法放在 WebWorker 里面,这样就算图像识别不能达到30帧,动画渲染也可流畅运行,对于性能比较差的电脑,用户识别图像的过程可能会比较慢,但不会影响动画播放。

然后说动画,由于浏览器天生的优越性,无论是 WebGL,Canvas2D 或者 SVG 动画都能在现代浏览器中行云流水。但是要作出惊艳的动画还是需要一定的技术积累。

神经网络主要进行图像分类是很好用的,但是它不是真正的图像识别。我们的应用可能会在 Maker 上显示一个3d模型,当 Maker 位置发生变化的时候,3D 模型也跟着位移。主流的 AR 应用采用 SIFT 算法实现此功能,这个算法计算量很大,JS 扛不住这样的实时计算,不过这个算法有 GPU 实现版本,如果哪个大牛能用 WebGL 实现 SIFT,那么将对 WebAR 产生历史性地推动作用。


这个 Demo已经站在技术时代的前沿了-.-;;结合机器学习技术实现了 AR。Web 端因为各种 MV* 框架始终代表着 UI 界面的先进生产力,但是到了图像图形这一块就简直是石器时代,基本的算法都没有,运算性能还特别差,甚至现在的 iOS 还不能调用 WebRTC。但外国有句名言:“凡是能写成JS的最终都会被写成 JS”,毕竟 WebAR 所需要的技术都已经到位了,WebRTC 提供了摄像头的能力,WebGL 提供了并行计算能力,WebWorker 提供了多线程能力,现在就差相应的高效率算法了,而这些算法也是在Native中已经成熟了,不久的将来也一定会被翻译成 JS。WebAR 火起来只是时间的问题~~也许哪天你的 React 代码里面就会这样写:

render(){
 return <ARCamera size={size}></ARCamera>
}

如果您有更好的算法或者相关技术链接请在评论指出,也麻烦您点个赞!

阅读原文


    推荐文章

    • 前端开发,从草根到英雄(下)
    03-25   阅读 7591 次
    • 前端开发者必备思维
    03-29   阅读 7716 次
    • 15 个有趣的 JavaScript 与 CSS 库
    12-02   阅读 6615 次