Wanli
commited on
Commit
·
a9555be
1
Parent(s):
5142c7c
Let mp_palmdet support multiple palms detection (#85)
Browse files- demo.py +41 -35
- mp_palmdet.py +20 -10
demo.py
CHANGED
|
@@ -36,23 +36,37 @@ parser.add_argument('--save', '-s', type=str, default=False, help='Set true to s
|
|
| 36 |
parser.add_argument('--vis', '-v', type=str2bool, default=True, help='Set true to open a window for result visualization. This flag is invalid when using camera.')
|
| 37 |
args = parser.parse_args()
|
| 38 |
|
| 39 |
-
def visualize(image,
|
| 40 |
output = image.copy()
|
| 41 |
|
| 42 |
if fps is not None:
|
| 43 |
cv.putText(output, 'FPS: {:.2f}'.format(fps), (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
return output
|
| 58 |
|
|
@@ -69,30 +83,23 @@ if __name__ == '__main__':
|
|
| 69 |
image = cv.imread(args.input)
|
| 70 |
|
| 71 |
# Inference
|
| 72 |
-
|
| 73 |
-
if
|
| 74 |
print('Hand not detected')
|
| 75 |
-
else:
|
| 76 |
-
# Print results
|
| 77 |
-
print('score: {:.2f}'.format(score))
|
| 78 |
-
print('palm box: {}'.format(palm_box))
|
| 79 |
-
print('palm_landmarks: ')
|
| 80 |
-
for plm in enumerate(palm_landmarks):
|
| 81 |
-
print('\t{}'.format(plm))
|
| 82 |
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
else: # Omit input to call default camera
|
| 97 |
deviceId = 0
|
| 98 |
cap = cv.VideoCapture(deviceId)
|
|
@@ -106,12 +113,11 @@ if __name__ == '__main__':
|
|
| 106 |
|
| 107 |
# Inference
|
| 108 |
tm.start()
|
| 109 |
-
|
| 110 |
tm.stop()
|
| 111 |
|
| 112 |
# Draw results on the input image
|
| 113 |
-
|
| 114 |
-
frame = visualize(frame, score, palm_box, palm_landmarks, fps=tm.getFPS())
|
| 115 |
|
| 116 |
# Visualize results in a new Window
|
| 117 |
cv.imshow('MPPalmDet Demo', frame)
|
|
|
|
| 36 |
parser.add_argument('--vis', '-v', type=str2bool, default=True, help='Set true to open a window for result visualization. This flag is invalid when using camera.')
|
| 37 |
args = parser.parse_args()
|
| 38 |
|
| 39 |
+
def visualize(image, results, print_results=False, fps=None):
|
| 40 |
output = image.copy()
|
| 41 |
|
| 42 |
if fps is not None:
|
| 43 |
cv.putText(output, 'FPS: {:.2f}'.format(fps), (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))
|
| 44 |
|
| 45 |
+
for idx, palm in enumerate(results):
|
| 46 |
+
score = palm[-1]
|
| 47 |
+
palm_box = palm[0:4]
|
| 48 |
+
palm_landmarks = palm[4:-1].reshape(7, 2)
|
| 49 |
|
| 50 |
+
# put score
|
| 51 |
+
palm_box = palm_box.astype(np.int32)
|
| 52 |
+
cv.putText(output, '{:.4f}'.format(score), (palm_box[0], palm_box[1]+12), cv.FONT_HERSHEY_DUPLEX, 0.5, (0, 255, 0))
|
| 53 |
|
| 54 |
+
# draw box
|
| 55 |
+
cv.rectangle(output, (palm_box[0], palm_box[1]), (palm_box[2], palm_box[3]), (0, 255, 0), 2)
|
| 56 |
+
|
| 57 |
+
# draw points
|
| 58 |
+
palm_landmarks = palm_landmarks.astype(np.int32)
|
| 59 |
+
for p in palm_landmarks:
|
| 60 |
+
cv.circle(output, p, 2, (0, 0, 255), 2)
|
| 61 |
+
|
| 62 |
+
# Print results
|
| 63 |
+
if print_results:
|
| 64 |
+
print('-----------palm {}-----------'.format(idx + 1))
|
| 65 |
+
print('score: {:.2f}'.format(score))
|
| 66 |
+
print('palm box: {}'.format(palm_box))
|
| 67 |
+
print('palm landmarks: ')
|
| 68 |
+
for plm in palm_landmarks:
|
| 69 |
+
print('\t{}'.format(plm))
|
| 70 |
|
| 71 |
return output
|
| 72 |
|
|
|
|
| 83 |
image = cv.imread(args.input)
|
| 84 |
|
| 85 |
# Inference
|
| 86 |
+
results = model.infer(image)
|
| 87 |
+
if len(results) == 0:
|
| 88 |
print('Hand not detected')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
+
# Draw results on the input image
|
| 91 |
+
image = visualize(image, results, print_results=True)
|
| 92 |
+
|
| 93 |
+
# Save results if save is true
|
| 94 |
+
if args.save:
|
| 95 |
+
print('Resutls saved to result.jpg\n')
|
| 96 |
+
cv.imwrite('result.jpg', image)
|
| 97 |
+
|
| 98 |
+
# Visualize results in a new window
|
| 99 |
+
if args.vis:
|
| 100 |
+
cv.namedWindow(args.input, cv.WINDOW_AUTOSIZE)
|
| 101 |
+
cv.imshow(args.input, image)
|
| 102 |
+
cv.waitKey(0)
|
| 103 |
else: # Omit input to call default camera
|
| 104 |
deviceId = 0
|
| 105 |
cap = cv.VideoCapture(deviceId)
|
|
|
|
| 113 |
|
| 114 |
# Inference
|
| 115 |
tm.start()
|
| 116 |
+
results = model.infer(frame)
|
| 117 |
tm.stop()
|
| 118 |
|
| 119 |
# Draw results on the input image
|
| 120 |
+
frame = visualize(frame, results, fps=tm.getFPS())
|
|
|
|
| 121 |
|
| 122 |
# Visualize results in a new Window
|
| 123 |
cv.imshow('MPPalmDet Demo', frame)
|
mp_palmdet.py
CHANGED
|
@@ -2,10 +2,11 @@ import numpy as np
|
|
| 2 |
import cv2 as cv
|
| 3 |
|
| 4 |
class MPPalmDet:
|
| 5 |
-
def __init__(self, modelPath, nmsThreshold=0.3, scoreThreshold=0.5, backendId=0, targetId=0):
|
| 6 |
self.model_path = modelPath
|
| 7 |
self.nms_threshold = nmsThreshold
|
| 8 |
self.score_threshold = scoreThreshold
|
|
|
|
| 9 |
self.backend_id = backendId
|
| 10 |
self.target_id = targetId
|
| 11 |
|
|
@@ -48,9 +49,9 @@ class MPPalmDet:
|
|
| 48 |
output_blob = self.model.forward()
|
| 49 |
|
| 50 |
# Postprocess
|
| 51 |
-
|
| 52 |
|
| 53 |
-
return
|
| 54 |
|
| 55 |
def _postprocess(self, output_blob, original_shape):
|
| 56 |
score = output_blob[0, :, 0]
|
|
@@ -68,17 +69,26 @@ class MPPalmDet:
|
|
| 68 |
xy2 = (cxy_delta + wh_delta / 2 + self.anchors[:, :2]) * original_shape
|
| 69 |
boxes = np.concatenate([xy1, xy2], axis=1)
|
| 70 |
# NMS
|
| 71 |
-
keep_idx = cv.dnn.NMSBoxes(boxes, score, self.score_threshold, self.nms_threshold, top_k=
|
| 72 |
if len(keep_idx) == 0:
|
| 73 |
-
return
|
| 74 |
-
selected_score = score[keep_idx]
|
| 75 |
-
selected_box = boxes[keep_idx]
|
| 76 |
|
| 77 |
# get landmarks
|
| 78 |
-
selected_landmarks = landmark_delta[keep_idx].reshape(7, 2)
|
| 79 |
-
selected_landmarks =
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
def _load_anchors(self):
|
| 84 |
return np.array([[0.015625, 0.015625],
|
|
|
|
| 2 |
import cv2 as cv
|
| 3 |
|
| 4 |
class MPPalmDet:
|
| 5 |
+
def __init__(self, modelPath, nmsThreshold=0.3, scoreThreshold=0.5, topK=5000, backendId=0, targetId=0):
|
| 6 |
self.model_path = modelPath
|
| 7 |
self.nms_threshold = nmsThreshold
|
| 8 |
self.score_threshold = scoreThreshold
|
| 9 |
+
self.topK = topK
|
| 10 |
self.backend_id = backendId
|
| 11 |
self.target_id = targetId
|
| 12 |
|
|
|
|
| 49 |
output_blob = self.model.forward()
|
| 50 |
|
| 51 |
# Postprocess
|
| 52 |
+
results = self._postprocess(output_blob, np.array([w, h]))
|
| 53 |
|
| 54 |
+
return results
|
| 55 |
|
| 56 |
def _postprocess(self, output_blob, original_shape):
|
| 57 |
score = output_blob[0, :, 0]
|
|
|
|
| 69 |
xy2 = (cxy_delta + wh_delta / 2 + self.anchors[:, :2]) * original_shape
|
| 70 |
boxes = np.concatenate([xy1, xy2], axis=1)
|
| 71 |
# NMS
|
| 72 |
+
keep_idx = cv.dnn.NMSBoxes(boxes, score, self.score_threshold, self.nms_threshold, top_k=self.topK)
|
| 73 |
if len(keep_idx) == 0:
|
| 74 |
+
return np.empty(shape=(0, 19))
|
| 75 |
+
selected_score = score[keep_idx]
|
| 76 |
+
selected_box = boxes[keep_idx]
|
| 77 |
|
| 78 |
# get landmarks
|
| 79 |
+
selected_landmarks = landmark_delta[keep_idx].reshape(-1, 7, 2)
|
| 80 |
+
selected_landmarks = selected_landmarks / self.input_size
|
| 81 |
+
selected_anchors = self.anchors[keep_idx]
|
| 82 |
+
for idx, landmark in enumerate(selected_landmarks):
|
| 83 |
+
landmark += selected_anchors[idx]
|
| 84 |
+
selected_landmarks *= original_shape
|
| 85 |
|
| 86 |
+
# [
|
| 87 |
+
# [bbox_coords, landmarks_coords, score]
|
| 88 |
+
# ...
|
| 89 |
+
# [bbox_coords, landmarks_coords, score]
|
| 90 |
+
# ]
|
| 91 |
+
return np.c_[selected_box.reshape(-1, 4), selected_landmarks.reshape(-1, 14), selected_score.reshape(-1, 1)]
|
| 92 |
|
| 93 |
def _load_anchors(self):
|
| 94 |
return np.array([[0.015625, 0.015625],
|