forked from Tau-J/rtmlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyolox.py
138 lines (114 loc) · 5.05 KB
/
yolox.py
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Code modified from https://github.com/IDEA-Research/DWPose/blob/opencv_onnx/ControlNet-v1-1-nightly/annotator/dwpose/cv_ox_det.py # noqa
from typing import List, Tuple
import cv2
import numpy as np
from ..base import BaseTool
from .post_processings import multiclass_nms
class YOLOX(BaseTool):
def __init__(self,
onnx_model: str,
model_input_size: tuple = (640, 640),
nms_thr=0.45,
score_thr=0.7,
backend: str = 'onnxruntime',
device: str = 'cpu'):
super().__init__(onnx_model,
model_input_size,
backend=backend,
device=device)
self.nms_thr = nms_thr
self.score_thr = score_thr
def __call__(self, image: np.ndarray):
image, ratio = self.preprocess(image)
outputs = self.inference(image)[0]
results = self.postprocess(outputs, ratio)
return results
def preprocess(self, img: np.ndarray):
"""Do preprocessing for RTMPose model inference.
Args:
img (np.ndarray): Input image in shape.
Returns:
tuple:
- padded_img (np.ndarray): Preprocessed image.
- ratio (float): Scale factor applied to the image.
"""
if img.shape[:2] == tuple(self.model_input_size[:2]):
padded_img = img.copy()
ratio = 1.
else:
if len(img.shape) == 3:
padded_img = np.ones(
(self.model_input_size[0], self.model_input_size[1], 3),
dtype=np.uint8) * 114
else:
padded_img = np.ones(self.model_input_size, dtype=np.uint8) * 114
ratio = min(self.model_input_size[0] / img.shape[0],
self.model_input_size[1] / img.shape[1])
resized_img = cv2.resize(
img,
(int(img.shape[1] * ratio), int(img.shape[0] * ratio)),
interpolation=cv2.INTER_LINEAR,
).astype(np.uint8)
padded_shape = (int(img.shape[0] * ratio), int(img.shape[1] * ratio))
padded_img[:padded_shape[0], :padded_shape[1]] = resized_img
return padded_img, ratio
def postprocess(
self,
outputs: List[np.ndarray],
ratio: float = 1.,
) -> Tuple[np.ndarray, np.ndarray]:
"""Do postprocessing for RTMPose model inference.
Args:
outputs (List[np.ndarray]): Outputs of RTMPose model.
ratio (float): Ratio of preprocessing.
Returns:
tuple:
- final_boxes (np.ndarray): Final bounding boxes.
- final_scores (np.ndarray): Final scores.
"""
if outputs.shape[-1] == 4:
# onnx without nms module
grids = []
expanded_strides = []
strides = [8, 16, 32]
hsizes = [self.model_input_size[0] // stride for stride in strides]
wsizes = [self.model_input_size[1] // stride for stride in strides]
for hsize, wsize, stride in zip(hsizes, wsizes, strides):
xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize))
grid = np.stack((xv, yv), 2).reshape(1, -1, 2)
grids.append(grid)
shape = grid.shape[:2]
expanded_strides.append(np.full((*shape, 1), stride))
grids = np.concatenate(grids, 1)
expanded_strides = np.concatenate(expanded_strides, 1)
outputs[..., :2] = (outputs[..., :2] + grids) * expanded_strides
outputs[..., 2:4] = np.exp(outputs[..., 2:4]) * expanded_strides
predictions = outputs[0]
boxes = predictions[:, :4]
scores = predictions[:, 4:5] * predictions[:, 5:]
boxes_xyxy = np.ones_like(boxes)
boxes_xyxy[:, 0] = boxes[:, 0] - boxes[:, 2] / 2.
boxes_xyxy[:, 1] = boxes[:, 1] - boxes[:, 3] / 2.
boxes_xyxy[:, 2] = boxes[:, 0] + boxes[:, 2] / 2.
boxes_xyxy[:, 3] = boxes[:, 1] + boxes[:, 3] / 2.
boxes_xyxy /= ratio
dets, keep = multiclass_nms(boxes_xyxy,
scores,
nms_thr=self.nms_thr,
score_thr=self.score_thr)
if dets is not None:
pack_dets = (dets[:, :4], dets[:, 4], dets[:, 5])
final_boxes, final_scores, final_cls_inds = pack_dets
isscore = final_scores > 0.3
iscat = final_cls_inds == 0
isbbox = [i and j for (i, j) in zip(isscore, iscat)]
final_boxes = final_boxes[isbbox]
elif outputs.shape[-1] == 5:
# onnx contains nms module
pack_dets = (outputs[0, :, :4], outputs[0, :, 4])
final_boxes, final_scores = pack_dets
final_boxes /= ratio
isscore = final_scores > 0.3
isbbox = [i for i in isscore]
final_boxes = final_boxes[isbbox]
return final_boxes