在计算机视觉中,人体姿态估计(关键点检测)是一个很常见的问题,在体育健身、动作采集、3D试衣、舆情监测等领域具有广阔的应用前景,本文要使用的检测方法就是基于OpenPose的人体姿态估计方法。

一、OpenPose简介

OpenPose人体姿态识别项目是美国卡耐基梅隆大学(CMU)基于卷积神经网络(CNN)和监督学习(SL)并以Caffe为框架开发的开源库。可以实现人体动作、面部表情、手指运动等姿态估计。适用于单人或者多人,具有非常好的鲁棒性,是世界上首个基于深度学习的实时多人二维姿态估计应用。

二、实现原理

OpenPose 网络VGGNet的前10层用于为输入图像创建特征映射,然后将这些特征输入到卷积层的两个并行分支中。第一个分支预测了一组置信图(18 个),每个置信图表示人体姿态骨架图的特定部件,第二个分支预测另外一组 Part Affinity Field (PAF,38个),PAF 表示部件之间的关联程度。下图展示的是OpenPose网络模型架构图和检测实例图像的流程图。

三、OpenPose实现代码

import cv2
import time
import numpy as np
from random import randintimage1 = cv2.imread("znl112.jpg")#根据自己的路径添加
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 maximafor 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 = 10paf_score_th = 0.1conf_th = 0.7# loop for every POSE_PAIRfor k in range(len(mapIdx)):# A->B constitute a limbpafA = 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 limbcandA = 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 validif(nA != 0 and nB != 0):valid_pair = np.zeros((0,3))for i in range(nA):max_j=-1maxScore = -1found = 0for j in range(nB):# Find d_ijd_ij = np.subtract(candB[j][:2], candA[i][:2])norm = np.linalg.norm(d_ij)if norm:d_ij = d_ij / normelse: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 Epaf_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 Pairif(len(np.where(paf_scores>paf_score_th)[0])/n_interp_samples)>conf_th:if avg_paf_score > maxScore:max_j = jmaxScore = avg_paf_scorefound = 1# Append the connection to the listif found:valid_pair = np.append(valid_pair, [[candA[i][3], candB[max_j][3], maxScore]], axis=0)# Append the detected connections to the global listvalid_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 scorepersonwiseKeypoints = -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 = 0person_idx = -1for j in range(len(personwiseKeypoints)):if personwiseKeypoints[j][indexA] == partAs[i]:person_idx = jfound = 1breakif 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 subsetelif 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_scorerow[-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 += 1detected_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:continueB = 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)

找一张单人的测试图片,测试效果如下:

如果想要在运行结果显示出检测到的人物数目,可以通过选择人体中的一个或者几个关键点作为判断依据,读者可根据自己的情况进行调整,在本文中使用检测到人体鼻子(Nose)的数量作为判断人数的依据,其运行时间和检测到的人数如下所示:

分别再找三张不同的包含多个人物图片进行测试,检测到的人数分别是2,2,5,运行结果如下所示:
图片1


图片2


图片3


以上就是文章的所有内容,如果本文对你有帮助,可以给我点个赞,加个关注,谢谢!

