Web 前端中的增強現實(AR)開發技術

blank

Web 前端中的增強現實(AR)開發技術

本文作者GeekPlux ,首發外刊君,也可以到GeekPlux的部落格閱讀本文。註明作者和地址即可轉載。

增強現實(以下簡稱AR)浪潮正滾滾而來,Web 瀏覽器作為人們最唾手可得的人機交互終端,正在大力發展AR 技術。很多Web 前端工程師也在尋求職業轉型,於是我把我近半年的相關調研結果在此匯結成文。本文力求把目前前端方向的AR技術都羅列一遍,細節不贅述(保證文章篇幅不過長),只做概括和科普(因此文章中的鏈接很多),零零散散寫了一個多月(拖延症),歡迎已經在從事該領域或研究的道友前來糾正補充。

blank
Web AR 初音未來

AR 可以簡單的理解為一種實時將虛擬圖像疊加在現實場景中的技術,且能交互[1]。我個人覺得AR 比VR 要有前景,主要因為:

AR的優勢在於把目之所及的現實場景變成了背景,並將現實世界和數字世界無縫連接。

當然這個“無縫”目前還談不上,不過一直在進步。在談Web 前端如何做AR 前,有必要先了解一下AR 實現的2 種主要方式和其關鍵技術:

AR 實現的方式和關鍵技術

AR 的主要實現方式有2 種[2][3]:光學透視式(Optical see-through) 和視頻透視式(Video see-through)。目前,市面上的頭戴式設備通常採用2 種方式中的1 種或2 種都採用,而手持設備(手機、平板等)通常採用視頻透視式。光學透視式是將電腦生成的數字圖像顯示在眼前的一層半透明鏡片上,這樣就可以使現實場景和虛擬訊息同時出現在視網膜上。而視頻透視式技術是將現實場景首先通過相機錄入電腦,經過和虛擬對象整合、壓縮,再統一呈現在用戶眼前。兩者各有優劣[4]:光學透視式中的現實場景因為沒有經過電腦處理,因此顯示得更自然、直接;雖然它實現簡單,但是也存在定位精度不高、匹配不准確、顯示有延遲等問題。而視頻透視式因為經過整合,所以匹配準確,最終顯示效果同步程度高,還能對生成的顯示結果根據用戶需求進行進一步處理;但是它實現難度較高,且丟失了一部分真實感。目前(2017年底) Web前端要想實現AR,都是靠的視頻透視式技術

另外,計算機視覺技術在AR 中起著至關重要的作用。因為實現AR最核心的是識別與追踪。首先,相機要先識別基準標誌、關鍵點、光學圖片等;然後再根據特徵檢測、邊緣檢測或其他圖像處理方法來實時追踪;最後將虛擬圖像疊加到真實場景中。根據2008 年的統計結果顯示,近十年著名的AR 會議ISMAR 中有關追踪技術的論文占到了20%以上[3].

Web AR

根據上一節的闡述,我們可以得出結論:要實現AR需要識別、追踪和渲染三步,在瀏覽器中也不外如是。另外,還可以結合傳感器來提供更多的交互或讓AR 渲染得更準確、通過網絡連接雲端來加速計算或交換更多數據等。如下圖所示,這是我自己整理出的一個Web AR 流程圖。 Web AR 或者說移動AR 在某些方面如便攜性、傳感器豐富、自帶網絡等還是有很大優勢的,在此我就不多說了。

blank
Web AR 流程圖

WebVR 規範

首先,Web AR 目前還是一項前沿技術,沒有標準也沒有成熟的庫供使用,不過已經有大公司和一部分開發者正在積極推進。 2017年10月2日W3C的WebVR組發布了WebVR規範1.1版的初稿,2.0版還在熱火朝天地修訂當中。

WebVR是一個開放標準,使您可以在瀏覽器中體驗VR。我們的目標是讓每個人都可以更輕鬆地體驗VR,無論您擁有什麼設備。 - webvr.info

