正確的身體姿勢是一個人整體健康的關鍵。然而,保持正確的身體姿勢可能很困難,因為我們經常忘記這一點。這篇博文將引導您完成為此構建解決方案所需的步驟。最近,我們在使用 POSE 進行身體姿勢檢測方面玩得很開心。它就像一個魅力!
文章目錄
- 使用 Pose 進行身體姿勢檢測
- 應用目的
- 身體姿勢檢測和分析應用工作流程
- 要求
- 身體姿勢檢測代碼說明
- 使用 pose進行身體姿勢檢測
Pose 是一種高保真身體姿勢跟蹤解決方案,可從 RGB 幀(注意RGB圖像幀)渲染全身上的33 個 3D 地標和背景分割掩模。它利用 BlazePose[1] 拓撲,這是 COCO[2]、BlazeFace[3] 和 BlazePalm[4] 拓撲的超集。
應用目標 – 身體追蹤
我們的目標是從完美的側視圖檢測一個人,并測量頸部和軀干相對于某個參考軸的傾斜度。通過監測人彎曲低于某個閾值角度時的傾斜角度。
其他功能包括測量特定姿勢的時間和相機對準。我們必須確保相機看到正確的側視圖。因此我們需要對齊功能。
添加
代碼環境安裝
pip install -r requirements.txt
身體姿勢檢測代碼說明
1. 導入庫
import cv2
import numpy
…
2. 計算偏移距離的函數
該設置要求人處于正確的側視圖中。該函數findDistance 幫助我們確定兩點之間的偏移距離。它可以是髖點、眼睛或肩膀。
選擇這些點是因為它們總是或多或少關于人體的中心軸對稱。這樣,我們將在腳本中合并相機對齊功能。
def findDistance(x1, y1, x2, y2):
dist = m.sqrt((x2-x1)**2+(y2-y1)**2)
return dist
3. 計算身體姿勢傾斜度的功能
角度是姿勢的主要決定因素。我們使用頸線和軀干線與 y 軸所成的角度。領口連接肩膀和眼睛。這里我們以肩部為支點。
同樣,軀干線連接臀部和肩膀,其中臀部被認為是樞軸點
以頸線為例,我們有以下幾點。
P1 (x1,y1):肩部
P2 (x2, y2):眼睛
P3 (x3,y3):穿過P1的垂直軸上的任意點
顯然,P3的x 坐標與 P1 的 x 坐標相同。由于y3對所有y都有效,因此為了簡單起見,我們取 y3 = 0。
我們采用向量方法來求三點的內角。兩個向量P 12 和P 13之間的角度 由下式給出:
def findAngle(x1, y1, x2, y2):theta = m.acos( (y2 -y1)*(-y1) / (m.sqrt((x2 - x1)**2 + (y2 - y1)**2 ) * y1) )degree = int(180/m.pi)*thetareturn degree
4. 發送不良身體姿勢警報功能
使用此功能在檢測到不良姿勢時發送警報。我們將其留為空,供您使用。您可以在方便的時候隨意發揮創意和定制。例如,您可以連接 Telegram Bot 來發出警報,這非常簡單。鏈接見參考文獻[6]。或者您可以通過創建 Android 應用程序將其提升一個檔次。
def sendWarning(x):pass
在這里初始化常量和方法。這些內容應該通過內聯注釋是不言自明的。
# Initialize frame
counters.good_frames = 0bad_frames = 0
# Font type.font = cv2.FONT_HERSHEY_SIMPLEX #
Colors.blue = (255, 127, 0)red = (50, 50, 255)green = (127, 255, 0)dark_blue = (127, 20, 0)light_green = (127, 233, 100)yellow = (0, 255, 255)pink = (255, 0, 255)
# Initialize mediapipe pose
class.mp_pose = mp.solutions.posepose = mp_pose.Pose()
身體姿勢檢測主要功能
1. 創建視頻捕獲和視頻寫入器對象
為了進行演示,我們使用預先錄制的視頻樣本。在實踐中,您需要定位網絡攝像頭以捕獲您的側視圖。在以下代碼片段中,創建了視頻捕獲和視頻編寫器對象。
如您所見,我們正在獲取視頻元數據來創建視頻捕獲對象。如果要以mp4格式寫入,請將編解碼器更改為*‘mp4v’。有關視頻編寫器和處理編解碼器的更直觀指南,請查看有關OpenCV 視頻編寫器的文章。
# For webcam input replace file name with 0.
file_name = 'input.mp4' cap = cv2.VideoCapture(file_name)
# Meta.
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frame_size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# Video writer.
video_output = cv2.VideoWriter('output.mp4', fourcc, fps, frame_size)
2.身體姿勢檢測 主循環
- fPose ()解決方案的可配置 API不需要太多調整。默認值足以檢測姿勢地標。但是,如果我們希望實用程序生成分段掩碼,則
ENABLE_SEGMENTATION 標志必須設置為True。以下是姿勢解決方案中的一些可配置 API 。 - STATIC_IMAGE_MODE:這是一個布爾值。如果設置為True,則會針對每個輸入圖像運行人物檢測。這對于視頻來說不是必需的,視頻中檢測運行一次,然后進行地標跟蹤。默認值為False。
MODEL_COMPLEXITY:默認值為 1。它可以是 0、1 或 2。如果選擇更高的復雜度,推理時間會增加。 - ENABLE_SEGMENTATION:如果設置為True,解決方案會生成分割掩模以及姿勢地標。默認值為False。
- MIN_DETECTION_CONFIDENCE:范圍從 [0.0 – 1.0]。顧名思義,它是檢測被認為有效的最小置信度值。默認值為
0.5。 - MIN_TRACKING_CONFIDENCE:范圍從 [0.0 – 1.0]。它是被視為已跟蹤的地標的最小置信值。默認值為 0.5。
通常,默認值就可以很好地工作。因此,我們不會在mp_pose.Pose().以下部分中傳遞任何參數,該部分將討論 RGB 幀的處理,稍后我們可以從中提取姿勢地標。最后,我們將圖像轉換回 OpenCV 友好的 BGR顏色空間。
3. 獲取身體姿勢地標坐標
解決方案輸出對象的pose_landmarks屬性提供地標的標準化x和y坐標。因此,為了獲得實際值,我們需要將輸出分別乘以圖像的寬度和高度。
地標“ LEFT_SHOULDER”、“RIGHT_SHOULDER”等是 PoseLandmark 類的屬性。為了獲取標準化坐標,我們使用以下語法。
使用如下所示的表示形式來簡化這些方法。
4. 對齊相機
這是為了確保相機捕捉到人的正確側視圖。我們正在測量左肩點和右肩點之間的水平距離。正確對齊后,左右點應該幾乎重合。
請注意,偏移距離閾值基于對具有與視頻樣本精確尺寸的數據集的觀察。如果您嘗試使用更高分辨率的樣本,該值將會改變。它不必非常具體;您可以根據自己的直覺設置閾值。
實際上,距離法根本不是確定對齊的正確方法。它應該是基于角度的。
為簡單起見,我們使用距離方法。
# Calculate distance between left shoulder and right shoulderpoints.offset = findDistance(l_shldr_x, l_shldr_y, r_shldr_x, r_shldr_y)
# Assist to align the camera to point at the side view of the person.
# Offset threshold 30 is based on results obtained from analysis over 100 samples.if offset < 100: cv2.putText(image, str(int(offset)) + ' Aligned', (w - 150, 30), font, 0.9, green, 2)else: cv2.putText(image, str(int(offset)) + ' Not Aligned', (w - 150, 30), font, 0.9, red, 2
5. 計算身體姿勢傾斜度并繪制地標
使用預定義函數獲得傾角findAngle。地標及其連接如下圖所示。
6. 身體姿勢檢測條件
根據姿勢的好壞;顯示結果。同樣,閾值角度基于直覺。您可以根據需要設置閾值。每次檢測時,良好姿勢和不良姿勢的幀計數器都會分別遞增。
特定姿勢的時間可以通過幀數除以fps來計算。查看我們之前的博客文章中的fps 測量方法。
結論
這就是使用構建姿勢校正器應用程序的全部內容。在這篇文章中,我們實現檢測人體姿勢。您學習了如何獲取姿勢標志、可配置 API、輸出等。我希望這篇博文可以幫助 姿勢的基礎知識,并幫助您為下一個項目產生一些新想法。