HandAI開源項目,拉近人和攝影的距離:基於手勢識別完成不同的拍攝行爲

在12月初,我誕生了這個想法。現在的拍攝效果的轉換都是人和機器通過物理接觸完成,包括開始拍攝,各種拍攝效果等,幾乎都是通過手指來完成。人類具有豐富的表達自我的能力,手勢是表達自我的手段之一。無論是哪個地域的文化,一些手勢都有其含義。在深度學習時代,我們完全可以用手勢代替手指,告訴機器我們想做什麼樣的事情,想調換什麼拍攝模式,因此HandAI誕生了。固然手指在更多的場合還是很方便,但我做這個事情,不想去探討手勢控制的價值以及實用性,我只是單純想做這個事情。

效果展示視頻
友情提示:後半段視頻聲音略大,請調小音量。
項目地址 隨手賞個star吧((╹▽╹))。

項目功能

HandAI能識別出8種手勢。這八種手勢是亞洲地區常用的手勢,其意義都是積極或中性的,沒有貶義手勢。
Note: 如果gif圖像沒法顯示(有些圖像較大),可以去github上下載項目,在pictures文件夾中查看。

  • one:背景虛化,實現景深效果,前景人物不虛化
    在這裏插入圖片描述
  • two:背景變化
  • three:背景調成黑白模式,前景人物依然有色彩。
    在這裏插入圖片描述
  • four:人臉貼紙
    在這裏插入圖片描述
  • five:畫面橫向複製擴展
    在這裏插入圖片描述
  • good:視頻背景轉換模式,當右上角出現紅點之後,使用yeah手勢(two),即可把背景換成視頻數據,而不是單純的圖像。
    在這裏插入圖片描述
  • eight:華麗防擋彈幕模式。
    在這裏插入圖片描述
  • ok:結束錄製
    在這裏插入圖片描述

項目設計思路

項目包括三個深度學習模型,分別是手部關鍵點檢測以及識別(算統一的一個模型), 人像精細分割模型,人臉即五個關鍵點檢測。

  • 手部關鍵點檢測以及識別:對每一幀都要運行該模型,用來判斷手勢的含義(8個類別之一)。
  • 人像分割模型:也是每一幀都要運行,獲得前景人物的掩碼。用於做背景變化,背景虛化,背景黑白,防擋彈幕。
  • 人臉及五個關鍵點檢測:用於做人臉貼紙。

下面具體講解,首先看整個項目的結構圖,非常簡單。
在這裏插入圖片描述
我使用了一個flags.py文件設置各種手勢的當前狀態。這些狀態會保留並施加到下一幀上,所以每個手勢都不是獨立作用的。正如視頻中描述,這些手勢對應的效果能一起作用在同一幀上。

手勢識別

在2019年8月,谷歌發佈了一個能檢測手部關鍵點的開源apk,當時很多公衆號對其進行了報道。在他們開放的視頻中,該開源模型可以檢測手部21個關鍵點並且識別手勢。但是遺憾的是,在開源的代碼中,並沒有識別手勢的部分,僅僅有關鍵點檢測。但是在谷歌發佈的博客中,提到了他們識別手勢的方法是,判斷手部關節點的彎曲程度以及關係。在HandAI中,我使用了他們開源的網絡檢測手部關鍵點,根據他們的描述,復現了8種手勢的識別。

  • 如果判斷手部彎曲程度: 計算指關節到指尖的向量,計算指關節到手掌底部的向量,再計算兩個向量的餘弦距離。根據餘弦距離判斷手指的彎曲程度。再把每個手指的狀態(彎曲,伸直)映射到一組預定義的手勢上即可。不需要在訓練一個分類網絡。

背景的虛化,變化,黑白效果

關於背景的虛化,變化,以及黑白效果。本質上就是得到了人像的mask,然後把mask遷移到另一張圖像上罷了。不多介紹。

人臉貼紙的實現思路:

首先貼紙肯定要往臉上貼,所以需要一個人臉檢測網絡。還需要確保貼紙能貼到臉上的合理區域,比如貓耳朵不能把人眼睛覆蓋了是吧。所以需要關鍵點檢測。越是需要貼的準,貼的多樣,就越需要檢測多個關鍵點,一般98個關鍵點是很合適的,因爲關鍵點還覆蓋了頭部,可以貼帽子。當然68個點也可以,只是需要根據面部比例算出頭部的位置。
在我的項目中,我簡化了操作。首先我在網上找到了這樣的素材
在這裏插入圖片描述
這個貓臉貼紙圖包含了足夠多的部分,所以我沒有必要定位每個需要貼紙的位置,貼上合適的貼紙。我只要找到人臉鼻子的位置,和貓鼻子對應。然後計算合適的比例,對貓臉素材縮放,然後把素材的mask找到,算出相對座標,直接覆蓋在人臉上就ok了。
詳細說下計算比例的問題。我使用centerFace檢測人臉。centerFace還能輸出人臉的眼部中心,鼻子,兩個嘴角這五個位置的關鍵點。通過計算人臉鼻子到嘴角(左或者右)的距離,和貓臉素材的鼻子中心到嘴角(估計一下大概位置)的距離,這兩個距離的比值,就是貓臉素材應該縮放的尺度。
然後在貓臉素材上求得所有像素點相對於鼻子中心的相對座標,加上人臉鼻子的座標,就是貓臉素材應該在人臉圖像座標上的具體位置。
f1(x,y)=(xnose,ynose)+frelative(x,y)f_1(x,y) = (x_{nose}, y_{nose}) + f_{relative}(x,y)
frelative(x,y)=(x,y)(xcat_nose,ycat_nose)f_{relative} (x,y)= (x,y) - (x_{cat\_nose}, y_{cat\_nose})
其中,x,yx,y是貓臉素材在貓臉圖像座標系下的座標。通過函數f1f_1,將座標變換到人臉座標系下。

畫面擴展

如果檢測到了5這個手勢,flags將會設置對應的狀態。首先會記錄手掌中心的位置pospos。然後後續幀在移動5的過程中,計算當前幀手掌中心和pospos在x軸的距離,按照合理的比例求出當前畫面有多寬的位置應該被擴展。包括畫面的擴展,以及收回擴展畫面,都是這樣做的。

防擋彈幕

防擋彈幕,其中防擋的效果自然是用人像精細分割得到的mask來實現的,不多說。至於這個彈幕效果如何生成。哈哈。將每一條彈幕視作一個對象,加入到隊列中。首先沒有一個彈幕被髮出,所有的彈幕都在一個隊列中。每一幀都有彈幕發出,發出的彈幕出列,並進入另一個隊列中。所以有兩個隊列,其中一個隊列用來保存沒有發出的彈幕,另一個隊列用來保存發出的隊列。對每一幀,都遍歷保存發出的隊列,彈幕這個對象中保存了彈幕應該出現的位置,然後draw出來,再把位置更新一下,就是x軸減去一個合理的數值,數值是和fps有關的。

項目例子

推薦先運行webCamera_demo.py看看效果。需要pytorch-GPU, tensorflow2.0等庫。在我的電腦,cpu是intel i5-8300, GPU GTX1060(6GB)上,處理速度是5fps。
同時我還提供了每個模型使用的例子,可以去example文件夾查看。

致謝

本項目受很多開源項目支撐。其中有谷歌的mediapipe,centerFace,PortraitNet。
mediapipe
centerFace
PortraitNet
谷歌手勢識別
hand tracking
感謝這些開源項目,今後我也將會秉持開源精神,促進知識傳播,共享技術,共同進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章