? ? ?游戲開始后,隨著音樂會給出不同的動作提示,用戶按照提示擺出正確動作即可得分。援引官方說法,“尬舞機”主要應用了今日頭條 AI Lab 自主開發的“人體關鍵點檢測技術”,依靠這項技術,抖音能夠檢測到圖像中所包含人體的各個關鍵點的位置,從而實現從用戶姿態到目標姿態的準確匹配。
? ? 以上這些體感游戲,都牽涉到計算機視覺中的一個細分領域:?人體姿態估計(pose estimation)?,即識別圖像中的人體關鍵點(人體上有一定自由度的關節,如頭、頸、肩、肘、腕、腰、膝、踝等)并正確的聯系起來,通過對人體關鍵點在三維空間相對位置的計算,來估計人體當前的姿態。
? ? ?人體姿態估計有不少難點,比如:如何從圖片中區分出人和背景;如何定位人體的關鍵點;如何根據二維的關鍵點坐標計算出三維中的姿態;如何處理四肢交叉或遮擋的情況;如何定位多人;如何提升計算速度等等。而相關技術在游戲、安防、人機交互、行為分析等方面都有應用前景。因此,這是計算機視覺甚至人工智能領域中極具挑戰的一個課題。(小聲說句,我的碩士畢業論文就是這個方向)
? ? 不過,因為前人的貢獻,現在你只需通過少量的 Python 代碼,也可以實現從照片或視頻中進行人體姿態估計。這都要仰賴于 CMU 的開源項目:?Openpose?。
OpenPose 是基于卷積神經網絡和監督學習并以 caffe 為框架寫成的開源庫,可以實現人的面部表情、軀干和四肢甚至手指的跟蹤,適用多人且具有較好的魯棒性。是世界上第一個基于深度學習的實時多人二維姿態估計,為機器理解人類提供了一個高質量的信息維度。
其理論基礎來自《Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields》,是 CVPR 2017 的一篇論文,作者是來自 CMU 感知計算實驗室的曹哲、Tomas Simon、Shih-En Wei、Yaser Sheikh。
項目地址:?https://github.com/ZheC/Realtime_Multi-Person_Pose_Estimation
(摘自網絡)
論文演示效果:
? ? ?此方法可以達到對視頻流的實時多人檢測。要知道,Kinect 可是加了一個額外的紅外深度攝像頭才做到如此準確地識別(還不能是這么多人)。
詳細的原理,我在這里就不冒充大牛強行解釋了。但通俗地說幾點,為什么 Openpose 有如此突破性地效果:
- 以往的識別思路是自上而下:先找人,找到人了再進一步區分身體不同部分。Openpose 則是自下而上:?先找手腳關節等特征部位,再組合人體?;
- Openpose 團隊將?人臉識別?、?手部識別?的已有成果整合到了姿態識別中,取得了更好的效果;
- 有了?大數據?的支持,這是過去的研究所沒有的。看看這個 CMU 為采集人體數據所搭建的設備,你就會有所體會:
? ? ?之前的文章?Python+OpenCV 十幾行代碼模仿世界名畫?中,我們提到 OpenCV-Python 在 3.3 版本中加入了?深度神經網絡(DNN)?的支持。同樣在項目 Samples 中,提供 Openpose 的一個 Python 簡單實現版本。(只支持圖像中有單個人)
官方代碼:
https://github.com/opencv/opencv/blob/master/samples/dnn/openpose.py
使用方法,命令行進入代碼所在目錄執行:
python openpose.py --model pose.caffemodel --proto pose.prototxt --dataset MPI
--model
?參數和?--proto
?參數分別是預先訓練好的人體姿態模型和配置文件。因為模型文件很大,并不包括在 OpenCV 代碼庫中,可以在 Openpose 項目(https://github.com/CMU-Perceptual-Computing-Lab/openpose?)找到下載地址。
另外可以通過?--input
?參數指定識別的圖片或視頻地址,默認則使用攝像頭實時采集。
執行后效果:
?核心代碼:
? ? 和之前 fast-neural-style 的代碼類似,大部分的工作都是 Openpose 做好的,OpenCV 這里只是使用訓練好的神經網絡進行計算。所以核心代碼其實沒有幾行,而且跟上次的例子幾乎一致。剩下一半的代碼都是在把獲取到的關鍵點坐標繪制成人體的骨架結構。
? ? 這里順帶提醒一下,我發現代碼中的一個斷言?assert(len(BODY_PARTS) == out.shape[1])
?無法滿足,會導致程序終止。如果出現這樣的問題,就把這句注釋掉,并不會對結果有影響。拿到人體關鍵點數據后,我們就可以做進一步的判斷。比如我們加一個很簡單的判斷:
? 如果左手腕和右手腕的高度都超過脖子的高度,就認為是一個抬手的動作,在屏幕上輸出“?HANDS UP!?”。注意在 OpenCV 坐標系里,圖像的坐標原點是左上角。 效果:
? ? ?如此,一個簡單的動作識別程序就有了。雖然很粗糙,但已經可以附加在很多應用上,比如:商場、科技館里的互動游戲、交互式的視覺藝術作品等等。感興趣的同學不妨親自試一試,期待看到你們借此做出更有意思的項目。