擴增實境(Augmented Reality,簡稱AR):是一種實時地計算攝影機影像的位置及角度並加上相應影象、視訊、3D模型的技術,這種技術的目標是在螢幕上把虛擬世界套在現實世界並進行互動。
本文將讓你瞭解“如何通過 Web 技術實現一個簡單但有趣的 AR 效果”。
實現分析
正如文章開頭說道:AR 是將真實環境與虛擬物體實時地疊加到一個畫面。因此我們需要通過攝像頭實時獲取真實環境,並通過識別演算法識別與分析真實環境中特定的物體,然後結合得到的資料,將虛擬物體以某種方式結合到畫面中。
結合我們的案例,可得出以下步驟:
- 獲取視訊源
- 分析源,並識別出 Marker 位置
- 將虛擬物體疊加在 Marker 上
- 將最終畫面顯示在螢幕上
下面我們就根據以上步驟逐點分析。
技術分析
獲取視訊源
不依賴 Flash 或 Silverlight,我們使用 navigator.getUserMedia() API,該 API 允許 web 應用獲取使用者的攝像頭與麥克風流(stream)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<!-- 若不加 autoplay,則會停留在第一幀 --> <video autoplay></video> navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; var video = document.querySelector('video'); var constraints = { video: true } function successCallback(stream) { // 此處利用該 window.URL 物件的 createObjectURL 方法將 blob 轉為 url。 if (window.URL) { video.src = window.URL.createObjectURL(stream); // 用來建立 video 可以播放的 src } else { video.src = stream; } } function errorCallback(error) { console.log('navigator.getUserMedia error: ', error); } if (navigator.getUserMedia) { navigator.getUserMedia({video: true}, successCallback, errorCallback); } else { console.log('getUserMedia() is not supported in your browser') video.src = 'somevideo.webm'; // fallback. } |
上述 API 已不被推薦,建議使用新標準 API:navigator.mediaDevices.getUserMedia()。
1 2 3 4 5 |
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) { /* use the stream */ }).catch(function(err) { /* handle the error */ }); |
另外,可通過 constraints 引數設定以下選項:
- 啟用 video、audio 二者其一或兩者同時啟用
- 匹配攝像頭解析度(若裝置擁有不止一個攝像頭)
- 選擇前後攝像頭
navigator.getUserMedia() 相容性問題
目前 IOS 裝置的微信和 Safari 均不支援,較新的安卓和桌面端瀏覽器均支援。
另外,出於安全問題考慮,Chrome 只支援 HTTPS 頁面啟用攝像頭。因此,我們可以用 Firefox,或者藉助一些線上編輯器,如 jsbin、jsFiddle 等進行開發測試。
識別
得到視訊源後,我們需要對影象中的物體(本案例是 Marker)進行實時識別。下面提供兩個可實現識別的庫:
正如其名,它們是 aruco 和 artoolkit 的 JavaScript 版本。本文僅對第一個庫進行介紹。
OpenCV(Open Source Computer Vision Library):是一個跨平臺的計算機視覺庫。它可用於開發實時的影象處理、計算機視覺以及模式識別程式。
jsaruco 能識別視訊每幀畫面中的 Marker 位置(含 4 個角座標)。獲取座標後,我們就能將虛擬物體放在真實環境的適當位置了。關於 jsaruco 的介紹和用法,可到 這裡 檢視。
結合真實環境和虛擬物體
對影象的處理,Canvas(WebGL) 無疑是目前 Web 的最佳選擇。
虛擬物件若是 2D 的,則直接利用 Canvas 2D API 在相應座標上進行繪製。若虛擬物件是 3D 的,則可使用 Three.js 或 A-Frame 等 3D 庫(當然,你也可以直接用 WebGL)。
如果你對 Three.js 還不瞭解,可以看看 《Three.js入門指南》。
Marker 分析
每個識別庫都有其自身的實現方式。因此,一些 Marker 可能只適用於某個庫。對於 jsaruco
,它對 Marker 的要求如下:
一個 7×7 的正方形,其外層是“不用”的黑邊。內部 5×5 單元格則組成了 ID 資訊。其中,每行需要遵循以下模式:
white - black - black - black - black
white - black - white - white - white
black - white - black - black - white
black - white - white - white - black
因此,根據上述資訊,我們可以得出該庫最多可識別 1024(4的5次方) 個 Marker。也就是說:每個 Marker 對應唯一一個 ID,然後我們可以利用 ID 指定顯示的虛擬物件。
一個合格的 Marker 應該是這樣子:
可通過這個 連結,獲取 jsaruco 的更多 Marker。
當然,更先進的影象識別庫不僅能識別 Marker,也可以識別你指定的圖片,甚至是自然特徵跟蹤( Natural Feature Tracking)和 SLAM(Simultaneous Localization and Mapping,即時定位與地圖構建)。
自然特徵跟蹤
SLAM
實現案例
建議使用帶有攝像頭的電腦體驗以下案例(注意不要被自己的頭像驚豔到~)。
另外,由於以下案例均未要求特定 ID 的 Marker,因此你可以選擇以下 Marker(拍照或列印),或者在 這裡 挑選一個進行體驗。
Marker
想體驗以下案例,需要先對某一個 Marker 拍下或列印,然後將其展示在攝像頭前。
另外,為了保持文章的簡潔,在此就不直接展示以下案例的實現程式碼。若需要,則直接檢視案例原始碼。
再次提醒:以下案例均在電腦上進行開發測試,未針對移動端裝置進行優化測試。
除了第一個案例,其餘均以動畫的方式展示虛擬元素。
顯示 2D 圖
當你展示團隊 Logo 時,連結>>。
顯示心跳
當你看到“男神/女神”時,連結>>。
顯示卡片
當需要展示某個人的身份資訊時,連結>>。
顯示 3D 地球
當展示我們的地球母親時,連結>>。
顯示 3D 商品。
當展示我們的商品時,連結>>。
最後
由於筆者才疏學淺,實現的案例未必完全符合 AR 的要求。但希望通過本文,讓大家能對 Web AR 有一定的瞭解。