論文閱讀筆記 — 人體姿態辨識 OpenPose

Hung-Chih Chiu
13 min readMay 28, 2020

--

經過了Pose Machines與Convolutional Pose Machines(CPM)的介紹, 終於要進入我們的重點OpenPose, 一樣先讓大家參考一下Youtube上面有關OpenPose影片

https://www.youtube.com/watch?v=pW6nZXeWlGM&t=7s

OpenPose有多熱門? 可以看到先前Jetson NANO在發佈上直接把OpenPose列為支援的模型, 與ResNet, Inception, VGG, Yolo等著名的模型放在一起, 就可以知道OpenPose受歡迎的程度了.

圖1 Jetson NANO介紹支援的模型

如果上網尋找OpenPose等相關論文, 可以找到兩篇, 分別是2017年的Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields (https://arxiv.org/pdf/1611.08050.pdf)以及2018年底的 OpenPose: Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields (https://arxiv.org/pdf/1812.08008.pdf). 這兩篇的作者都是相同, 主要的差異在2018年年底的這篇改進了模型架構, 透過疊加多層較小的convolution filter, 達到同樣的receptive field, 增加了非線性度, 又能夠有效縮減參數量, 除此之外, Intel後來有發表一篇同樣以Real-time 2D Multi-Person Pose Estimation on CPU: Lightweight OpenPose (https://arxiv.org/pdf/1811.12004.pdf)為標題的paper, 從題目就可以知道它對OpenPose做了輕量化的動作, 不過因為不是同一作者, 我們放到下次再做介紹, 今天將針對同作者的兩篇差異進行說明.

不論是哪個模型, OpenPose的基本流程都如圖2所示, 將原始RGB影像輸入模型後, 模型會如同CPM, CPM介紹如前面文章:

OpenPose透過CNN的架構去找每個關節位置的Confidence Map (圖2 b)以及OpenPose新定義出來的Part Affinity Fields (PAF) (圖2 c), 模型在整合上述兩種特徵之後, 就可進一步針對每個肢段進行預測. 這樣的描述感覺和CPM沒有太大的差異, 但是CPM主要是在影像中只有單人的環境下對肢體進行預測, OpenPose在多人與背景雜亂的環境下仍可維持一定的人體關節與肢段預測的準確度以及速度.

圖2 OpenPose流程

我們先來看一下一開始2017年OpenPose的模型(圖3), 與CPM類似也是透過多個Stage的迭代, 不斷提升每個Stage所預測出的關節與肢段的精度. 圖中的F是代表的是第一階段的輸入, 這個輸入是將影像透過VGG-19模型的前10層之後所擷取出的影像特徵, 將這個影像特徵再分別送入兩組CNN, 圖3中的分支1與分支2, 分支1所預測的是每一個關鍵點的Confidence Map(如同CPM), 每一個關鍵點代表的就是輸出的其中一張feature map, 例如總共有J個關鍵點, 就會產生J張 feature maps.而分支2就是針對每一個支段, 也是這篇文章新定義PAF, 每個支段都會以一個2維向量表示, 後面會詳述這個PAF是如何定義的. 同樣如果有C個支段, 就會產生C張feature maps.

圖3 2017年OpenPose模型

上述的兩個支段可以分別表達成下面兩個式子St與Lt. 其中St代表的是第t個階段所預測出各個關鍵點的Confidence map, ρt是第t階段的CNN架構. 這邊需注意第一階段的架構跟後續的架構是有些不同的, 第一階段的輸入只有從VGG-19 第10層擷取出的特徵外, 內部CNN架構只有5層. 第2階段之後的CNN則是7層的架構, 輸入除了經VGG-19擷取的特徵外, 還要把前一層所產生的關節點Confidence Map與各個肢段的PAF concatenate起來一起送入網路進行預測. 而Lt代表的就是第t個階段的肢段預測, 論文中稱他為PAF, 是一組2維的單位向量, 代表兩個關鍵點相連的向量. 而φ代表的就是產生這個向量的CNN架構, 同樣的第1階段的架構與後續的架構不同, 這部分與關鍵點的架構類似, 就不重述.

如果對於上面所說的關鍵點或是PAF描述不清楚, 我們可以來看一下下面這張圖, 圖4中列出第1, 第3與第6階段所產生的特徵圖, 圖4上面那一列所產生的是關於右手腕的Confidence Map, 而圖4下面那一列產生的則是右上臂的PAF, 可以看到在多人背景複雜的情形下, 手臂與手腕的位置經由多次調整後原本可能有被誤判的關鍵點或是PAF就逐步被修正.

圖4 不同階段所產生的關鍵點與PAF

與CPM相同, 在每個階段結束前都會針對每個階段的loss進行計算並進行權重更新, 這樣的好處可以避免多個階段導致梯度消失的問題. 各別loss function fS與fL如下所示, 在這些參數中, t代表的都是第t個Stage, S代表的是關鍵點, 而L代表PAF, p代表的是在影像上的位置, *代表的是ground truth的資料. Loss就是透過CNN架構預測出來的結果與ground truth的L2 norm, 這邊作者很聰明的用了一個W(p)參數乘在L2的結果前面, W(p)是一個0與1的數值, 這個參數的目的用以避免當ground truth沒有標記, 但是模型有預測出來時, 就會讓這個點的L2結果很大, 影響了原本的預測參數的調整.

了解了作者模型的架構, 以及loss function如何定義之後, 接著再來看一下真值ground truth如何定義. 首先我們看一下比較好理解各個關鍵點的真值是如何產生的. 關鍵點的真值可以參考下列式子. S前面有說過是代表關鍵點的位置, *代表真值, 而j與k分別代表第k個人的第j個關鍵點. p代表的就是影像上的每一個像素點的位置, 而xj,k指的就是影像上經由標註的關鍵點位置, σ參數用來定義其他影像點與關鍵點在平面上分布的範圍, σ值越大分布的範圍就越窄, 最後再取一個負值, 代表經過exponential這數值最大就是1, 離我們標註的xj,k越近得到的S*就越靠近1, 越遠就隨著σ逐步decade.

假設今天我們有一張多人的影像, 我們想要在這個影像中提供關於頭部標註的特徵. 大家可以想像最終在這張影像中每個人的頭上, 都有個標註了頭部位置的類似高斯分布圖. 而多個類似高斯的分布中, 作者他們是將多個位置採用max而不是平均值集結成一張真值圖, 以避免標註的位置因為過於相近, 導致相鄰的兩個峰值因為平均後而沒有得到正確的位置.

圖5 將每個標註後的關鍵位置透過Max集結起來

接著我們再來看PAF的真值是如何定義的, 這邊直接看圖6就很好理解, 在圖6中作者展示了第k個人的右前臂, 我們定義第k個人的右手肘Xj1,k與右手腕Xj2,k之間的區域是這第k個人的右前臂PAF.

圖6 PAF定義

在影像中上只要是在這個第k個右前臂範圍內的像素, 我們都給定每個像素一個數值L*c,k = v, 而右前臂範圍外的像素我們都給L*c,k = 0. 式子中k是第k個人, c是第c個肢段或PAF, L*c,k的定義如下:

而這個v就是我們前面提到的一個2維向量, 是經由兩個關節點所形成的單位向量, 如下兩式表示, 下兩式中lc,k是影像上肢段的長度, 以像素為單位, 而σl則是影像上肢段的寬度.

最終關於PAF的真值式子如下, PAF這邊採用的是平均而不是像關鍵點一樣採取最大值的做法, 這邊主要原因是PAF是以向量表示, 且肢段涵蓋的範圍比較大, 有可能不同人的圖樣肢段 (例如A的右前臂與B的右前臂)在影像上有交叉的情形, 而在兩個手臂交疊的像素, 用A與B兩個右前臂的向量平均來表示是比較合理的, 透過兩個向量的平均呈現該影像部為可能有多組肢段交疊.

理論上透過模型我們得到了每個人體上的關鍵點, 以及每個人體的PAFs, 我們應該能準確推斷出每個人的姿勢與位置, 論文中也有提到PAF的資訊可以協助在多人聚集的情形下, 仍能夠完成正確的肢段連結如下圖所示.

圖7 PAF資訊可以協助不同肢段點的連結

但是因為人像重疊的情形可能很複雜, 或是找出的關鍵點與PAF不搭配, 即便找出了關鍵點與PAF, 我們可能還是會有誤判的情形. 因此作者又進行了下列處理, 首先會先用non-maximum suppression將影像中預測重複的關鍵點移除, 接著作者定義了下列式子以量測找出來的關節點與PAF的關係, 這個式子所代表的是兩個向量的內積, 一個是PAF所預測肢段的向量Lc, 另一個是兩個關節點dj2與dj1之間所形成的單位向量, 如果兩個單位向量方向一致, 透過這個式子所得到的E值應該是最大的.

另外為了要找出哪兩個關節點有相互連結, 作者又定義了一個z參數, 用來決定兩個關節點是否相連, 其中j1與j2代表兩個關節點, j1有m個可能的位置, j2有n個可能的位置, 如果j1與j2相連, z就為1, 如果沒有就為0.

所以我們最終要解決的問題就是下列的式子, 我們要找一個最佳化的z, 讓我們的E可以最大, 另外我們給定了下面兩個限制條件, 可以確保同一個關節不會重複連結多個點.

為了解決這樣最佳化的問題, 作者將問題進一步簡化成只有bipartite matching的問題, 就我的理解, 像是頭不會與腳踝連接, 或是右手腕只能與右手肘連接等, 而這樣的問題正好可以用匈牙利演算法來解決, 匈牙利演算法可以去查Wiki說明, 算法就像是要解決一個任務分配的問題, (https://zh.wikipedia.org/wiki/%E5%8C%88%E7%89%99%E5%88%A9%E7%AE%97%E6%B3%95), 這個例子中的工人與任務剛好對應的就是我們要找個兩個關鍵點的組合. 因此透過匈牙利演算法讓我們找到一組最大的E, 完成所有的關鍵點的位置匹配.

在實際訓練上, 作者採用了MPII以及COCO的資料集進行訓練, 結果部份我覺得沒有2018年的那篇有趣, 所以我在下面介紹完2018年模型後再來談一些有趣的結果.

圖8就是2018年更新的OpenPose Model, 基本的結構類似, 但是可以看到作者將原本平行計算關節點與PAF改為串接的架構, F同樣是經由VGG-19第10層Convolution layer出來的結果, 先進行Tp個階段的PAF的預測, 後面在接上Tc個階段的關鍵點預測.

圖8 2018年OpenPose模型

在PAF的預測中, 只對前一階段的PAF結果與一開始的Feature Map進行微調, 式子如下. 而CNN的架構中, 2017年的論文在第2階段之後是用了5層7x7的filter之後再搭配2層1x1的filter. 到了2018年, 作者將原本的7x7, 換成3層的3x3, 讓原本的影像達到相同的receptive field, 但是因為將1層改為3層, 同時增加了模型的非現性度, 以及減少模型參數的數量. 同時與2017年的相比, 在運算PAF時不再有前一階段所預測出的關鍵點作為輔助特徵, 這邊作者有提到這樣在每個Stage運算時可以減少一半的計算量 (但是接數變兩倍不是相同??), 另外作者經實驗發現經多階段微調的PAF可以提升關鍵點的精度, 但是相反的步驟卻沒有這樣的效果, 有提到是PAF內其實就有涵蓋各關節點的資訊, 因此把PAF的預測放在關鍵點預測的前方.

在前面Tp個步驟進行PAF的預測與調整之後, 接著則進行每個關鍵部位的預測, 如下兩式. LTp就是第Tp階段得到的PAF, 而除了第一個STp關鍵點的預測, 後續的St預測都會將前一階段預測的關鍵點, VGG-19的影像特徵與LTp作為輸入預測關鍵點. 這邊所採用的CNN架構, 與先前所述的相同, 都改用3層3x3的convolution layer以減少參數量並增加非線性度.

而loss function的定義與得到關鍵點的位置與PAF後透過匈牙利演算法得到最後關鍵點的連結都與前篇論文相同, 所以這邊就不重複介紹. 結果的部分, 作者在MPII以及COCO資料集上也比較了本模型跟其他模型的差異, 這邊我覺得比較有趣的是下表作者這邊列出不同模型在COCO資料集上比較結果, 可以看到Top-Down的幾個模型AP還是高於Bottom-Up.

表1 不同Model在COCO資料集下的AP

另外, 相較於Top-Down的預測方式 (Alpha-Pose, Mask R-CNN), Bottom-up的OpenPose在不同人數下都能維持一定的推論速度.

圖9 不同模型對於影像中人數多寡的計算時間

希望透過這篇介紹可以讓大家更清楚OpenPose是如何運作的, 下一篇預計要來說明OpenPose的輕量化是如何設計的.

--

--