当前位置:网站首页>Single or multiple human posture estimation using openpose
Single or multiple human posture estimation using openpose
2022-07-25 15:10:00 【weixin_ forty-two million seven hundred and nine thousand five 】
In computer vision , Human posture estimation ( Key point detection ) It's a very common problem , In physical fitness 、 Action acquisition 、3D Fitting 、 Public opinion monitoring and other fields have broad application prospects , The detection method to be used in this paper is based on OpenPose Human posture estimation method based on .
One 、OpenPose brief introduction
OpenPose The human posture recognition project is Carnegie Mellon University (CMU) Based on Convolutional Neural Networks (CNN) And supervised learning (SL) And Caffe Open source library developed for the framework . It can realize human movement 、 Facial expressions 、 Finger movements, etc . Suitable for single or multiple people , It has very good robustness , It is the first real-time multi person two-dimensional attitude estimation application based on deep learning in the world .
Two 、 Realization principle
OpenPose The Internet VGGNet Before 10 Layer is used to create feature mapping for the input image , Then these features are input into two parallel branches of the convolution layer . The first branch predicts a set of confidence graphs (18 individual ), Each confidence graph represents a specific part of the human posture skeleton graph , The second branch predicts another set Part Affinity Field (PAF,38 individual ),PAF Indicates the degree of association between components . The picture below shows OpenPose Network model architecture diagram and flow chart of detection example image .