為什麼本文的題目是Web AR,這裡卻提到WebVR 呢?因為WebVR規範中的部分API對Web AR也同樣適用。比如VRDevicePose可以獲取攝像頭位置。這是目前唯一接近Web AR 的標準,有了標准我們就可以只針對規範的接口做開發,從而適應絕大多數的設備。擴展閱讀: WebVR於增強現實針對智能手機AR的WebVR API擴展

WebARonARKit, WebARonARCore

ARKit 和ARCore 分別是蘋果和谷歌兩大巨頭出品的移動AR SDK,提供的功能也類似:運動追踪、環境感知和光線感應,我相信很多對AR 感興趣的開發者對這兩個SDK 都不陌生。但這兩個都是移動AR的SDK,於是谷歌的AR團隊提供了WebARonARKitWebARonARCore兩個庫,以便開發者能用Web技術來基於ARKit和ARCore開發,從而實現WebAR 。目前這兩個庫都還在試驗階段,想吃螃蟹的人趕緊去試試。其實現原理都是結合特定係統(iOS 和Android)擴展了WebVR API。 Google AR團隊封裝了一個three.ar.js的庫,提供了一些實用的AR API,包括ARView, ARReticle, ARPerspectiveCamera, ARDebug和ARUtils等。

AR.js

2017年SIGGRAPH(圖形學頂級會議)上AR.js可謂大放異彩,有人做了Web AR 相關的session就是用了AR.js來講解。 AR.js是Jerome Etienne開發的一款Web AR庫,可以用十行HTML就實現AR ,並有60 FPS的幀率。但其實AR.js 做的事很簡單,它主要封裝了以下幾個庫:

  • WebRTC。下文會詳細講解,主要是獲取視頻流。
  • JSARToolKitARToolKit可以說是第一個開源的AR框架,在1999年發布,一直更新至今。雖然歷史悠久但目前仍被廣泛應用( 官方網站的風格一點也沒有歷史感)。它主要提供了識別和追踪marker 的功能,本文附錄中還有補充。
  • Three.js, Babylon.js, A-Frame。這幾個都是基於WebGL 的渲染庫,用於渲染要在AR 環境中顯示的東西,下文會擴充。

由此觀之,AR.js 像是一個把所有輪子都拼起來的瑞士軍刀,簡單易用。作者在GitHub 和Twitter 上都很活躍,有什麼問題可以直接問他。

WebRTC 獲取視頻流

前三節我們提到了一個正在成形的標準和兩個框架,是目前Web AR 的最新進展了。指望標準發布肯定黃花菜都涼了,但我們可以自己動手豐衣足食。

剛才我們說到AR 首先要識別,那就要用到WebRTC 技術。 WebRTC(Web 實時通信,Web Real-Time Communication),顧名思義是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術。它其中有個很重要的API: getUserMedia()可以實時獲取攝像頭的視頻流,這是視頻透視式的AR實現的前提(目前iOS 11剛剛支持這個API,Android是很早就能用)。有了視頻流我們就可以分析其中的特徵點,運用計算機視覺的算法識別和追踪視頻流中的事物。這裡有2 個要點也要提一下:一是getUserMedia 默認獲取的是前置攝像頭,如果想獲取後置攝像頭的視頻流,需要用navigator.mediaDevices.enumerateDevices() 將設備的音頻、視頻設備遍歷得到,具體參照demo ;二是要用https打開網頁才能訪問攝像頭。

Tracking.js, JSFeat, ConvNetJS, deeplearn.js, keras.js 識別與追踪

獲取到視頻流之後的工作就是識別和追踪了。視頻流你可以看作是一幀一幀的圖像,所以處理視頻流的過程可以理解為圖像處理的過程。但這裡其實還涉及到一個如何傳輸視頻流的問題,一般有兩種方式:

1. 在前端直接處理視頻流

在前端直接進行圖像處理,可以用Tracking.jsJSFeat 。這兩個庫類似,都是在前端做計算機視覺的,包括提取特徵點、人臉識別等。把WebRTC 拿到的視頻流直接傳給它們並調用API 就能得到自己想要的效果。對於一些成熟的算法,如人臉識別,可以直接拿到識別結果,如果自己要識別的物體比較複雜你也可以自己進行特徵點的計算,但這可能在前端會算力不足,關於性能的問題下文再論述。

