Python圖像處理篇之opencv實現(xiàn)坐姿檢測
前言
坐姿檢測是計算機視覺中的一個應(yīng)用,可以通過分析人體姿態(tài)來判斷是否保持正確坐姿。下面我將介紹使用Python實現(xiàn)坐姿檢測的方法和完整代碼。
一、方法概述
使用OpenCV和MediaPipe
使用OpenCV和MediaPipe:MediaPipe提供了現(xiàn)成的人體姿態(tài)估計模型
關(guān)鍵點檢測
關(guān)鍵點檢測:檢測身體關(guān)鍵點(如肩膀、耳朵、臀部等)
角度計算
角度計算:計算關(guān)鍵點之間的角度來判斷坐姿
姿態(tài)評估
姿勢評估:根據(jù)角度閾值判斷坐姿是否正確
二、完整代碼實現(xiàn)
import cv2 import mediapipe as mp import numpy as np import time class PostureDetector: def __init__(self, mode=False, upBody=False, smooth=True, detectionCon=0.5, trackCon=0.5): """ 初始化姿勢檢測器 參數(shù): mode: 是否靜態(tài)圖像模式 (False表示視頻流) upBody: 是否只檢測上半身 smooth: 是否平滑處理 detectionCon: 檢測置信度閾值 trackCon: 跟蹤置信度閾值 """ self.mode = mode self.upBody = upBody self.smooth = smooth self.detectionCon = detectionCon self.trackCon = trackCon self.mpDraw = mp.solutions.drawing_utils self.mpPose = mp.solutions.pose self.pose = self.mpPose.Pose( static_image_mode=self.mode, model_complexity=1, smooth_landmarks=self.smooth, enable_segmentation=False, smooth_segmentation=self.smooth, min_detection_confidence=self.detectionCon, min_tracking_confidence=self.trackCon ) # 坐姿評估參數(shù) self.good_posture_time = 0 self.bad_posture_time = 0 self.posture_status = "Unknown" self.last_posture_change = time.time() def find_pose(self, img, draw=True): """ 檢測圖像中的姿勢關(guān)鍵點 參數(shù): img: 輸入圖像 (BGR格式) draw: 是否繪制關(guān)鍵點和連接線 返回: 帶標注的圖像和姿勢關(guān)鍵點 """ img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) self.results = self.pose.process(img_rgb) if self.results.pose_landmarks and draw: self.mpDraw.draw_landmarks( img, self.results.pose_landmarks, self.mpPose.POSE_CONNECTIONS) return img def get_landmarks(self, img): """ 獲取所有姿勢關(guān)鍵點的坐標 參數(shù): img: 輸入圖像 返回: 關(guān)鍵點坐標列表 (x,y,z) 或 None """ self.landmarks = [] if self.results.pose_landmarks: for id, lm in enumerate(self.results.pose_landmarks.landmark): h, w, c = img.shape cx, cy = int(lm.x * w), int(lm.y * h) self.landmarks.append([id, cx, cy, lm.z]) return self.landmarks def calculate_angle(self, a, b, c): """ 計算三個點之間的角度 參數(shù): a, b, c: 三個點的坐標 (x,y) 返回: 角度 (degrees) """ a = np.array(a) b = np.array(b) c = np.array(c) radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0]) angle = np.abs(radians * 180.0 / np.pi) if angle > 180.0: angle = 360 - angle return angle def evaluate_posture(self, img, draw=True): """ 評估坐姿是否正確 參數(shù): img: 輸入圖像 draw: 是否在圖像上繪制評估結(jié)果 返回: 圖像和坐姿評估結(jié)果 """ current_time = time.time() posture_changed = False if not self.landmarks or len(self.landmarks) < 33: return img, "No person detected" # 獲取需要的關(guān)節(jié)點 left_shoulder = self.landmarks[11][1:3] # 11: 左肩 right_shoulder = self.landmarks[12][1:3] # 12: 右肩 left_ear = self.landmarks[7][1:3] # 7: 左耳 right_ear = self.landmarks[8][1:3] # 8: 右耳 left_hip = self.landmarks[23][1:3] # 23: 左髖 right_hip = self.landmarks[24][1:3] # 24: 右髖 # 計算肩膀中點 shoulder_mid = ( (left_shoulder[0] + right_shoulder[0]) // 2, (left_shoulder[1] + right_shoulder[1]) // 2 ) # 計算耳朵中點 ear_mid = ( (left_ear[0] + right_ear[0]) // 2, (left_ear[1] + right_ear[1]) // 2 ) # 計算髖部中點 hip_mid = ( (left_hip[0] + right_hip[0]) // 2, (left_hip[1] + right_hip[1]) // 2 ) # 計算脊柱角度 (肩膀-髖部-垂直線) spine_angle = self.calculate_angle( (shoulder_mid[0], shoulder_mid[1] - 100), # 肩膀上方一點 shoulder_mid, hip_mid ) # 計算頸部角度 (耳朵-肩膀-水平線) neck_angle = self.calculate_angle( (ear_mid[0] - 100, ear_mid[1]), ear_mid, shoulder_mid ) # 坐姿評估標準 good_spine = 160 < spine_angle < 200 # 脊柱應(yīng)該接近垂直 good_neck = 70 < neck_angle < 110 # 頸部應(yīng)該接近垂直 # 判斷坐姿 new_status = "Good" if good_spine and good_neck else "Bad" # 更新姿勢狀態(tài)時間 if new_status != self.posture_status: posture_changed = True self.last_posture_change = current_time self.posture_status = new_status else: if new_status == "Good": self.good_posture_time += 1 else: self.bad_posture_time += 1 # 在圖像上繪制結(jié)果 if draw: # 繪制關(guān)鍵點和連接線 cv2.circle(img, ear_mid, 8, (255, 0, 0), cv2.FILLED) cv2.circle(img, shoulder_mid, 8, (255, 0, 0), cv2.FILLED) cv2.circle(img, hip_mid, 8, (255, 0, 0), cv2.FILLED) cv2.line(img, ear_mid, shoulder_mid, (255, 0, 0), 3) cv2.line(img, shoulder_mid, hip_mid, (255, 0, 0), 3) # 顯示角度信息 cv2.putText(img, f"Spine Angle: {int(spine_angle)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) cv2.putText(img, f"Neck Angle: {int(neck_angle)}", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) # 顯示坐姿狀態(tài) color = (0, 255, 0) if new_status == "Good" else (0, 0, 255) cv2.putText(img, f"Posture: {new_status}", (10, 90), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2) # 顯示時間統(tǒng)計 cv2.putText(img, f"Good Time: {self.good_posture_time//10}s", (10, 120), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) cv2.putText(img, f"Bad Time: {self.bad_posture_time//10}s", (10, 140), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) # 如果姿勢不良,添加警告 if new_status == "Bad": cv2.putText(img, "WARNING: Bad Posture!", (img.shape[1]//2 - 150, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) return img, new_status def main(): cap = cv2.VideoCapture(0) # 使用攝像頭 detector = PostureDetector() while True: success, img = cap.read() if not success: break img = detector.find_pose(img) landmarks = detector.get_landmarks(img) if landmarks: img, posture = detector.evaluate_posture(img) cv2.imshow("Posture Detection", img) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
三、代碼說明
PostureDetector類
PostureDetector類:核心坐姿檢測類
find_pose()
find_pose(): 檢測圖像中的人體姿勢
get_landmarks()
get_landmarks(): 獲取姿勢關(guān)鍵點坐標
cakculate_angle()
calculate_angle(): 計算三個關(guān)鍵點之間的角度
evaluate_posture()
evaluate_posture(): 評估坐姿是否正確
坐姿評估標準(可進行參數(shù)調(diào)整):
脊柱角度應(yīng)在160-200度之間(接近垂直)
頸部角度應(yīng)在70-110度之間(接近垂直)
滿足以上條件判斷為"Good"坐姿,否則為"Bad"
可視化功能:
- 繪制關(guān)鍵點和連接線
- 顯示角度數(shù)值
- 顯示坐姿狀態(tài)和時間統(tǒng)計
- 不良坐姿時顯示警告
如何使用
安裝依賴庫:
pip install opencv-python mediapipe numpy
運行腳本:
python posture_detection.py
調(diào)整攝像頭位置,確保能清晰看到上半身
四、改進方向
- 添加更多評估標準(如肩膀是否前傾)
- 實現(xiàn)坐姿歷史記錄和統(tǒng)計分析
- 添加聲音提醒功能
- 優(yōu)化性能(如降低圖像分辨率)
- 添加校準功能,適應(yīng)不同體型
這個實現(xiàn)提供了基本的坐姿檢測功能,你可以根據(jù)需要進一步擴展和完善。
總結(jié)
到此這篇關(guān)于Python圖像處理篇之opencv實現(xiàn)坐姿檢測的文章就介紹到這了,更多相關(guān)Python opencv坐姿檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
教你怎么用python實現(xiàn)字符串轉(zhuǎn)日期
今天教各位小伙伴怎么用python實現(xiàn)字符串轉(zhuǎn)日期,文中有非常詳細的代碼示例,對正在學(xué)習(xí)python的小伙伴很有幫助,需要的朋友可以參考下2021-05-05pytorch 實現(xiàn)在預(yù)訓(xùn)練模型的 input上增減通道
今天小編就為大家分享一篇pytorch 實現(xiàn)在預(yù)訓(xùn)練模型的 input上增減通道,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01python為Django項目上的每個應(yīng)用程序創(chuàng)建不同的自定義404頁面(最佳答案)
這篇文章主要介紹了python為Django項目上的每個應(yīng)用程序創(chuàng)建不同的自定義404頁面,本文給出了最佳答案,大家可以跟隨小編一起學(xué)習(xí)下2020-03-03PyTorch中的squeeze()和unsqueeze()解析與應(yīng)用案例
這篇文章主要介紹了PyTorch中的squeeze()和unsqueeze()解析與應(yīng)用案例,文章內(nèi)容介紹詳細,需要的小伙伴可以參考一下,希望對你有所幫助2022-03-03Python爬蟲selenium驗證之中文識別點選+圖片驗證碼案例(最新推薦)
本文介紹了如何使用Python和Selenium結(jié)合ddddocr庫實現(xiàn)圖片驗證碼的識別和點擊功能,感興趣的朋友一起看看吧2025-02-02