3、 ... and 、OpenPose Implementation code
import cv2
import time
import numpy as np
from random import randint
image1 = cv2.imread("znl112.jpg")# Add... According to your own path
protoFile = "pose_deploy_linevec.prototxt"
weightsFile = "pose_iter_440000.caffemodel"
nPoints = 18
# COCO Output Format
keypointsMapping = ['Nose', 'Neck', 'R-Sho', 'R-Elb', 'R-Wr', 'L-Sho', 'L-Elb', 'L-Wr', 'R-Hip',
'R-Knee', 'R-Ank', 'L-Hip', 'L-Knee', 'L-Ank', 'R-Eye', 'L-Eye', 'R-Ear', 'L-Ear']
POSE_PAIRS = [[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],
[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],
[1,0],[0,14],[14,16],[0,15],[15,17],[2,17],[5,16]]
# index of pafs correspoding to the POSE_PAIRS
# e.g for POSE_PAIR(1,2), the PAFs are located at indices (31,32) of output, Similarly, (1,5) -> (39,40) and so on.
mapIdx = [[31,32], [39,40], [33,34], [35,36], [41,42], [43,44],
[19,20], [21,22], [23,24], [25,26], [27,28], [29,30],
[47,48], [49,50], [53,54], [51,52], [55,56], [37,38], [45,46]]
colors = [[0,100,255], [0,100,255], [0,255,255], [0,100,255], [0,255,255], [0,100,255],
[0,255,0], [255,200,100], [255,0,255], [0,255,0], [255,200,100], [255,0,255],
[0,0,255], [255,0,0], [200,200,0], [255,0,0], [200,200,0], [0,0,0]]
def getKeypoints(probMap, threshold=0.1):
mapSmooth = cv2.GaussianBlur(probMap,(3,3),0,0)
mapMask = np.uint8(mapSmooth>threshold)
keypoints = []
#find the blobs
_, contours, _ = cv2.findContours(mapMask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#for each blob find the maxima
for cnt in contours:
blobMask = np.zeros(mapMask.shape)
blobMask = cv2.fillConvexPoly(blobMask, cnt, 1)
maskedProbMap = mapSmooth * blobMask
_, maxVal, _, maxLoc = cv2.minMaxLoc(maskedProbMap)
keypoints.append(maxLoc + (probMap[maxLoc[1], maxLoc[0]],))
return keypoints
# Find valid connections between the different joints of a all persons present
def getValidPairs(output):
valid_pairs = []
invalid_pairs = []
n_interp_samples = 10
paf_score_th = 0.1
conf_th = 0.7
# loop for every POSE_PAIR
for k in range(len(mapIdx)):
# A->B constitute a limb
pafA = output[0, mapIdx[k][0], :, :]
pafB = output[0, mapIdx[k][1], :, :]
pafA = cv2.resize(pafA,(frameWidth, frameHeight))
pafB = cv2.resize(pafB,(frameWidth, frameHeight))
# Find the keypoints for the first and second limb
candA = detected_keypoints[POSE_PAIRS[k][0]]
candB = detected_keypoints[POSE_PAIRS[k][1]]
nA = len(candA)
nB = len(candB)
# If keypoints for the joint-pair is detected
# check every joint in candA with every joint in candB
# Calculate the distance vector between the two joints
# Find the PAF values at a set of interpolated points between the joints
# Use the above formula to compute a score to mark the connection valid
if(nA != 0 and nB != 0):
valid_pair = np.zeros((0,3))
for i in range(nA):
max_j=-1
maxScore = -1
found = 0
for j in range(nB):
# Find d_ij
d_ij = np.subtract(candB[j][:2], candA[i][:2])
norm = np.linalg.norm(d_ij)
if norm:
d_ij = d_ij / norm
else:
continue
# Find p(u)
interp_coord = list(zip(np.linspace(candA[i][0], candB[j][0], num=n_interp_samples),
np.linspace(candA[i][1], candB[j][1], num=n_interp_samples)))
# Find L(p(u))
paf_interp = []
for k in range(len(interp_coord)):
paf_interp.append([pafA[int(round(interp_coord[k][1])), int(round(interp_coord[k][0]))],
pafB[int(round(interp_coord[k][1])), int(round(interp_coord[k][0]))] ])
# Find E
paf_scores = np.dot(paf_interp, d_ij)
avg_paf_score = sum(paf_scores)/len(paf_scores)
# Check if the connection is valid
# If the fraction of interpolated vectors aligned with PAF is higher then threshold -> Valid Pair
if(len(np.where(paf_scores>paf_score_th)[0])/n_interp_samples)>conf_th:
if avg_paf_score > maxScore:
max_j = j
maxScore = avg_paf_score
found = 1
# Append the connection to the list
if found:
valid_pair = np.append(valid_pair, [[candA[i][3], candB[max_j][3], maxScore]], axis=0)
# Append the detected connections to the global list
valid_pairs.append(valid_pair)
else: # If no keypoints are detected
#print("No Connection : k = {}".format(k))
invalid_pairs.append(k)
valid_pairs.append([])
return valid_pairs, invalid_pairs
# This function creates a list of keypoints belonging to each person
# For each detected valid pair, it assigns the joint(s) to a person
def getPersonwiseKeypoints(valid_pairs, invalid_pairs):
# the last number in each row is the overall score
personwiseKeypoints = -1 * np.ones((0, 19))
for k in range(len(mapIdx)):
if k not in invalid_pairs:
partAs = valid_pairs[k][:,0]
partBs = valid_pairs[k][:,1]
indexA, indexB = np.array(POSE_PAIRS[k])
for i in range(len(valid_pairs[k])):
found = 0
person_idx = -1
for j in range(len(personwiseKeypoints)):
if personwiseKeypoints[j][indexA] == partAs[i]:
person_idx = j
found = 1
break
if found:
personwiseKeypoints[person_idx][indexB] = partBs[i]
personwiseKeypoints[person_idx][-1] += keypoints_list[partBs[i].astype(int),2]+valid_pairs[k][i][2]
# if find no partA in the subset, create a new subset
elif not found and k < 17:
row = -1 * np.ones(19)
row[indexA] = partAs[i]
row[indexB] = partBs[i]
# add the keypoint_scores for the two keypoints and the paf_score
row[-1] = sum(keypoints_list[valid_pairs[k][i,:2].astype(int),2])+valid_pairs[k][i][2]
personwiseKeypoints = np.vstack([personwiseKeypoints,row])
return personwiseKeypoints
frameWidth = image1.shape[1]
frameHeight = image1.shape[0]
t = time.time()
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
# Fix the input Height and get the width according to the Aspect Ratio
inHeight = 368
inWidth = int((inHeight/frameHeight)*frameWidth)
inpBlob = cv2.dnn.blobFromImage(image1,1.0/255,(inWidth,inHeight),(0,0,0),swapRB=False,crop=False)
net.setInput(inpBlob)
output = net.forward()
print("Time Taken in forward pass = {}".format(time.time() - t))
detected_keypoints = []
keypoints_list = np.zeros((0,3))
keypoint_id = 0
threshold = 0.1
for part in range(nPoints):
probMap = output[0,part,:,:]
probMap = cv2.resize(probMap, (image1.shape[1], image1.shape[0]))
keypoints = getKeypoints(probMap, threshold)
#print("Keypoints - {} : {}".format(keypointsMapping[part], keypoints))
if keypointsMapping[part]=='Nose':
print(len(keypoints))
keypoints_with_id = []
for i in range(len(keypoints)):
keypoints_with_id.append(keypoints[i] + (keypoint_id,))
keypoints_list = np.vstack([keypoints_list, keypoints[i]])
keypoint_id += 1
detected_keypoints.append(keypoints_with_id)
#print(len(keypoints))
frameClone = image1.copy()
for i in range(nPoints):
for j in range(len(detected_keypoints[i])):
cv2.circle(frameClone, detected_keypoints[i][j][0:2], 5, colors[i], -1, cv2.LINE_AA)
#cv2.imshow("Keypoints",frameClone)
valid_pairs, invalid_pairs = getValidPairs(output)
personwiseKeypoints = getPersonwiseKeypoints(valid_pairs, invalid_pairs)
for i in range(17):
for n in range(len(personwiseKeypoints)):
index = personwiseKeypoints[n][np.array(POSE_PAIRS[i])]
if -1 in index:
continue
B = np.int32(keypoints_list[index.astype(int), 0])
A = np.int32(keypoints_list[index.astype(int), 1])
cv2.line(frameClone, (B[0], A[0]), (B[1], A[1]), colors[i], 3, cv2.LINE_AA)
cv2.imshow("Detected Pose",frameClone)
cv2.waitKey(0)
Find a single test picture , The test results are as follows :
If you want to show the number of people detected in the running results , You can choose one or several key points in the human body as the basis for judgment , Readers can adjust according to their own situation , In this paper, the detection of human nose is used (Nose) As the basis for judging the number of people , Its running time and the number of people detected are as follows :
Find three different pictures containing multiple characters to test , The number of people detected are 2,2,5, The running results are as follows :
picture 1

picture 2

picture 3

That's all of the article , If this article helps you , You can give me a compliment , Add a focus on , thank you !
边栏推荐
- Stored procedure bias of SQL to LINQ
- 打开虚拟机时出现VMware Workstation 未能启动 VMware Authorization Service
- Yarn: the file yarn.ps1 cannot be loaded because running scripts is prohibited on this system.
- Share a department design method that avoids recursion
- ice 100G 网卡分片报文 hash 问题
- Introduction to raspberry Pie: initial settings of raspberry pie
- 6月产品升级观察站
- [C topic] Li Kou 88. merge two ordered arrays
- 35 quick format code
- Add the jar package under lib directory to the project in idea
猜你喜欢

流程控制(上)

【JS高级】js之正则相关函数以及正则对象_02

Melody + realsense d435i configuration and error resolution

41 picture background synthesis - colorful navigation map

IP address classification, which determines whether a network segment is a subnet supernetwork

pl/sql 创建并执行oralce存储过程,并返回结果集

Splice a field of the list set into a single string

oracle_ 12505 error resolution
[Android] recyclerview caching mechanism, is it really difficult to understand? What level of cache is it?

Realsense ROS installation configuration introduction and problem solving
随机推荐
"Ask every day" what is volatile
js URLEncode函数
Scala110-combineByKey
System.AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
防抖(debounce)和节流(throttle)
[C题目]力扣88. 合并两个有序数组
Visual Studio 2022 查看类关系图
密码强度验证示例
6月产品升级观察站
pl/sql 创建并执行oralce存储过程,并返回结果集
ice 100G 网卡分片报文 hash 问题
"Ask every day" briefly talk about JMM / talk about your understanding of JMM
44 Sina navigation, Xiaomi sidebar exercise
[C topic] force buckle 876. Intermediate node of linked list
Debounce and throttle
npm的nexus私服 E401 E500错误处理记录
瀑布流布局
Melody + realsense d435i configuration and error resolution
Leetcode combination sum + pruning
MeanShift聚类-01原理分析