用OpenPose进行单个或多个人体姿态估计相关推荐

  1. Openpose+Tensorflow 这样实现人体姿态估计 | 代码干货

    作者 | 李秋键 出品 | AI科技大本营(ID:rgznai100) 人体姿态估计指从单个 RGB 图像中精确地估计出人体的位置以及检测骨骼关键点的位置.人体姿态估计是计算机视觉领域的研究热点,是诸 ...

  2. Python+OpenCV+OpenPose实现人体姿态估计(人体关键点检测)

    目录 1.人体姿态估计简介 2.人体姿态估计数据集 3.OpenPose库 4.实现原理 5.实现神经网络 6.实现代码 1.人体姿态估计简介 人体姿态估计(Human Posture Estimat ...

  3. CV之PoseEstimation:Pose Estimation人体姿态估计(AI识人,OpenPose+DeepCut+RMPE+Mask RCNN)的简介、案例应用之详细攻略

    CV之PoseEstimation:Pose Estimation人体姿态估计(AI识人,OpenPose+DeepCut+RMPE+Mask RCNN)的简介.案例应用之详细攻略 目录 Pose E ...

  4. OpenPose 升级,CMU提出首个单网络全人体姿态估计网络,速度大幅提高

    点击我爱计算机视觉标星,更快获取CVML新技术 昨天,曾经开源OpenPose的卡内基梅隆大学(CMU)公布了ICCV 2019 论文 Single-Network Whole-Body Pose E ...

  5. 人体姿态估计openpose学习与应用

    前言 2021年时,就有做人体姿态估计的想法,具体应用场景是想去把这个姿态估计与工厂操作工的动作结合起来,搭建一套能够监控和规范产线操作工装配动作的基于视觉的人体姿态估计系统.因为一系列的各种原因就搁 ...

  6. 3D视觉——3.人体姿态估计(Pose Estimation) 算法对比 即 效果展示——MediaPipe与OpenPose

    上一话 3D视觉--2.人体姿态估计(Pose Estimation)入门--OpenPose含安装.编译.使用(单帧.实时视频)https://blog.csdn.net/XiaoyYidiaodi ...

  7. OpenPose实现人体姿态估计(人体关键点检测)

    转载:Python+OpenCV+OpenPose实现人体姿态估计(人体关键点检测)_不脱发的程序猿-CSDN博客_python人体姿态识别

  8. 基于深度学习和传统算法的人体姿态估计,技术细节都讲清楚了

    作者 | 站长 pursueYfuture 来源 | AI专栏(ID: pursue-Y-future) 计算机视觉的一大研究热点是人体姿态估计,还有很多问题急需解决,比如遮挡,交互等等.在最近的CV ...

  9. 人体姿态估计(Human Pose Estimation)技巧方法汇总

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 作者:Poeroz https://zhuanlan.zhihu.com/p/10 ...

最新文章

  1. 顶级数据库管理系统的性能比较研究(论文翻译)
  2. 尽快卸载这两款恶意浏览器插件!已有近50万用户安装
  3. python能做什么项目好-python能做什么项目
  4. android的logcat详细用法
  5. 判断当前所使用python的版本和来源
  6. 《HTML5 2D游戏编程核心技术》——第1章,第1.3节特别功能
  7. Java常用类(2)--日期时间相关类Date、Calendar、LocalDateTime、Instant全面
  8. activity 、window与view的关系 (上)
  9. 58天 -算法 openJudge百炼 2787-凑24 - 递归
  10. form表单的get和post传值问题
  11. php中file文件操作函数readfile fread fgets fgetc以及不需要加fopen的file_get_contents file_put_contents file()
  12. 39页第6题 求贷款的金额
  13. ppt转图片php,如何将ppt转换成图片格式
  14. 对硬盘进行分区时,GPT和MBR有什么区别?
  15. 台式计算机可以发射无线网络,台式机怎么样发射无线信号
  16. JavaSE经典编程题
  17. 【历史上的今天】11 月 16 日:RISC-V 掌门人出生;微软发布 Windows CE;电子管问世
  18. 新零售mysql设计 订单表 订单详情表
  19. 账单分期和最低还款之间的差距你绝对想不到,以广发卡为例子,看看自动分期的好处。
  20. 在线教学视频课程如何防止学员挂机?

热门文章

  1. 厦门感芯科技MC3172(1):介绍和环境搭建
  2. Oracle Forms Error Messages 列表03
  3. cfdpost教程_CFD-Post知识论坛_CFD-Post安装视频_CFD-Post实例教程-仿真秀
  4. 在Microsoft Teams中,以一个已经存在的Team作为模板创建Team
  5. mysql所有任务为灰色_MySQL权限体系任务事理
  6. AI神器竟然能代替PS抠图了
  7. 目前市面上最受欢迎共享产品有哪些
  8. 保存系统的操作日志,通过swagger注解获取请求描述(通用版本)
  9. 莎士比亚(50条名句)内容大全 - 谁料过去的繁华,化作今朝的泥土 - 作者 第7页
  10. MySQL中的事务回滚机制