序
目的:最近在做基于图像的驾驶员疲劳检测系统项目,其中行为检测包含驾驶员打电话和抽烟的危险行为,基于图像用之前的Dlib68特征点和opencv肤色和动态追踪图像处理已经远远达不到理想标准,我们需要获取脸部和手部关键点信息;为了精确识别打电话和抽烟或者是喝水等动作,这里引入了机器视觉中一经典开源模型——Openpose(人体姿态识别模型)。
Openpose简介
正文
(1)配置Openpose环境
Windows10 + python3.7 + anaconda3 + jupyter5.6.0
可以按步骤配置,也可以直接下载训练好的模型
解压,进入..\openpose-master\models目录,双击运行getModels.bat
等待加载模型pose_iter_584000.caffemodel:
等待时间较长,如中途中断,重新双击运行getModels.bat即可,
完整加载模型大小:100M,
保存位置:..\openpose-master\models\pose\body_25\pose_iter_584000.caffemodel
跑了一天完全加载5个模型如图,openpose总大小800M,编译真的太心寒了,这里快速下载入口。
OpenPose 人体姿态模型下载路径:
(2)主要模型介绍
目录
openpose分别检测:人脸、人手、人姿态(又分为三种数据集,mpi为较小的数据集)
一个简单地demo:Windows10 + python3.7 + anaconda3 + jupyter5.6.0
import cv2
import time
import numpy as np
import matplotlib.pyplot as plt
import os
# Load a Caffe Model
if not os.path.isdir('model'):
os.mkdir("model")
protoFile = "D:/myworkspace/JupyterNotebook/openpose/openpose-master/models/pose/mpi/pose_deploy_linevec_faster_4_stages.prototxt"
weightsFile = "D:/myworkspace/JupyterNotebook/openpose/openpose-master/models/pose/mpi/pose_iter_160000.caffemodel"
# Specify number of points in the model
nPoints = 15
POSE_PAIRS = [[0,1], [1,2], [2,3], [3,4], [1,5], [5,6], [6,7], [1,14], [14,8], [8,9], [9,10], [14,11], [11,12], [12,13] ]
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
# Read Image
im = cv2.imread("D:/myworkspace/JupyterNotebook/openpose/tf-pose-estimation-master/images/apink1.jpg")
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
inWidth = im.shape[1]
inHeight = im.shape[0]
# Convert image to blob
netInputSize = (368, 368)
inpBlob = cv2.dnn.blobFromImage(im, 1.0 / 255, netInputSize, (0, 0, 0), swapRB=True, crop=False)
net.setInput(inpBlob)
# Run Inference (forward pass)
output = net.forward()
# Display probability maps
plt.figure(figsize=(20,10))
plt.title('Probability Maps of Keypoints')
for i in range(nPoints):
probMap = output[0, i, :, :]
displayMap = cv2.resize(probMap, (inWidth, inHeight), cv2.INTER_LINEAR)
plt.subplot(3, 5, i+1); plt.axis('off'); plt.imshow(displayMap, cmap='jet')
# Extract points
# X and Y Scale
scaleX = float(inWidth) / output.shape[3]
scaleY = float(inHeight) / output.shape[2]
# Empty list to store the detected keypoints
points = []
# Confidence treshold
threshold = 0.1
for i in range(nPoints):
# Obtain probability map
probMap = output[0, i, :, :]
# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
# Scale the point to fit on the original image
x = scaleX * point[0]
y = scaleY * point[1]
if prob > threshold :
# Add the point to the list if the probability is greater than the threshold
points.append((int(x), int(y)))
else :
points.append(None)
# Display Points & Skeleton
imPoints = im.copy()
imSkeleton = im.copy()
# Draw points
for i, p in enumerate(points):
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)
# Draw skeleton
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.title('Displaying Points')
plt.subplot(122); plt.axis('off'); plt.imshow(imSkeleton);
#plt.title('Displaying Skeleton')
plt.show()1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
运行效果:
标出了15个人体姿态特征点
mpi15个关键点参考说明:
(3)主要模型参考图
# Body25: 25 points
# COCO: 18 points
# MPI: 15 points1
2
3
左:BODY_25, 右:COCO
Face
Hand
(4)人体姿态各模型检测
#!/usr/bin/python3
#!--*-- coding: utf-8 --*--
from __future__ import division
import cv2
import time
import numpy as np
import matplotlib.pyplot as plt
import os
class general_pose_model(object):
def __init__(self, modelpath, mode="BODY25"):
# 指定采用的模型
# Body25: 25 points
# COCO