通過一個偶然機會,我了解到了人體姿態解算,在學習K210之余,我便想著通過opencv實現這個功能,查找了很多資料,發現可以利用opencv+openpose實現,接著我又開始找一些資料,在pycharm上部署。
前言
人體姿態估計的一個有趣應用是 CGI(computer graphic image,一種電影制造技術)應用。如果可以檢測出人體姿態,那么圖形、風格、特效增強、設備和藝術造型等就可以被加載在人體上。
通過追蹤人體姿態的變化,渲染的圖形可以在人動的時候“自然”地與人“融合”。姿態估計的一個有趣應用是在交互游戲中追蹤人體對象的運動。
比較流行的 Kinect 使用 3D 姿態估計(采用 IR 傳感器數據)來追蹤人類玩家的運動,從而利用它來渲染虛擬人物的動作。
應用:
用于檢測一個人是否摔倒或疾病
用于健身、體育和舞蹈等的自動教學
用于理解全身的肢體語言(如機場跑道信號、交警信號等)
用于增強安保和監控
一、環境配置
pycharm2021.2.2
pycharm是一個很好用的軟件,剛開始我們必須要配置相應的環境,當然你使用我主頁里那篇模型訓練的環境也可以,在你運行的時候系統會提示你缺少了什么環境,并讓你安裝,你直接安裝即可。這里我就不過多的贅述了。
1.導入文件
在pycharm上導入相應的文件后,你可以直接點擊運行,系統會提示你缺少了什么環境,缺少什么就安裝什么,通過終端使用pip安裝即可。
需要的留下郵箱即可,我發給你。
2.具體代碼
# To use Inference Engine backend, specify location of plugins: # export LD_LIBRARY_PATH=/opt/intel/deeplearning_deploymenttoolkit/deployment_tools/external/mklml_lnx/lib:$LD_LIBRARY_PATH import cv2 as cv import numpy as np import argparse parser = argparse.ArgumentParser() parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera') parser.add_argument('--thr', default=0.2, type=float, help='Threshold value for pose parts heat map') parser.add_argument('--width', default=368, type=int, help='Resize input to specific width.') parser.add_argument('--height', default=368, type=int, help='Resize input to specific height.') args = parser.parse_args() BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4, "LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9, "RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14, "LEye": 15, "REar": 16, "LEar": 17, "Background": 18 } POSE_PAIRS = [ ["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"], ["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"], ["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"], ["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"], ["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"] ] inWidth = args.width inHeight = args.height net = cv.dnn.readNetFromTensorflow("graph_opt.pb") cap = cv.VideoCapture(args.input if args.input else 0) while cv.waitKey(1) < 0: ? ?hasFrame, frame = cap.read() ? ?if not hasFrame: ? ? ? ?cv.waitKey() ? ? ? ?break ? ?frameWidth = frame.shape[1] ? ?frameHeight = frame.shape[0] ? ? ? ?net.setInput(cv.dnn.blobFromImage(frame, 1.0, (inWidth, inHeight), (127.5, 127.5, 127.5), swapRB=True, crop=False)) ? ?out = net.forward() ? ?out = out[:, :19, :, :] ?# MobileNet output [1, 57, -1, -1], we only need the first 19 elements ? ?assert(len(BODY_PARTS) == out.shape[1]) ? ?points = [] ? ?for i in range(len(BODY_PARTS)): ? ? ? ?# Slice heatmap of corresponging body's part. ? ? ? ?heatMap = out[0, i, :, :] ? ? ? ?# Originally, we try to find all the local maximums. To simplify a sample ? ? ? ?# we just find a global one. However only a single pose at the same time ? ? ? ?# could be detected this way. ? ? ? ?_, conf, _, point = cv.minMaxLoc(heatMap) ? ? ? ?x = (frameWidth * point[0]) / out.shape[3] ? ? ? ?y = (frameHeight * point[1]) / out.shape[2] ? ? ? ?# Add a point if it's confidence is higher than threshold. ? ? ? ?points.append((int(x), int(y)) if conf > args.thr else None) for pair in POSE_PAIRS: partFrom = pair[0] partTo = pair[1] assert(partFrom in BODY_PARTS) assert(partTo in BODY_PARTS) idFrom = BODY_PARTS[partFrom] idTo = BODY_PARTS[partTo] if points[idFrom] and points[idTo]: cv.line(frame, points[idFrom], points[idTo], (0, 255, 0), 3) cv.ellipse(frame, points[idFrom], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED) cv.ellipse(frame, points[idTo], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED) t, _ = net.getPerfProfile() freq = cv.getTickFrequency() / 1000 cv.putText(frame, '%.2fms' % (t / freq), (10, 20), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0)) cv.imshow('OpenPose using OpenCV', frame)
這里便是主函數的代碼。
3.效果展示
這副圖片便是識別的效果,幀率還是很不錯的。
三、效果優化
這個幀率雖然可以,但是效果屬實有點拉跨。教我K210的學長便指導我進行優化改進,這里附上學長的連接
1.具體代碼
import cv2 import time import mediapipe as mp from tqdm import tqdm # 導入solution mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils pose = mp_pose.Pose(static_image_mode=False, # model_complexity=1, smooth_landmarks=True, # enable_segmentation=True, min_detection_confidence=0.5, min_tracking_confidence=0.5) def process_frame(img): # BGR轉RGB img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) results = pose.process(img_RGB) # 可視化 mp_drawing.draw_landmarks(img, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) # look_img(img) # mp_drawing.plot_landmarks(results.pose_world_landmarks, mp_pose.POSE_CONNECTIONS) # # BGR轉RGB # img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # # results = hands.process(img_RGB) # if results.multi_hand_landmarks: # 如果有檢測到手 # # for hand_idx in range(len(results.multi_hand_landmarks)): # hand_21 = results.multi_hand_landmarks[hand_idx] # mpDraw.draw_landmarks(img, hand_21, mp_hands.HAND_CONNECTIONS) return img cap = cv2.VideoCapture(1) # 打開cap cap.open(0) # 無限循環,直到break被觸發 while cap.isOpened(): # 獲取畫面 success, frame = cap.read() if not success: print('Error') break ## !!!處理幀函數 frame = process_frame(frame) # 展示處理后的三通道圖像 cv2.imshow('my_window', frame) if cv2.waitKey(1) in [ord('q'), 27]: break cap.release() cv2.destroyAllWindows()
2.效果展示
效果簡直太好了
總結
到這里這篇文章就結束了,寫這篇博客只是單純記錄自己的學習過程。希望看到這篇博客的你,能夠更加堅定的學習。胡適說過一句話我覺得特別好,這里分享給大家。
怕什么真理無窮,進一寸有進一寸的歡喜。
審核編輯:湯梓紅
-
傳感器
+關注
關注
2548文章
50667瀏覽量
751947 -
3D
+關注
關注
9文章
2862瀏覽量
107324 -
代碼
+關注
關注
30文章
4747瀏覽量
68348 -
OpenCV
+關注
關注
30文章
628瀏覽量
41260 -
CGI
+關注
關注
0文章
20瀏覽量
10342
原文標題:【人體姿態檢測】通過Opencv+Openpose實現
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論