提到計算機視覺,不得不提深度學習,畢竟現在很多圖像處理算法被深度學習吊打。 ConvNetJS ,是斯坦福大學開源的一個前端深度學習框架,可以讓你在前端完成深度神經網絡的訓練。 deeplearn.js則是Google Brain團隊搞的,功能和ConvNetJS類似。現在ConvNetJS 好像不怎麼維護了,deeplearn.js 還在頻繁更新中,感興趣的同學可以試用一下。另外一個緊鑼密鼓開發的深度學習庫keras.js則是讓你可以在瀏覽器中運行已經訓練好的Keras模型( Kears是著名的深度學習開發框架),並支持WebGL 2。

這些框架都在主頁上提供了豐富的Demo,非常有趣,把玩一下說不定激發你的靈感。

2. 前端傳輸視頻流給後端,後端處理完畢返回結果到前端

另一種處理視頻流的方法就是傳到後端去處理,後端處理方式的選擇就數不勝數了,現在實現AR大多數用的都是SLAM算法,後端處理完返回前端結果即可。那麼如何傳輸成了我們前端同學的難題,一般有這兩種方法:

  • 傳圖片訊息給後端。 Canvas 提供了兩個API,一個是toDataURL,它可以生成圖片的base64 字符串;另一個是toBlob,這個方法是異步的,可以將圖片轉換成Blob 文件對象,因為其是二進制的,所以更方便傳給後端。具體使用來看,後者比前者的效率更高一點。
  • 傳像素訊息給後端。 WebGL 的readPixels 方法,可以獲取framebuffer 中的像素值。

除此之外應該還有其他方法,總之目標是將前端的圖像訊息傳給後端,傳輸方式可以用AJAX,也可以用WebSocket,具體根據場景來定。

這一節主要講了識別和追踪,其實除了單純的對圖像、視頻流處理,我們還能通過移動端設備的各種傳感器數據獲取到更多的距離、深度、光照等訊息,從而使識別追踪更準確。

A-Frame, Three.js, Babylon.js, Pixi.js, WebGL 渲染與交互

講完識別和追踪,終於該聊聊渲染了。 A-Frame是Mozilla團隊在2015年開源的一款做WebVR的框架,但日前A-Frame團隊發布的aframe-xr其中包括了一些Web AR組件。一開始我們也說過VR和AR中有部分實現是重合的,所以用A-Frame的各種組件可以讓你用很少的代碼構建出AR所需要的3D立體世界。提到3D,不得不提WebGL 。 WebGL 是OpenGL ES 在瀏覽器端的實現,你可以理解其為OpenGL 的子集。用WebGL 你可以操作前端的每一個像素點,懂一點圖形學的同學一定知道它的強大,而且它能調用GPU,所以前端涉及到GPU 的地方也缺不了它。 WebGL雖然強大,但寫起來異常複雜,學習成本也很高,而前端最著名的3D庫Three.js將繁瑣的WebGL API進行了封裝和優化,讓你可以用可讀性更好的代碼在前端書寫WebGL。 Pixi.js和Three.js做了類似的事情,但它只支持2D渲染,不過它還是很好用的,如果你只是想用WebGL來做複雜的渲染但沒涉及到3D場景,不妨試試它。 Babylon.js就更牛了,它是一款遊戲引擎,也是封裝了WebGL在前端做高性能的渲染,但它和Three.js的關注點不一樣,如果你對渲染的精細程度非常有要求,比如光線、陰影等,那麼你可以考慮下babylon.js,畢竟這是款由微軟前員工開發的遊戲引擎啊……

這些基於WebGL 的渲染方法,有一個共性的難題是如何交互,比如hover, click 效果如何實現。其實在Web AR 中交互非常局限:如果是桌面設備即電腦,和瀏覽網頁的交互差不多,有hover, click, drag 拖拽等;如果用的是移動設備,即手機、平板,則可能有zoom 的交互(這裡多嘴一句,其實移動AR 中,應該盡量避免手指去zoom 的交互,而應該引導用戶用移近或移遠設備來進行放大縮小)。這些實現起來要依賴於光線投射算法Ray casting方法。 Three.js直接提供了Raycaster類供實現ray casting算法。其實原理很簡單,就是攝像頭(這裡的攝像頭不是指手機的攝像頭,而是你渲染時的Camera,可以參考Three.js中的Camera )視作視點,與你在屏幕上觸碰的點坐標連城一條射線,看這條射線與你視圖中哪些物體相交。

