1. 程式人生 > >[轉]Web 前端中的增強現實(AR)開發技術

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

本文轉自https://geekplux.com/2018/01/18/augmented-reality-development-tech-in-web-frontend.html

---------------------------------------------------------------------------------------------------------------------------------

本文力求把目前前端方向的 AR 技術都羅列一遍,細節不贅述(保證文章篇幅不過長),只做概括和科普(因此文章中的連結很多).

Web AR 初音未來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 在某些方面如便攜性、感測器豐富、自帶網路等還是有很大優勢的,在此我就不多說了。

Web AR 流程圖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 團隊提供了 WebARonARKit 和 WebARonARCore 兩個庫,以便開發者能用 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.js 和 JSFeat。這兩個庫類似,都是在前端做計算機視覺的,包括提取特徵點、人臉識別等。把 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)視作視點,與你在螢幕上觸碰的點座標連城一條射線,看這條射線與你檢視中哪些物體相交。

Ray casting 演算法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 上 https://github.com/geekplux/AR-AI-VIS-demo,大家可以玩玩,其實就幾行程式碼。下一篇可能會寫寫 Web 前端做人臉識別相關的文章,感覺又給自己挖了個大坑,希望我的拖延症早日治好。

附錄:AR 開發技術

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

AR 開發技術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 B L, 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 J P, Fuchs H. Optical versus video see-through head-mounted displays in medical visualization[M]. Cambridge: MIT Press, 2000, 9: 287-309

相關推薦

[]Web 前端增強現實AR開發技術

本文轉自https://geekplux.com/2018/01/18/augmented-reality-development-tech-in-web-frontend.html-----------------------------------------------

android studio | openGL es 3.0增強現實AR開發 (1) 建立一個openGL es 3.0開發環境

1.什麼是NDK,什麼是JNI? NDK:Native Development Kit(原生開發工具包), NDK允許使用者使用類似C / C++之類的原生程式碼語言執行部分程式。它包括下面的部分(1)從C / C++生成原生程式碼庫所需要的工具和buil

unity+高通vuforia開發增強現實AR教程

增強現實(Augmented Reality,簡稱AR),是在虛擬現實的基礎上發展起來的新技術,也被稱之為混合現實。是通過計算機系統提供的資訊增加使用者對現實世界感知的技術,將虛擬的資訊應用到真實世界,並將計算機生成的虛擬物體、場景或系統提示資訊疊加到真實場景中,從而實現

unity+高通vuforia開發增強現實AR教程

前段時間忙公司的事,好久沒到CSDN來了,看到教程有這麼多人蔘考,決心再接再厲,這篇教程就講講怎麼做video形式的增強現實。(自己做了個案例,少女時代著名的甩大腿舞戳我O(∩_∩)O) 高通的SDK好像沒有video的預製件,所以我一般都下載最新的samples,裡面

Android增強現實-AR的三種方式(展示篇)

這段時間研究了一段時間Android端增強現實的方式,總體分為兩個大類:全景圖和3D模型。 於是基於這兩種形式,以三種方式來展示增強現實: 1.全景360°GIF,支援拖動,縮放。 2.展示3D模型 3.Google官方展示全景圖探究 這篇部落格就

web前端知識小筆記

jquery getview 例如 get del tar and 條件語句 arguments 1.if條件語句相關 對於 if 語句括號裏的表達式,ECMAScript 會自動調用 Boolean()轉型函數將這個表達式的結果轉換成一個布爾值。如果值為 true,執行

Web API的路由——基本路由

名稱 nts delete nal dict quest 添加 let web api 一.Web API中的路由概念   路由的作用用一句話說明:通過request的uri找到處理該請求的Controller,Action,以及給Action的參數賦值。 web api

Web前端-Html部分筆記

HTML 表單 一、表單概述 1、作用: 用於為使用者建立 HTML 表單,用於向伺服器傳輸資料。 表單能夠包含 input 元素,比如文字欄位、複選框、單選框、提交按鈕等等。 表單還可以包含 menus、textarea、fieldset、legend 和

Web前端-Html部分筆記

