從前端工程師到高級AR工程師
本文將簡單講述圖像追踪的原理和如何用JS+WebRTC實現帶追踪的AR。
WebRTC AR追踪http://v.youku.com/v_show/id_XMzExNzY1MjA4MA==.html
https://www.zhihu.com/video/907715533284200448
上一篇文章講瞭如何在Web端實現圖像識別,但我們認知中的AR通常還包括追踪技術,也就是把虛擬的模型定位到現實場景中。在演示視頻中,繪製全部採用2D Canvas API ,先繪製WebRCT得到的背景,然後計算出Marker的變化矩陣,接下來把動畫繪製到Canvas上。偽代碼如下
//繪製相機視頻ctx.drawImage(bg,0,0);ctx.save();let[a,c,e,b,d,f]=posMatrix;ctx.transform(a,b,c,d,e,f);//繪製動畫視頻ctx.drawImage(mv,0,0,mv.videoWidth,mv.videoHeight,0,0,markerWidth,markerHeight);ctx.restore();
要實現定位主要有以下步驟:特徵點提取->特徵點匹配-> 計算變化矩陣
圖片特徵點提取:
有些長得好看的人,無論穿什麼馬甲,總能在人群中一眼被認出來(長得難看的人也會被一眼扔出去)
圖片也是這樣的,有些點特別明顯,無論怎麼變化(旋轉,縮放),總是能被穩定地找出來

以上gif是計算圖片的特徵點,每次旋轉圖片,計算新的特徵點(紅色),有些特徵點不受旋轉影響,總是能被找到。越複雜的算法,找出的特徵點越穩定。
找出一張圖片的特徵點之後,算法會給每個特徵點計算一個類似“ID”的值,ID和特徵點是一一對應的,可以通過ID來判斷特徵點,在兩張圖片中,我們把ID最相近的兩個點匹配在一起,當成同一個特徵點。

當然如果兩個ID相差很遠,那麼也不能把這兩個點當成同一個特徵點,而是拋棄這兩個特徵點。
如果圖片只發生移動而沒有縮放旋轉,特徵點A,在圖一的位置是(x1,y1)而在圖二的位置變成了(x2,y2),我們就可以計算出圖一到圖二的圖像變化(x2-x1,y2-y1)。上圖中明顯還發生了旋轉,和縮放。所以需要多個特徵點進行計算,計算出來的結果可以是三維矩陣或者四維矩陣。
在AR追踪時,預先計算好Marker的特徵點和特徵點ID,對於攝像機每一幀的照片,計算出每張照片的所有特徵點,通過特徵點ID匹配,找到Marker在照片的位置,並且在這個位置上繪製圖形或者模型。
這些圖片匹配的算法都很經典,從opencv裡面信手拈來,有人把opencv裡面一部分算法寫成了js版本(最簡單的那一部分-.-),使用JS也能進行圖像追踪, JSFeat這個庫好幾年前就寫了,不過可能那幾年AR還沒有進入大眾視野。使用這個庫可以完成以上說的尋找特徵點,特徵點匹配和計算變化矩陣,具體可以參考Demo的代碼
一般來說,越穩定的識別算法,對性能要求越高。
- 首先每張圖要從幾百萬的像素裡反復計算,找出幾百個特徵點
- 這幾百個特徵點又要計算ID並且和另一張圖的幾百個特徵點進行距離計算
- 當匹配了兩張圖的特徵點之後,這些特徵點還要擬合出誤差最小的變化矩陣
在這幾步下,JS的計算能力捉襟見肘,輕輕鬆松跌破30幀。純JS無法完成的情況下,要么借助Native計算,要么使用WebAssembly,這兩個都不是很容易...
視頻中展示的demo是在iOS11下用iPhone7運行480*640分辨率的效果,明顯看出有丟幀的情況,主要原因還是特徵點識別不穩定,需要更穩定的算法和更強的計算力支撐。
再提供一個SIFT的算法介紹,供大家深度學習。也歡迎大家留言討論圖像算法,如何在Web環境運行複雜的圖像算法。更歡迎各位耐心看到這裡的工程師們點個贊!