openpose人体姿态估计

您所在的位置:网站首页 卡耐基梅隆 openpose人体姿态估计

openpose人体姿态估计

#openpose人体姿态估计| 来源: 网络整理| 查看: 265

参考博客:Openpose驾驶员危险驾驶检测(抽烟打电话)

人体姿态识别模型—openpose

OpenPose人体姿态识别项目是美国卡耐基梅隆大学(CMU)基于卷积神经网络和监督学习并以caffe为框架开发的开源库。可以实现人体动作、面部表情、手指运动等姿态估计。适用于单人和多人,具有极好的鲁棒性。是世界上首个基于深度学习的实时多人二维姿态估计应用。 参考:Github开源人体姿态识别项目OpenPose中文文档 OpenPose项目Github链接:https://github.com/CMU-Perceptual-Computing-Lab/openpose

openpose模型有:手,脸,人体姿态。如图: 在这里插入图片描述

CoCo人体18点检测-图片 import cv2 import matplotlib.pyplot as plt #配置文件 protoFile = './models/pose/coco/pose_deploy_linevec.prototxt' weightsfile = './models/pose/coco/pose_iter_440000.caffemodel' npoints = 18 POSE_PAIRS = [[1,0],[1,2],[1,5],[2,3],[3,4],[5,6],[6,7],[1,8],[8,9],[9,10],[1,11],[11,12],[12,13],[0,14],[0,15],[14,16],[15,17]] #加载网络 net = cv2.dnn.readNetFromCaffe(protoFile,weightsfile) #读取图片 im = cv2.imread('kai.jpg') #(1440*1080) im = cv2.cvtColor(im,cv2.COLOR_BGR2RGB) inHeight = im.shape[0] #1440 inWidth = im.shape[1] #1080 netInputsize = (368,368) #转为inpBlob格式 inpBlob = cv2.dnn.blobFromImage(im,1.0/255,netInputsize,(0,0,0),swapRB=True,crop=False) #归一化后的图片最为输入传入net网络,然后输出 net.setInput(inpBlob) output = net.forward() #1*57*46*46 # plt.figure(figsize=(20,10)) # for i in range(npoints): # probMap = output[0,i,:,:] #把18个output[2][3]输出出来 probMap.shape(46*46) # displayMap = cv2.resize(probMap,(inWidth,inHeight),cv2.INTER_LINEAR) #1440*1080 # plt.subplot(3,6,i+1);plt.axis('on'); # plt.imshow(displayMap,cmap='jet') # plt.show() scaleX = float(inWidth) / output.shape[3] #float(1080)/64 = 23.47826086956522 scaleY = float(inHeight)/ output.shape[2] #float(1440)/64 = 31.304347826086957 points = [] threshold = 0.1 for i in range(npoints): probMap = output[0,i,:,:] #shape(46*46) minVal,prob,minLoc,point =cv2.minMaxLoc(probMap) x = scaleX * point[0] y = scaleY * point[1] if prob > threshold: points.append((int(x),int(y))) else: points.append(None) #points[]最后为18个关键点的坐标 #[(516, 313), (516, 438), (399, 438), (375, 626), (352, 751), (610, 438), (633, 594), (657, 751), (446, 751), # (446, 970), (446, 1158), (563, 782), (540, 1001), (540, 1064), (493, 281), (540, 281), (446, 313), (563, 313)] imPoints = im.copy() imSkeleton = im.copy() for i,p in enumerate(points): #enumerate把points的值前面带上索引i cv2.circle(imPoints,p,8,(255,255,0),thickness=1,lineType=cv2.FILLED) cv2.putText(imPoints,'{}'.format(i),p,cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2,lineType=cv2.LINE_AA) for pair in POSE_PAIRS: partA = pair[0] partB = pair[1] #if points[partA] and points[partB]: cv2.line(imSkeleton,points[partA],points[partB],(255, 255,0),2) cv2.circle(imSkeleton, points[partA],8,(255,0,0),thickness=-1, lineType=cv2.FILLED) plt.figure(figsize=(20,10)) plt.subplot(121) plt.axis('off');plt.imshow(imPoints) plt.subplot(122) plt.axis('off');plt.imshow(imSkeleton) plt.show()

检测结果: 18点姿态检测

CoCo人体18点检测-视频

把上述代码改为由opencv捕获摄像头,实时进行人体姿态检测

import cv2 def detect(img): protoFile = './models/pose/coco/pose_deploy_linevec.prototxt' weightsfile = './models/pose/coco/pose_iter_440000.caffemodel' npoints = 18 POSE_PAIRS = [[1, 0], [1, 2], [1, 5], [2, 3], [3, 4], [5, 6], [6, 7], [1, 8], [8, 9], [9, 10], [1, 11], [11, 12], [12, 13], [0, 14], [0, 15], [14, 16], [15, 17]] net = cv2.dnn.readNetFromCaffe(protoFile, weightsfile) inHeight = img.shape[0] # 1440 inWidth = img.shape[1] # 1080 netInputsize = (368, 368) inpBlob = cv2.dnn.blobFromImage(img, 1.0 / 255, netInputsize, (0, 0, 0), swapRB=True, crop=False) net.setInput(inpBlob) output = net.forward() scaleX = float(inWidth) / output.shape[3] scaleY = float(inHeight) / output.shape[2] points = [] threshold = 0.1 for i in range(npoints): probMap = output[0, i, :, :] # shape(46*46) minVal, prob, minLoc, point = cv2.minMaxLoc(probMap) x = scaleX * point[0] y = scaleY * point[1] if prob > threshold: points.append((int(x), int(y))) else: points.append(None) for i, p in enumerate(points): # enumerate把points的值前面带上索引i cv2.circle(img, p, 8, (255, 255, 0), thickness=1, lineType=cv2.FILLED) cv2.putText(img, '{}'.format(i), p, cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, lineType=cv2.LINE_AA) cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() detect(frame) cv2.imshow('frame',frame) if cv2.waitKey(1) & 0xFF == ord('q'): # 按‘q’退出 break

检测结果: 在这里插入图片描述

距离计算

为了检测驾驶员是否存在吸烟和打电话等危险行为,可以计算人体特定关键点之间的距离。 吸烟:右手到鼻子的距离或者左手到鼻子的距离。 打电话:右手到右耳的距离或者左手到左耳的距离。

import math def __distance(A,B): if A is None or B is None: return 0 else: return math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2) distance0 = __distance(points[0],points[4]) #右手到鼻子距离 distance1 = __distance(points[0],points[7]) #左手到鼻子距离 distance2 = __distance(points[4],points[16]) #右手到右耳距离 distance3 = __distance(points[7],points[17]) #左手到左耳距离 print('右手到鼻子距离:',distance0,'左手到鼻子距离:',distance1) print('右手到右耳距离:',distance2,'左手到左耳距离:',distance3

计算结果

右手到鼻子距离: 467.6964827748868 左手到鼻子距离: 460.135849505339 右手到右耳距离: 447.97321348491363 左手到左耳距离: 447.97321348491363


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3