source:
开源地址:https://github.com/misbah4064/hand_pose_detection
模型下载:https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/models/getModels.sh
论坛资料 openpose使用 https://blog.csdn.net/qq_27158179/article/details/82717821
演示视频
代码
视频处理
import cv2
import time
import numpy as np
protoFile = "D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\hand\\pose_deploy.prototxt"
weightsFile = "D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\hand\\pose_iter_102000.caffemodel"
nPoints = 22
POSE_PAIRS = [ [0,1],[1,2],[2,3],[3,4],[0,5],[5,6],[6,7],[7,8],[0,9],[9,10],[10,11],[11,12],[0,13],[13,14],[14,15],[15,16],[0,17],[17,18],[18,19],[19,20] ]
threshold = 0.2
video_file = "D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\videoMine.mp4"
cap = cv2.VideoCapture(video_file)
hasFrame, frame = cap.read()
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]
aspect_ratio = frameWidth/frameHeight
inHeight = 368
inWidth = int(((aspect_ratio*inHeight)*8)//8)
vid_writer = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 15, (frame.shape[1],frame.shape[0]))
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
k = 0
while 1:
k+=1
t = time.time()
hasFrame, frame = cap.read()
frameCopy = np.copy(frame)
if not hasFrame:
cv2.waitKey()
break
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
(0, 0, 0), swapRB=False, crop=False)
net.setInput(inpBlob)
output = net.forward()
print("forward = {}".format(time.time() - t))
# Empty list to store the detected keypoints
points = []
for i in range(nPoints):
# confidence map of corresponding body's part.
probMap = output[0, i, :, :]
probMap = cv2.resize(probMap, (frameWidth, frameHeight))
# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
if prob > threshold :
cv2.circle(frameCopy, (int(point[0]), int(point[1])), 6, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
cv2.putText(frameCopy, "{}".format(i), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_SIMPLEX, .8, (0, 0, 255), 2, lineType=cv2.LINE_AA)
# Add the point to the list if the probability is greater than the threshold
points.append((int(point[0]), int(point[1])))
else :
points.append(None)
# Draw Skeleton
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]
if points[partA] and points[partB]:
cv2.line(frame, points[partA], points[partB], (0, 255, 255), 2, lineType=cv2.LINE_AA)
cv2.circle(frame, points[partA], 5, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
cv2.circle(frame, points[partB], 5, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
print("Time Taken for frame = {}".format(time.time() - t))
# cv2.putText(frame, "time taken = {:.2f} sec".format(time.time() - t), (50, 50), cv2.FONT_HERSHEY_COMPLEX, .8, (255, 50, 0), 2, lineType=cv2.LINE_AA)
# cv2.putText(frame, "Hand Pose using OpenCV", (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 50, 0), 2, lineType=cv2.LINE_AA)
cv2.imshow('Output-Skeleton', frame)
# cv2.imwrite("video_output/{:03d}.jpg".format(k), frame)
key = cv2.waitKey(1)
if key == 27:
break
print("total = {}".format(time.time() - t))
vid_writer.write(frame)
vid_writer.release()
图像处理
import cv2
import time
import numpy as np
#加载模型和图像
protoFile = "D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\hand\\pose_deploy.prototxt"
weightsFile = "D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\hand\\pose_iter_102000.caffemodel"
nPoints = 22
POSE_PAIRS = [ [0,1],[1,2],[2,3],[3,4],[0,5],[5,6],[6,7],[7,8],[0,9],[9,10],[10,11],[11,12],[0,13],[13,14],[14,15],[15,16],[0,17],[17,18],[18,19],[19,20] ]
threshold = 0.2
frame = cv2.imread("D:\\Data_documents\\ImageProcess\\MachineViewReport\\hand_pose_detection-master\\hand02.jpg")
net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile)
frameCopy = np.copy(frame)
frameWidth = frame.shape[1]
frameHeight = frame.shape[0]
aspect_ratio = frameWidth/frameHeight
inHeight = 368
inWidth = int(((aspect_ratio*inHeight)*8)//8)
#推断预测
inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),(0, 0, 0), swapRB=False, crop=False)#blobFromImage将图像转为blob
net.setInput(inpBlob)# 将图像输入到caffe网络中
output = net.forward()#输出前向传播的预测结果 实现网络推断
#显示检测
points = []
for i in range(nPoints):
# confidence map of corresponding body's part.
probMap = output[0, i, :, :]
probMap = cv2.resize(probMap, (frameWidth, frameHeight))
# Find global maxima of the probMap.
minVal, prob, minLoc, point = cv2.minMaxLoc(probMap)
if prob > threshold :
cv2.circle(frameCopy, (int(point[0]), int(point[1])), 8, (0, 255, 255), thickness=-1, lineType=cv2.FILLED)
cv2.putText(frameCopy, "{}".format(i), (int(point[0]), int(point[1])), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, lineType=cv2.LINE_AA)
# Add the point to the list if the probability is greater than the threshold
points.append((int(point[0]), int(point[1])))
else :
points.append(None)
cv2.imshow('Output-Keypoints', frameCopy)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('frame01.png', frameCopy)
#绘制骨骼
for pair in POSE_PAIRS:
partA = pair[0]
partB = pair[1]
if points[partA] and points[partB]:
cv2.line(frame, points[partA], points[partB], (0, 255, 255), 2)
cv2.circle(frame, points[partA], 8, (0, 0, 255), thickness=-1, lineType=cv2.FILLED)
cv2.imshow('Output-Skeleton', frame)
cv2.imwrite('frame02.png', frame)
cv2.waitKey(0)
cv2.destroyAllWindows()
CV函数
cv2.VideoCapture()
cap = cv2.VideoCapture(0)
VideoCapture()中参数是0,表示打开笔记本的内置摄像头。
cap = cv2.VideoCapture(“…/1.avi”)
VideoCapture(“…/1.avi”),表示参数是视频文件路径则打开视频
cap.read()
cap.read()按帧读取视频,ret,frame是获cap.read()方法的两个返回值。其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵
cv2.VideoWriter
VideoWriter(filename, fourcc, fps, frameSize[, isColor]) ->
- 第一个参数是要保存的文件的路径
- fourcc 指定编码器
- fps 要保存的视频的帧率
- frameSize 要保存的文件的画面尺寸
- isColor 指示是黑白画面还是彩色的画面
https://blog.csdn.net/briblue/article/details/87914421
CV机器学习函数
- cv2.dnn.readNetFromCaffe(prototxt, model)
用于进行SSD网络的caffe框架的加载
参数说明:prototxt表示caffe网络的结构文本,model表示已经训练好的参数结果
- t=delib.correlation_tracker()
使用delib生成单目标的追踪器
- delib.rectangle(int(box[0]), int(box[1]), int(box[2]), int(box[3]))
用于生成追踪器所需要的矩形框[(startX, startY), (endX, endY)]
- t.start_track(rgb, rect) # 初始化生成器的开始状态
- cv2.Writer(name, fourcc, (frame.shape[1], frame.shape[0]), True)
进行图片写入到视频里面
参数说明: name表示视频的名字,fourcc表示视频格式,frame.shape[1] 表示视频的长和宽,
- cv2.dnn.blobFromImage(frame, 0.007843, (w, h), 127.5)
对图像进行归一化操作(-1, 1),
参数说明:frame表示输入图片,0.007843表示需要乘的数,即1/127.5,(w, h)表示图像大小,127.5表示需要 减去的数
- net.SetInput(rgb)
表示将图片输入到caffe网络中
参数说明: rgb表示已经经过归一化的图片
- net.forward() 输出前向传播的预测结果
- oq = multiprocessing.Queue() 生成用于多进行传输过程中的线程
- p = multiprocessing.Process(target=start_track, args=(bb, label, rgb, iq, oq))