通過一個(gè)偶然機(jī)會(huì),我了解到了人體姿態(tài)解算,在學(xué)習(xí)K210之余,我便想著通過opencv實(shí)現(xiàn)這個(gè)功能,查找了很多資料,發(fā)現(xiàn)可以利用opencv+openpose實(shí)現(xiàn),接著我又開始找一些資料,在pycharm上部署。
前言
人體姿態(tài)估計(jì)的一個(gè)有趣應(yīng)用是 CGI(computer graphic image,一種電影制造技術(shù))應(yīng)用。如果可以檢測(cè)出人體姿態(tài),那么圖形、風(fēng)格、特效增強(qiáng)、設(shè)備和藝術(shù)造型等就可以被加載在人體上。
通過追蹤人體姿態(tài)的變化,渲染的圖形可以在人動(dòng)的時(shí)候“自然”地與人“融合”。姿態(tài)估計(jì)的一個(gè)有趣應(yīng)用是在交互游戲中追蹤人體對(duì)象的運(yùn)動(dòng)。
比較流行的 Kinect 使用 3D 姿態(tài)估計(jì)(采用 IR 傳感器數(shù)據(jù))來(lái)追蹤人類玩家的運(yùn)動(dòng),從而利用它來(lái)渲染虛擬人物的動(dòng)作。
應(yīng)用:
用于檢測(cè)一個(gè)人是否摔倒或疾病
用于健身、體育和舞蹈等的自動(dòng)教學(xué)
用于理解全身的肢體語(yǔ)言(如機(jī)場(chǎng)跑道信號(hào)、交警信號(hào)等)
用于增強(qiáng)安保和監(jiān)控
一、環(huán)境配置
pycharm2021.2.2
pycharm是一個(gè)很好用的軟件,剛開始我們必須要配置相應(yīng)的環(huán)境,當(dāng)然你使用我主頁(yè)里那篇模型訓(xùn)練的環(huán)境也可以,在你運(yùn)行的時(shí)候系統(tǒng)會(huì)提示你缺少了什么環(huán)境,并讓你安裝,你直接安裝即可。這里我就不過多的贅述了。
1.導(dǎo)入文件
在pycharm上導(dǎo)入相應(yīng)的文件后,你可以直接點(diǎn)擊運(yùn)行,系統(tǒng)會(huì)提示你缺少了什么環(huán)境,缺少什么就安裝什么,通過終端使用pip安裝即可。
需要的留下郵箱即可,我發(fā)給你。
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)
這里便是主函數(shù)的代碼。
3.效果展示
這副圖片便是識(shí)別的效果,幀率還是很不錯(cuò)的。
三、效果優(yōu)化
這個(gè)幀率雖然可以,但是效果屬實(shí)有點(diǎn)拉跨。教我K210的學(xué)長(zhǎng)便指導(dǎo)我進(jìn)行優(yōu)化改進(jìn),這里附上學(xué)長(zhǎng)的連接
1.具體代碼
import cv2 import time import mediapipe as mp from tqdm import tqdm # 導(dǎo)入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轉(zhuǎn)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轉(zhuǎn)RGB # img_RGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # # results = hands.process(img_RGB) # if results.multi_hand_landmarks: # 如果有檢測(cè)到手 # # 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) # 無(wú)限循環(huán),直到break被觸發(fā) while cap.isOpened(): # 獲取畫面 success, frame = cap.read() if not success: print('Error') break ## !!!處理幀函數(shù) frame = process_frame(frame) # 展示處理后的三通道圖像 cv2.imshow('my_window', frame) if cv2.waitKey(1) in [ord('q'), 27]: break cap.release() cv2.destroyAllWindows()
2.效果展示
效果簡(jiǎn)直太好了
總結(jié)
到這里這篇文章就結(jié)束了,寫這篇博客只是單純記錄自己的學(xué)習(xí)過程。希望看到這篇博客的你,能夠更加堅(jiān)定的學(xué)習(xí)。胡適說(shuō)過一句話我覺得特別好,這里分享給大家。
怕什么真理無(wú)窮,進(jìn)一寸有進(jìn)一寸的歡喜。
審核編輯:湯梓紅
-
傳感器
+關(guān)注
關(guān)注
2551文章
51099瀏覽量
753606 -
3D
+關(guān)注
關(guān)注
9文章
2878瀏覽量
107548 -
代碼
+關(guān)注
關(guān)注
30文章
4788瀏覽量
68616 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41352 -
CGI
+關(guān)注
關(guān)注
0文章
20瀏覽量
10354
原文標(biāo)題:【人體姿態(tài)檢測(cè)】通過Opencv+Openpose實(shí)現(xiàn)
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論