从前端工程师到 AR 工程师

1,984 阅读7分钟
原文链接: zhuanlan.zhihu.com

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

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

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

当然我个人的技术视野也是有限的,如果您有更好的算法或者相关技术链接请在评论指出,也麻烦您点个赞!