Python OpenCV實現姿態識別的詳細代碼
前言
想要使用攝像頭實現一個多人姿態識別
環境安裝
下載並安裝 Anaconda
官網連接 https://anaconda.cloud/installers
安裝 Jupyter Notebook
檢查Jupyter Notebook是否安裝
Tip:這裡涉及到一個切換Jupyter Notebook內核的問題,在我這篇文章中有提到
AnacondaNavigator Jupyter Notebook更換Python內核https://www.jb51.net/article/238496.htm
生成Jupyter Notebook項目目錄
打開Anaconda Prompt
切換到項目目錄
輸入Jupyter notebook
在瀏覽器中打開 Jupyter Notebook
並創建新的記事本
下載訓練庫
圖片以及訓練庫都在下方鏈接
https://github.com/quanhua92/human-pose-estimation-opencv
將圖片和訓練好的模型放到項目路徑中graph_opt.pb
為訓練好的模型
單張圖片識別
導入庫
import cv2 as cv import os import matplotlib.pyplot as plt
加載訓練模型
net=cv.dnn.readNetFromTensorflow("graph_opt.pb")
初始化
inWidth=368 inHeight=368 thr=0.2 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"] ]
載入圖片
img = cv.imread("image.jpg")
顯示圖片
plt.imshow(img)
調整圖片顏色
plt.imshow(cv.cvtColor(img,cv.COLOR_BGR2RGB))
姿態識別
def pose_estimation(frame): 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 > 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)) return frame # 處理圖片 estimated_image=pose_estimation(img) # 顯示圖片 plt.imshow(cv.cvtColor(estimated_image,cv.COLOR_BGR2RGB))
視頻識別
Tip:與上面圖片識別代碼是銜接的
視頻來自互聯網,侵刪
cap = cv.VideoCapture('testvideo.mp4') cap.set(3,800) cap.set(4,800) if not cap.isOpened(): cap=cv.VideoCapture(0) raise IOError("Cannot open vide") 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 > 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('Video Tutorial',frame)
實時攝像頭識別
Tip:與上面圖片識別代碼是銜接的
cap = cv.VideoCapture(0) cap.set(cv.CAP_PROP_FPS,10) cap.set(3,800) cap.set(4,800) if not cap.isOpened(): cap=cv.VideoCapture(0) raise IOError("Cannot open vide") 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 > 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('Video Tutorial',frame)
參考
DeepLearning_by_PhDScholar
Human Pose Estimation using opencv | python | OpenPose | stepwise implementation for beginners
https://www.youtube.com/watch?v=9jQGsUidKHs
到此這篇關於Python OpenCV實現姿態識別的文章就介紹到這瞭,更多相關Python姿態識別內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- python入門jupyter基礎操作及文本用法
- jupyter notebook保存文件默認路徑更改方法匯總(親測可以)
- 聊聊.py和.ipynb的一些小知識
- jupyter 添加不同內核的操作
- 詳解如何修改jupyter notebook的默認目錄和默認瀏覽器