Merge tag '3.4.1-cvsdk' into 3.4
[platform/upstream/opencv.git] / samples / dnn / openpose.py
1 # To use Inference Engine backend, specify location of plugins:
2 # export LD_LIBRARY_PATH=/opt/intel/deeplearning_deploymenttoolkit/deployment_tools/external/mklml_lnx/lib:$LD_LIBRARY_PATH
3 import cv2 as cv
4 import numpy as np
5 import argparse
6
7 parser = argparse.ArgumentParser(
8         description='This script is used to demonstrate OpenPose human pose estimation network '
9                     'from https://github.com/CMU-Perceptual-Computing-Lab/openpose project using OpenCV. '
10                     'The sample and model are simplified and could be used for a single person on the frame.')
11 parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
12 parser.add_argument('--proto', help='Path to .prototxt')
13 parser.add_argument('--model', help='Path to .caffemodel')
14 parser.add_argument('--dataset', help='Specify what kind of model was trained. '
15                                       'It could be (COCO, MPI) depends on dataset.')
16 parser.add_argument('--thr', default=0.1, type=float, help='Threshold value for pose parts heat map')
17 parser.add_argument('--width', default=368, type=int, help='Resize input to specific width.')
18 parser.add_argument('--height', default=368, type=int, help='Resize input to specific height.')
19 parser.add_argument('--inf_engine', action='store_true',
20                     help='Enable Intel Inference Engine computational backend. '
21                          'Check that plugins folder is in LD_LIBRARY_PATH environment variable')
22
23 args = parser.parse_args()
24
25 if args.dataset == 'COCO':
26     BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
27                    "LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
28                    "RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14,
29                    "LEye": 15, "REar": 16, "LEar": 17, "Background": 18 }
30
31     POSE_PAIRS = [ ["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"],
32                    ["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"],
33                    ["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"],
34                    ["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"],
35                    ["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"] ]
36 else:
37     assert(args.dataset == 'MPI')
38     BODY_PARTS = { "Head": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
39                    "LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
40                    "RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "Chest": 14,
41                    "Background": 15 }
42
43     POSE_PAIRS = [ ["Head", "Neck"], ["Neck", "RShoulder"], ["RShoulder", "RElbow"],
44                    ["RElbow", "RWrist"], ["Neck", "LShoulder"], ["LShoulder", "LElbow"],
45                    ["LElbow", "LWrist"], ["Neck", "Chest"], ["Chest", "RHip"], ["RHip", "RKnee"],
46                    ["RKnee", "RAnkle"], ["Chest", "LHip"], ["LHip", "LKnee"], ["LKnee", "LAnkle"] ]
47
48 inWidth = args.width
49 inHeight = args.height
50
51 net = cv.dnn.readNetFromCaffe(args.proto, args.model)
52 if args.inf_engine:
53     net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
54
55 cap = cv.VideoCapture(args.input if args.input else 0)
56
57 while cv.waitKey(1) < 0:
58     hasFrame, frame = cap.read()
59     if not hasFrame:
60         cv.waitKey()
61         break
62
63     frameWidth = frame.shape[1]
64     frameHeight = frame.shape[0]
65     inp = cv.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
66                               (0, 0, 0), swapRB=False, crop=False)
67     net.setInput(inp)
68     out = net.forward()
69
70     assert(len(BODY_PARTS) == out.shape[1])
71
72     points = []
73     for i in range(len(BODY_PARTS)):
74         # Slice heatmap of corresponging body's part.
75         heatMap = out[0, i, :, :]
76
77         # Originally, we try to find all the local maximums. To simplify a sample
78         # we just find a global one. However only a single pose at the same time
79         # could be detected this way.
80         _, conf, _, point = cv.minMaxLoc(heatMap)
81         x = (frameWidth * point[0]) / out.shape[3]
82         y = (frameHeight * point[1]) / out.shape[2]
83
84         # Add a point if it's confidence is higher than threshold.
85         points.append((int(x), int(y)) if conf > args.thr else None)
86
87     for pair in POSE_PAIRS:
88         partFrom = pair[0]
89         partTo = pair[1]
90         assert(partFrom in BODY_PARTS)
91         assert(partTo in BODY_PARTS)
92
93         idFrom = BODY_PARTS[partFrom]
94         idTo = BODY_PARTS[partTo]
95
96         if points[idFrom] and points[idTo]:
97             cv.line(frame, points[idFrom], points[idTo], (0, 255, 0), 3)
98             cv.ellipse(frame, points[idFrom], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
99             cv.ellipse(frame, points[idTo], (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
100
101     t, _ = net.getPerfProfile()
102     freq = cv.getTickFrequency() / 1000
103     cv.putText(frame, '%.2fms' % (t / freq), (10, 20), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
104
105     cv.imshow('OpenPose using OpenCV', frame)