以下是我對Web前端-Html部分的筆記,因為博主也是初學Web前端,有很多東西都還停留在表層的理解,如果我的部落格有任何錯誤,請及時評論或者私信我,我會及時更改。也歡迎同樣初學Web-前端的你願意關注我的部落格,我會把我每週的學習內容進行整理和上傳,方便大家溝通和交流學習經驗。 表格標籤

Web前端-Html部分筆記

下是我對Web前端-Html部分的筆記,因為博主也是初學Web前端,有很多東西都還停留在表層的理解,如果我的部落格有任何錯誤,請及時評論或者私信我,我會及時更改。也歡迎同樣初學Web-前端的你願意關注我的部落格,我會把我每週的學習內容進行整理和上傳,方便大家溝通和交流學習經驗。 列表標籤

Web前端-Html部分筆記

以下是我對Web前端-Html部分的筆記,因為博主也是初學Web前端,有很多東西都還停留在表層的理解,如果我的部落格有任何錯誤,請及時評論或者私信我,我會及時更改。也歡迎同樣初學Web-前端的你願意關注我的部落格,我會把我每週的學習內容進行整理和上傳,方便大家溝通和交流學習經驗。 一、常用基

Web前端-Html部分筆記

以下是我對Web前端-Html部分的筆記,因為博主也是初學Web前端,有很多東西都還停留在表層的理解,如果我的部落格有任何錯誤,請及時評論或者私信我,我會及時更改。也歡迎同樣初學Web-前端的你願意關注我的部落格,我會把我每週的學習內容進行整理和上傳,方便大家溝通和交流學習經驗。 由於是筆記

web前端面試知識點總結1

(1)button是行內元素還是塊級元素? 答:它是可變元素,既不屬於行內元素,也不屬於塊級元素。可變元素:根據上下文語境決定該元素為塊級還是內聯(可變元素如:button、iframe、map等)。 (2)行內元素有哪些?塊級元素有哪些?css盒子模型是什麼? 答:塊級

web前端進化之路——小程式開發

最近學習前端感覺很多知識學起來容易,但是很多知識點很容易忘記,想做一個工具來方便自己來學習,正好結合小程式,分享給大家。照顧初學者,可能講的比較細,理解哈。 準備工具 小程式一個 已申請(名稱是:we

web前端:Canvas 基礎

0.前言 最近忙裡偷閒,來寫寫文章。 ————-我是華麗的分割線————– 終於把這篇文章寫完了,關於本文,針對讀者主要是之前從未接觸過 Canvas的同學。當然,你要學 canvas 一定要有 JS 基礎啦。 其次就是,因為前前後後耽誤了兩天

萌新web前端從零開始1——計算機入門

    前言:這是一個萌新從零開始的學習之路,與大家分享自己的看法與見解,還請指出錯誤與遺漏點方便改正。     1.認識計算機。     計算機語言常見的有C,PHP,Ruby,Java,C#,Basic,JS,C++等,這裡我用到的是C#語言,用到的軟體是VisualStudio 2013版本。當用V

Web前端持續整合方案

一、引言     前端專案從開發到部署上線,中間通常要做一些額外的處理。比如程式碼壓縮、合併、css預編譯、巨集替換等。對於一個成熟的專案,這些通常都是通過指令碼自動完成的。本文結合專案實踐,介紹grunt在web前端持續整合中的應用。 二、專案工程化     1、開發一

web前端-CSS Border邊框-011

邊框樣式 邊框樣式屬性指定要顯示什麼樣的邊界。 border-style屬性用來定義邊框的樣式 border-style 值: 邊框寬度 您可以通過 border-width 屬性為邊框指定寬度。 為邊框指定寬度有兩種方法:可以指定長度值,比如

web前端-HTML知識體系初學者

1、web語義化和SEO web語義化是根據內容的結構化(內容語義化),選擇合適的標籤(程式碼語義化),便於開發者閱讀和寫出更優雅的程式碼,同時讓瀏覽器的爬蟲和機器更好地解析程式碼。 SEO是指在瞭解搜尋引擎自然排名的機制的基礎上,對網站進行內部及外部的調整優化,改進網站在

WEB前端學習 Day 2邊框

邊框是啥?上一次說到盒子模型裡面有border,這個邊框指的就是border, 比如說帶有弧度的,圓形的,帶有陰影的等。 那麼首先回顧一下盒子模型,盒子模型從裡到外分別是content,padding,border,margin。 分別是borde