blank
Ray casting 算法

這一節主要講了渲染與交互,事實上在實現AR 的時候,識別追踪和渲染交互是同時進行的,如何給用戶更好、更流暢的體驗是現在Web AR 的又一大難題。

性能

性能是很多人關心的問題。目前瀏覽器的算力確實還不足以與客戶端去媲美,但較之前也有了巨大的提升。識別和追踪本質上是像素級的計算,對算力的要求都很高,因此maker-based 的AR 定位效率通常比makerless 的要高很多。此外,計算機視覺算法的效率對性能影響也很大,比如人臉識別目前較其他識別要成熟很多,所以人臉識別的算法在Web 前端運行還算流暢。

提升性能的方法有很多種,大家一般會先想到用WebGL 調用GPU 加速,其次會想到用Web Worker,WebAssembly。前兩者我都試過,把純計算的代碼移到WebGL 的shader 或Web Worker 裡,這兩者雖然都是加速計算,但適用場景不同。 shader可以用於加速只和渲染(重繪)有關的代碼,無關渲染的代碼放入shader中反而會造成重複計算。 Web Worker 適用於事先計算或實時性要求不高的代碼,如佈局算法。 WebAssembly我還沒在做AR的時候用過,還有一個庫gpu.js也沒試過,希望有大神試過之後告訴我有什麼效果。

還有一種變相“提升”性能的方法是用濾波算法(比如卡爾曼濾波)將卡頓降到更小,讓用戶從視覺感受上似乎更流暢。

結尾

現在Web AR 大潮剛剛開始,有很多高地需要人去攻克,比如光照估計、性能優化等,希望有興趣的同學可以積極參與進來。而且Web 前端無論是技術還是人口都發展迅速,充滿了無限可能,有限的只是你的想像力。我很久之前做了個人臉識別+ AR的小demo ,在GitHub上 github.com/geekplux/AR- ,大家可以玩玩,其實就幾行代碼。下一篇可能會寫寫Web 前端做人臉識別相關的文章,感覺又給自己挖了個大坑,希望我的拖延症早日治好。

附錄:AR 開發技術

參考文獻[2] 中曾總結了當時所有的AR 開發技術,如下表:

blank
AR 開發技術

這張表將AR 開發工具分成了四類,分別羅列出來。其實目前大多的AR 開發都是用Unity 去做的,很多第三方SDK 也都是先集成到Unity 上,再由Unity 輸出到對應設備所需的格式。表中的Vuforia據我觀察是目前用的最多的第三方SDK。 ARToolKit則在Web前端和移動端用的很多,它的開源版是基於標記的(Marker-based),也提供機器學習的訓練方法,讓你可以將任意圖片訓練成Marker。另外由於這張表是2015年的,當時蘋果公司的ARKit和谷歌的ARCore這2個SDK還沒有橫空出世,可以將其歸到表中的第三行。

參考文獻

  • [1] Azuma R T. A survey of augmented reality[J]. Presence Teleoperators & Virtual Environments, 1997, 6(4): 355-385
  • [2] Billinghurst M, Clark A, Lee G. A survey of augmented reality[J]. Foundations and Trends in Human-Computer Interaction, 2015, 8(2-3): 73-272
  • [3] Zhou F, Duh BL, Billinghurst M. Trends in augmented reality tracking, interaction and display: a review of ten years of ISMAR[C] //Proceedings of the 7th IEEE/ACM International Symposium on Mixed and Augmented Reality. Washington : IEEE Computer Society Press, 2008: 193-202
  • [4] Rolland JP, Fuchs H. Optical versus video see-through head-mounted displays in medical visualization[M]. Cambridge: MIT Press, 2000, 9: 287-309

What do you think?

Written by marketer

blank

HTTPS 的故事

blank

我所知道的vue-router