利用opencv+openpose實現人體姿態檢測,附詳細代碼。
通過一個偶然機會,我了解到了人體姿態解算,在學習K210之余,我便想著通過opencv實現這個功能,查找了很多資料,發現可以利用opencv+openpose實現,接著我又開始找一些資料,在pycharm上部署。
前言
人體姿態估計的一個有趣應用是 CGI(computer graphic image,一種電影制造技術)應用。如果可以檢測出人體姿態,那么圖形、風格、特效增強、設備和藝術造型等就可以被加載在人體上。
通過追蹤人體姿態的變化,渲染的圖形可以在人動的時候“自然”地與人“融合”。姿態估計的一個有趣應用是在交互游戲中追蹤人體對象的運動。
比較流行的 Kinect 使用 3D 姿態估計(采用 IR 傳感器數據)來追蹤人類玩家的運動,從而利用它來渲染虛擬人物的動作。
應用:
用于檢測一個人是否摔倒或疾病
用于健身、體育和舞蹈等的自動教學
用于理解全身的肢體語言(如機場跑道信號、交警信號等)
用于增強安保和監控
一、環境配置
pycharm2021.2.2
pycharm是一個很好用的軟件,剛開始我們必須要配置相應的環境,當然你使用我主頁里那篇模型訓練的環境也可以,在你運行的時候系統會提示你缺少了什么環境,并讓你安裝,你直接安裝即可。這里我就不過多的贅述了。
1.導入文件
在pycharm上導入相應的文件后,你可以直接點擊運行,系統會提示你缺少了什么環境,缺少什么就安裝什么,通過終端使用pip安裝即可。
2.具體代碼
#TouseInferenceEnginebackend,specifylocationofplugins: #exportLD_LIBRARY_PATH=/opt/intel/deeplearning_deploymenttoolkit/deployment_tools/external/mklml_lnx/lib:$LD_LIBRARY_PATH importcv2ascv importnumpyasnp importargparse parser=argparse.ArgumentParser() parser.add_argument('--input',help='Pathtoimageorvideo.Skiptocaptureframesfromcamera') parser.add_argument('--thr',default=0.2,type=float,help='Thresholdvalueforposepartsheatmap') parser.add_argument('--width',default=368,type=int,help='Resizeinputtospecificwidth.') parser.add_argument('--height',default=368,type=int,help='Resizeinputtospecificheight.') 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.inputifargs.inputelse0) whilecv.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.threlseNone) forpairinPOSE_PAIRS: partFrom=pair[0] partTo=pair[1] assert(partFrominBODY_PARTS) assert(partToinBODY_PARTS) idFrom=BODY_PARTS[partFrom] idTo=BODY_PARTS[partTo] ifpoints[idFrom]andpoints[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('OpenPoseusingOpenCV',frame)
這里便是主函數的代碼。
3.效果展示
這副圖片便是識別的效果,幀率還是很不錯的。
三、效果優化
這個幀率雖然可以,但是效果屬實有點拉跨。教我K210的學長便指導我進行優化改進,這里附上學長的連接(https://blog.csdn.net/hyayq8124spm=1001.2014.3001.5509)
1.具體代碼
importcv2 importtime importmediapipeasmp fromtqdmimporttqdm #導入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) defprocess_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) #ifresults.multi_hand_landmarks:#如果有檢測到手 # #forhand_idxinrange(len(results.multi_hand_landmarks)): #hand_21=results.multi_hand_landmarks[hand_idx] #mpDraw.draw_landmarks(img,hand_21,mp_hands.HAND_CONNECTIONS) returnimg cap=cv2.VideoCapture(1) #打開cap cap.open(0) #無限循環,直到break被觸發 whilecap.isOpened(): #獲取畫面 success,frame=cap.read() ifnotsuccess: print('Error') break ##!!!處理幀函數 frame=process_frame(frame) #展示處理后的三通道圖像 cv2.imshow('my_window',frame) ifcv2.waitKey(1)in[ord('q'),27]: break cap.release() cv2.destroyAllWindows()
2.效果展示
總結
到這里這篇文章就結束了,寫這篇博客只是單純記錄自己的學習過程。希望看到這篇博客的你,能夠更加堅定的學習。胡適說過一句話我覺得特別好,這里分享給大家。
-
傳感器
+關注
關注
2551文章
51099瀏覽量
753572 -
3D
+關注
關注
9文章
2878瀏覽量
107538 -
OpenCV
+關注
關注
31文章
635瀏覽量
41350
原文標題:實踐教程|通過Opencv+Openpose實現人體姿態檢測
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論