OpenCV簡(jiǎn)單實(shí)現(xiàn)AR需用到的算法函數(shù)介紹
目前的AR需求(想要達(dá)到的目標(biāo))
公司目前的需求是要能夠指定一個(gè)物體開始追蹤,將一張預(yù)先準(zhǔn)備好的圖像覆蓋在被追蹤的物體上,
然后鏡頭偏轉(zhuǎn)縮放各類操作,再轉(zhuǎn)回來仍然可以識(shí)別到,并且同樣依舊覆蓋圖片到先前的位置上來。
有點(diǎn)類似Google Camera 里內(nèi)置的AR Stickers功能:

但是我們的需求不是在移動(dòng)終端上實(shí)現(xiàn),而是在PC上后置視頻,所以不能像手機(jī)那樣獲取到各類陀螺儀、加速度儀和指北針等Sensors進(jìn)行慣性定位式的追蹤。
所以這個(gè)需求只能考慮只能依靠圖像識(shí)別來實(shí)現(xiàn)之。
目標(biāo)追蹤算法
OpenCV內(nèi)置提供的追蹤算法有很多種,我大概把它分為三大類:
目標(biāo)追蹤算法、稠密(密集)光流算法、稀疏光流算法
每一類里面又有很多種算法。
1. Kalman(很古老的算法,卡爾曼濾波)
http://en.wikipedia.org/wiki/Kalman_filter
2. Meanshift(均值偏移算法)
https://en.wikipedia.org/wiki/Mean_shift
3. Camshift(是MeanShift算法的改進(jìn),稱為連續(xù)自適應(yīng)的MeanShift算法)
https://docs.opencv.org/4.6.0/d7/d00/tutorial_meanshift.html
4. Boosting(HAAR級(jí)聯(lián),相當(dāng)于AdaBoost的在線版本,抖動(dòng)很厲害,不建議使用)
5. MIL(比Boosting好,但是有遮擋不佳)
http://vision.ucsd.edu/~bbabenko/project_miltrack.shtml
6. KCF(比Boosting和MIL都要快,但是有遮擋時(shí)不佳)
http://www.robots.ox.ac.uk/~joao/publications/henriques_tpami2015.pdf
http://www.cvl.isy.liu.se/research/objrec/visualtracking/colvistrack/index.html
7. CSRT(速度比KCF慢一些,但是比KCF精確)
Lukezic_IJCV2018 Discriminative Correlation Filter
8. MedicamFlow(提供跟蹤評(píng)分機(jī)制,跳動(dòng)太快速可能會(huì)失效
http://www.aonsquared.co.uk/node/5
9. TLD(誤報(bào)多,需跟蹤、學(xué)習(xí)、檢測(cè),可解決遮擋問題,但不適合坐多行人下的跟蹤)
TLD (Tracking, learning and detection)
10. MOSSE(速度塊,準(zhǔn)確性較高,遮擋下效果也還能接受)
MOSSE (Minimum Output Sum of Squared)
11. GOTURN(基于深度學(xué)習(xí),處理遮擋效果不佳,需要提前訓(xùn)練好caffe模型文件)
http://davheld.github.io/GOTURN/GOTURN.pdf
https://github.com/davheld/GOTURN#train-the-tracker
https://github.com/Auron-X/GOTURN_Training_Toolkit
12. DaSiamRPN(基于深度學(xué)習(xí),需要提前訓(xùn)練好onnx模型文件)
跟GOTURN類似,就是模型文件格式支持的不同。
稠密(密集)光流算法
1. Farneback(Gunnar Farneback's algorithm)
2. Variational optical flow refinement
3. DIS(Dense Inverse Search (DIS) optical flow algorithm)
稀疏光流算法
1. SparsePyrLK(Lucas-Kanade optical flow algorithm)
小試牛刀
上一章節(jié)既然說是AR,那我就用OpenCV里面提供的AR模塊,來試試看能做到哪一步。
AR模塊叫ArUco模塊,它提供導(dǎo)出一些固定用于識(shí)別標(biāo)定(標(biāo)記)的函數(shù)。
cv::aruco::getPredefinedDictionary()
再使用cv::aruco::drawMarker()加入不同ID參數(shù)和想要生成圖片的特定寬高的形態(tài)各不相同的二維碼圖片。
如下圖所示:

我們將它用打印機(jī)打印出來,以便于在現(xiàn)實(shí)中鏡頭中識(shí)別。

將視頻載入到識(shí)別程序中來,然后調(diào)用cv::aruco::drawDetectedMarkers()函數(shù),它的作用就是內(nèi)置了一個(gè)將所有識(shí)別出來的aruco生成的標(biāo)定圖自動(dòng)畫個(gè)框,一般用于調(diào)試。
將會(huì)得到類似下圖這樣:

編號(hào)左上角為1,右上角為2,右下角為3,左下角為4。
既然準(zhǔn)確的將識(shí)別到的aruco標(biāo)定圖框出來了,那剩下來的當(dāng)然好辦了。
取一張要覆蓋的照片:

將識(shí)別到的上下左右四個(gè)標(biāo)定圖的四個(gè)角找到(圖1的左上角和圖2的右上角和圖3的右下角和圖4的左下角)
然后使用透視變換將圖片扭曲拉伸縮放透視變換到上一步四個(gè)角位置,
主要用到的函數(shù)有:cv::findHomography() cv::warpPerspective() cv::fillConvexPoly()
第一個(gè)函數(shù)cv::findHomography()是根據(jù)兩組離散的點(diǎn)計(jì)算出透視變換矩陣。
第二個(gè)函數(shù)cv::warpPerspective()是使用上一步計(jì)算出來的透視變換矩陣去將圖片矩陣變換成需要的樣子。
第三個(gè)函數(shù)cv::fillConvexPoly()用指定顏色(白色)顏色填充多邊形區(qū)域,是為了覆蓋透視變換后的圖片到原視頻幀上需要的掩碼圖所做的準(zhǔn)備的。
如下圖所示:

將上一步透視變換的圖片覆蓋到視頻幀上:

視頻效果:(未加入任何追蹤的版本)
改進(jìn)純aruco標(biāo)定識(shí)別
上面的演示效果視頻,如果您看了肯定會(huì)覺得在被遮擋的時(shí)候,效果會(huì)很差,因?yàn)樗膹垬?biāo)定圖如果缺了某一張就可能會(huì)亂飛。
所以我考慮了并實(shí)作了用稀疏光流法追蹤法去輔助上面的單純的標(biāo)定識(shí)別法,
在四張標(biāo)定圖有任意一個(gè)沒有識(shí)別到的情況下,就用稀疏光流追蹤法去預(yù)測(cè)當(dāng)前幀應(yīng)該的位置,
參考關(guān)鍵點(diǎn)就從視頻幀中的整張圖上去選。
要使用 稀疏光流追蹤主要就幾個(gè)步驟:
第一步:針對(duì)要追蹤的物體或者背景識(shí)別角點(diǎn)(關(guān)鍵點(diǎn)),關(guān)于這部分,我上一篇博客有介紹過角點(diǎn)檢測(cè)的11種算法。
第二步:將前后兩幀的統(tǒng)計(jì)出來的角點(diǎn)進(jìn)行對(duì)比(cv::calcOpticalFlowPyrLK()),得到兩幀的圖像中物體的變換矩陣。
第三步:用這個(gè)變換矩陣去影響aruco標(biāo)定法中未被識(shí)別到的矩陣點(diǎn)。
可以看下有加入稀疏光流追蹤的改良版本視頻效果:
結(jié)合物件追蹤算法
本來想法是既然物件追蹤算法OpenCV提供了12種,各有優(yōu)劣,覺得一定有一種是最適合自己場(chǎng)景的。
我就逐一嘗試了下各類內(nèi)置的物件追蹤算法,每一幀都來追蹤,比較一下各類追蹤算法追蹤效果:
實(shí)際上發(fā)現(xiàn)追蹤效果并不盡人意(視頻只顯示了4種算法,實(shí)際上我嘗試了8種追蹤算法,當(dāng)時(shí)的視頻沒保存)。
基本上都不會(huì)完全達(dá)到需求中所說的移出鏡頭視角范圍再移回來能持續(xù)被追蹤,甚至未移出鏡頭視角范圍內(nèi)有些追蹤算法都會(huì)跟丟。。。
這樣的話不但起不到輔助的作用,甚至還會(huì)帶偏原本稀疏光流法追蹤和aruco的結(jié)果。
稀疏光流法的騷操作
嘗試了很多追蹤算法,都覺得不盡人意,為什么不死磕在稀疏光流法上呢?
既然它這么好用,如果被追蹤的物體移出了鏡頭,想想為什么不在脫離鏡頭視角范圍之外的瞬間改成環(huán)境的光流追蹤,類似上一篇文章視頻防抖那樣,
然后一直將變換矩陣應(yīng)用到脫離視角前最后一幀時(shí)的位置開始持續(xù)應(yīng)用變換矩陣,使其在視角范圍之外也能持續(xù)追蹤,即使是在可見坐標(biāo)范圍外也一樣能work。
既然想到了就這么實(shí)現(xiàn)了:
下圖為追蹤鍵盤上的品牌logo,調(diào)焦距放大鏡頭,使其鍵盤logo脫離視角范圍外,再焦距回來,仍然可以接著原來的位置。

下圖為追蹤鍵盤上的Page Down按鍵

總結(jié)這種方法的缺點(diǎn):
1. 被追蹤的物體是允許移動(dòng)的,并且移動(dòng)在一定條件下也是可以持續(xù)被追蹤到的,
但是要注意到的是移動(dòng)的時(shí)必須在鏡頭視角范圍內(nèi)移動(dòng),如果是在背后視角外私底下動(dòng)就沒辦法了。
2. 如果被追蹤的物體移出鏡頭視角范圍太長(zhǎng)時(shí)間,視頻移動(dòng)太遠(yuǎn)距離,抖動(dòng)太劇烈,也會(huì)不準(zhǔn)確的。


浙公網(wǎng)安備 33010602011771號(hào)