摘要:本篇從理論到實踐分享了基於PoseNet算法的人體姿勢相似度識別項目。首先介紹了項目背景,因為部門搞活動需要大家去模仿誇張搞笑的表情和姿勢來提升活動的可玩性,所以需要利用CV算法對圖片進行相似度打分;然後詳細講解了人體姿勢相似度識別算法,主要包括基於PoseNet算法來識別姿勢和計算姿勢相似度兩個流程;最後基於已有的開源項目進行二次開發實現了人體姿勢相似度識別項目。對於以前從未接觸過CV項目的我來說既是挑戰也是契機。因為之前主要做NLP相關的項目,而實際業務場景中經常會有NLP和CV交叉相關的項目,所以就需要對CV也有一定的了解。通過這個項目相當於慢慢入了CV的門,最終的目標是不變的,將更多更好的機器學習算法落地到實際業務產生更多的價值。
下面主要按照如下思維導圖進行學習分享:
01項目背景介紹
1.1 為啥要做人體姿勢相似度識別
還是慣例講下為啥要學習人體姿勢相似度識別的背景,一方面讓大家了解下我做這件事的原因,另一方面對於想借鑑該項目的小夥伴會有所幫助。因為年底了部門想搞一個活動,就是提前準備一些誇張搞笑的表情和姿勢,然後大家來進行模仿,根據模仿的相似度來打分,分數越高對應的禮物越好,主要作用是增加活動的可玩性,帶動更多的小夥伴參與進來。下面是表情和姿勢的模仿效果圖:
圖1 誇張搞笑表情和姿勢的效果圖
因為表情和姿勢的識別其實是兩個模型,我主要負責姿勢相似度識別,所以本文主要講下如何識別姿勢的相似度。關於表情的相似度打分後面研究下再分享出來。
1.2 學點CV知識是為了在NLP走的更遠
上面講了下為啥要做人體姿勢相似度識別的業務背景。因為我其實之前主要是做NLP相關的工作,CV這塊接觸的實在很少。但是因為我們今年會做一些廣告文案自動生成相關的業務,就是根據一定的生成條件比如標籤分類來自動生成廣告文案。比如現在要創建一個傳奇遊戲標籤類型的廣告,我們會將傳奇遊戲標籤作為條件來自動生成一批廣告文案提供給廣告主選擇,這樣廣告主就不需要自己寫文案了,直接從文案庫裡選一條用就行了。有條件廣告文案生成模型的好處在於一方面可以節約廣告主撰寫廣告文案的成本,另一方面可以提昇平臺的服務水平,吸引更多的廣告主來我們平臺投放廣告。因為廣告文案生成模型可能會涉及到將廣告素材圖片也作為生成條件,屬於NLP領域和CV領域的交叉,所以需要學習和儲備一點CV知識,後面可以更好的去完成將廣告素材圖片也作為條件去生成廣告文案。整體來說就是「學點CV知識是為了在NLP走的更遠」。
02 人體姿勢相似度識別算法詳解
2.1 項目目標和效果圖
人體姿勢相似度識別項目的目標其實非常簡單,就是輸入兩張人體姿勢的圖片,輸出姿勢相似度的得分。經過調研,發現TensorFlow開源的PoseNet模型可以很好的滿足我們的需求。下面是我們項目完成之後的效果圖:
圖2 瑜伽姿勢相似度識別:標準姿勢和不標準姿勢
我們提供一張標準的瑜伽姿勢圖,也就是上圖中藍色衣服的圖片。然後分別提供一張模仿的比較像(灰色衣服)和不像的(白色衣服)兩張圖片進行對比,灰色衣服是模仿的比較像的,所以相似度得分比較高在0.95以上,而白色衣服是模仿的不像的,所以相似度得分比較低僅在0.7左右。這就是項目目標和效果圖說明。
2.2 項目整體流程
項目整體流程分成兩步,第一步是基於Tensorflow的PoseNet模型識別出人體姿勢,第二步就是計算兩個人體姿勢的相似度得分。下面會對兩個步驟進行詳細說明。
2.3 基於PoseNet算法識別人體姿勢
2.3.1 算法原理
基於PoseNet算法識別人體姿勢通俗的理解就是輸入一張圖片,模型會返回圖片中人的姿勢。這裡姿勢主要包括17個關鍵點。需要說明的是因為模型主要目標是識別圖片中人的姿勢,也就是人身體的關鍵位置點,所以並不會關注圖中的人是誰,也就是說不會進行人臉識別(好處在於可以保護人的隱私)。PoseNet算法會識別出人的姿態,具體如何刻畫這個姿態主要是通過人的17個關鍵部位,每個部位會得到一個檢測結果的信任值,信任值範圍在0-1之間,1代表檢測結果的信任值是最高的。下面是PoseNet算法可以檢測的17個關鍵點圖:
圖3 PoseNet算法可以檢測的17個關鍵點
只要你的電腦上安裝了攝像頭就可體驗Tensorflow官方提供的PoseNet算法,下面是PoseNet算法的demo,有興趣的小夥伴可以感受下,支持單目標姿勢和多目標姿勢,下面是體驗demo的連結和體驗效果圖:
https://storage.googleapis.com/tfjs-models/demos/posenet/camera.html
圖4 PoseNet算法同時支持單人和多人姿勢識別
2.3.2 人體姿勢識別流程
人體姿勢識別流程整體分成兩步,第一步是將圖片作為特徵輸入到CNN卷積神經網絡中;第二步就是利用單姿勢或多姿勢解碼算法輸出姿勢、姿勢置信度得分、關鍵點位置以及關鍵點置信度得分。下面是PoseNet模型的姿勢檢測流程:
圖5 PoseNet模型的姿勢檢測流程
姿勢、姿勢置信度得分、關鍵點位置以及關鍵點置信度得分是PoseNet刻畫人體姿勢的重點,下面通過一張示例圖進行詳細說明:
圖6 PoseNet如何刻畫人體姿勢
PoseNet模型可以說是從高低兩個層次來刻畫人體姿勢,具體是先識別出人體的17個關鍵點,然後根據所有關鍵點來刻畫人的整體姿勢。先來看看高層次的抽象姿勢以及姿勢置信度得分。上圖中左邊部分PoseNet算法識別出兩個人,其中person1的姿勢置信度得分為0.8,person2的姿勢置信度得分為0.7。姿勢是PoseNet算法返回的最高層次的目標,刻畫的是某個人整體的情況,姿勢的置信度得分越高,說明模型越有把握識別當前這個人的姿勢,那麼對應的可靠性就會越好。而具體模型是如何認為識別的把握越高則主要通過這個人對應的17個關鍵位置點的置信度情況。可以這麼簡單的理解,如果一個人對應的17個關鍵點越清晰,模型就認為這個人整體的姿勢越清晰。從上圖中也可以發現person1相比於person2來說關鍵點位置會更加豐富,所以對應的置信度得分也會越高;
然後再看看關鍵點位置以及各個關鍵點的置信度得分。上圖中右邊部分顯示了person1的兩個關鍵點位置以及對應的關鍵點置信度得分。關鍵點位置主要通過二維坐標來顯示,分別顯示了左肘(left elbow)和右肩(right shoulder)。其中左肘的置信度得分是0.9,說明模型認為是左肘的可信度很高,而右肩的置信度得分是0.6,模型認為是右肩的可信度則沒那麼高了。
2.3.3 模型輸入
模型輸入主要包括以下四部分:
輸入圖像:輸入圖像是指需要檢測的圖片;
圖像比例因子:圖像比例因子主要用於控制圖片縮放的比例,範圍是0.2-1,默認值為0.5。當通過網絡傳輸圖片時會根據實際業務需求對需要檢測的圖片進行縮放。如果線上實時要求較高可以對圖片進行更高比例的縮小,那麼網絡的傳輸速度就會更快,但是模型識別的準確率可能會有所下降。其實質是調節線上識別速度和模型效果準確率;
水平翻轉:水平翻轉主要是控制對檢測的圖片是否進行水平翻轉,默認是false;
輸出步幅:輸出步幅會影響神經網絡中層的高度和寬度。輸出步幅越低,模型的準確率就會越高,但是相對的線上識別速度就會越慢。通俗的理解其實有點像圖片的解析度問題,步幅越低,圖片的解析度就越高,解析度越高可以認為是圖片更高清了,那麼模型的識別準確度就會越高,對應的模型的識別速度就降低了。下面是同樣一張照片使用不同步幅對模型準確率和識別速度的對比圖:
圖7 不同輸出步幅對模型準確率和識別速度的對比
2.3.4 模型輸出
模型輸出主要包括兩大塊,第一塊是代表整體的姿勢以及姿勢的置信度得分,第二塊則是代表部分的每個姿勢的17個關鍵點位置以及對應的關鍵點置信度得分。下面是一個輸出示例圖:
圖8 PoseNet模型輸出示例
通過上圖輸出示例可以看出這個姿勢的整體置信度 為0.6694,這個姿勢包含17個關鍵點,每個關鍵點會有對應的名稱、二維坐標位置以及關鍵點對應的置信度得分。比如第一個關鍵點是鼻子(nose),對應的置信度得分是0.8434,並且還會返回鼻子對應的二維坐標。
2.4 計算姿勢相似度
上面是通過PoseNet模型如何得到人體姿勢以及姿勢包含的17個關鍵點流程。通過整體的姿勢和局部的17個關鍵點我們就能很好的刻畫人體的姿勢。通過PoseNet算法我們可以分別拿到兩張圖片中人的姿勢數據,接下來就是如何計算兩個姿勢的相似度問題。下面通過一個實際的例子進行說明。
第一步先拿到兩張圖片對應的姿勢pose1和pose2:
圖9 兩張圖片返回的人的姿勢數據
需要說明的是基於PoseNet算法對於圖片中的每個人會返回17個關鍵點,這裡為了簡單說明僅選用其中三個關鍵點;
第二步將姿勢數據打平,得到每個姿勢的坐標以及置信度得分:
圖10 將姿勢數據打平
因為有三個關鍵點,每個關鍵點包含二維坐標和置信度得分,將坐標位置向量打平就得到了6維向量vectorPose1XY,而置信度得分向量vectorPose1Scores是4維,其中前三維是三個關鍵點對應的置信度得分,最後一維是關鍵點打分的總和,比如2.5=0.9+0.9+0.7;
第三步進行標準化操作:
圖11 標準化操作
標準化操作分成兩階段,第一階段會分別對每個關鍵點的橫坐標X和縱坐標Y進行如下操作,比如第一個姿勢的第一個關鍵點對應的橫坐標x1變成了(x1-x_min)/xy_max;第二個階段則會進行L2規範化操作;
最後一步就是根據得到的向量計算兩張圖片中姿勢的相似度得分,主要是利用餘弦相似度公式計算,姿勢越相似,那麼得分越高,最高分為1。
03 項目實戰
3.1 借鑑開源項目
因為這個人體姿勢相似度識別項目主要是用於部門活動,需要在不影響當前工作的前提下利用業餘時間完成,並且時間非常緊。一句話形容就是不僅不能佔用正常的工作時間,而且還需要快速搞出來,所以最有效的方法就是看看有沒有類似的開源項目進行二次開發。經過調研主要基於以下兩個開源項目完成:
開源項目1:https://github.com/tensorflow/tfjs-models/tree/master/posenet
開源項目2:https://github.com/freshsomebody/posenet-similarity
先介紹下這兩個開源項目。開源項目1就是TensorFlow的PoseNet模型,通過這個模型蘇輸入一張圖片就會返回圖片中人的姿勢、姿勢置信度得分、關鍵點位置以及關鍵點置信度得分;開源項目2是基於開源項目1開發的,先基於PoseNet算法得到兩張圖片人的姿勢,然後提供了三種計算相似度的算法策略就可以返回姿勢的相似度得分,這三種相似度算法策略分別是weightedDistance、cosineDistance、cosineSimilarity。實際項目中我主要使用的是cosineSimilarity餘弦相似度策略。整體來說非常簡單,通過TensorFlow.js的方式傳入兩張圖片的地址就會返回相似度得分,開源項目2提供的源碼如下:
圖12 開源項目posenet-similarity對應的源碼
3.2 開源項目存在的問題及解決策略
上述源碼存在兩個重要的問題,經過一番折騰,下面是解決的策略:
最後代碼開源到我的github上了,有興趣的小夥伴可以下下來玩玩:
https://github.com/wilsonlsm006/posenet-similarity
總結及反思
本篇從理論到實踐分享了基於PoseNet算法的人體姿勢相似度識別項目。首先介紹了項目背景,因為部門搞活動需要大家去模仿誇張搞笑的表情和姿勢來提升活動的可玩性,所以需要利用CV算法對圖片進行相似度打分;然後詳細講解了人體姿勢相似度識別算法,主要包括基於PoseNet算法來識別姿勢和計算姿勢相似度兩個流程;最後基於已有的開源項目進行二次開發實現了人體姿勢相似度識別項目。對於以前從未接觸過CV項目的我來說既是挑戰也是契機。因為之前主要做NLP相關的項目,而實際業務場景中經常會有NLP和CV交叉相關的項目,所以就需要對CV也有一定的了解。通過這個項目相當於慢慢入了CV的門,最終的目標是不變的,將更多更好的機器學習算法落地到實際業務產生更多的價值。
參考資料
[1] https://github.com/tensorflow/tfjs-models/tree/master/posenet
[2] https://github.com/freshsomebody/posenet-similarity
[3] https://www.tensorflow.org/lite/models/pose_estimation/overview
[4]https://medium.com/tensorflow/real-time-human-pose-estimation-in-the-browser-with-tensorflow-js-7dd0bc881cd5
最新最全的文章請關注我的微信公眾號或者知乎專欄:數據拾光者。