vk commited on
Commit
1a2f039
·
1 Parent(s): f8c3c89

first commit

Browse files
app.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from yolox_onnx import YOLOX_ONNX
2
+ import albumentations as A
3
+ import gradio as gr
4
+ import cv2
5
+
6
+ def show_example(path):
7
+ return cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB)
8
+
9
+
10
+ def get_response(input_img,add_snow,add_rain,add_fog,confidence_threshold,iou_threshold):
11
+
12
+ '''
13
+ detects all possible pedestrians in the image and recognizes it
14
+ Args:
15
+ input_img (numpy array): one image of type numpy array
16
+ add_snow (boolean) : apply random snow augmentation
17
+ add_rain (boolean) : apply random rain augmentation
18
+ add_fog (boolean) : apply random fog augmentation
19
+ confidence_threshold (float) : minimum confidence prob required for bounding box candidate
20
+ iou_threshold (float) : intersection threshold above which bounding box will be neglected
21
+
22
+ Returns:
23
+ return img(numpy array): image with bounding boxes of pedestrians
24
+ '''
25
+
26
+
27
+ if not hasattr(input_img,'shape'):
28
+ return "invalid input",input_img
29
+
30
+ pedestrian_detector.predict(input_img,confidence_threshold,iou_threshold)
31
+ out_img=pedestrian_detector.output_img
32
+
33
+ if add_snow:
34
+ out_img = weather_transform["add_snow"] (image=out_img)['image']
35
+ elif add_rain:
36
+ out_img = weather_transform["add_rain"](image=out_img)['image']
37
+ elif add_fog:
38
+ out_img = weather_transform["add_fog"](image=out_img)['image']
39
+ else:
40
+ pass
41
+
42
+
43
+ return out_img
44
+
45
+
46
+ if __name__ == "__main__":
47
+ weather_transform = {}
48
+ weather_transform["add_rain"] = A.RandomRain(brightness_coefficient=0.9, drop_width=1, blur_value=5, p=1)
49
+ weather_transform["add_snow"] = A.RandomSnow(brightness_coeff=2.5, snow_point_lower=0.3, snow_point_upper=0.5, p=1)
50
+ weather_transform["add_fog"] = A.RandomFog(fog_coef_lower=0.7, fog_coef_upper=0.8, alpha_coef=0.1, p=1)
51
+
52
+
53
+ pedestrian_detector=YOLOX_ONNX('models/pedestrian-detection-best55.onnx')
54
+ iface = gr.Interface(
55
+ fn=get_response,
56
+ inputs=[gr.Image(type="numpy"), # Accepts image input
57
+ gr.Checkbox(label="add_snow"),
58
+ gr.Checkbox(label="add_rain"),
59
+ gr.Checkbox(label="add_fog"),
60
+ gr.Slider(0, 1,value=0.5, step=0.01, label="confidence_threshold"),
61
+ gr.Slider(0, 1,value=0.45, step=0.01, label="iou_threshold")],
62
+ examples=[[show_example('test1.jpg')],[show_example('test2.jpg')],[show_example('test3.jpg')]],
63
+ outputs=[gr.Image(type="numpy")],
64
+ title="Pedestrian Detection with All weather augmentation",
65
+ description="Upload images for pedestrian detection")
66
+
67
+ iface.launch(share=True)
models/pedestrian-detection-best55.onnx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dcb7921907ddf0b59f99f13223000011a41467dfafbdb6a1ab2a4c22432f72bd
3
+ size 3674588
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ opencv_python
2
+ albumentations==1.4.10
3
+ albucore==0.0.13
4
+ onnxruntime
5
+ gradio
yolox_onnx.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ from time import time
3
+ import numpy as np
4
+ import onnxruntime
5
+ from matplotlib import pyplot as plt
6
+ from collections import defaultdict
7
+
8
+
9
+ class YOLOX_ONNX:
10
+
11
+ def __init__(self, model_path):
12
+ providers = ['CPUExecutionProvider']
13
+ self.model = onnxruntime.InferenceSession(model_path, providers=providers)
14
+ self.image_size = self.model.get_inputs()[0].shape[-2:]
15
+ # print(self.model.get_outputs()[0].name)
16
+ # print(self.image_size)
17
+ self.labels_map=['pedestrian']
18
+
19
+
20
+
21
+
22
+ def __preprocess_image(self, img, swap=(2, 0, 1)):
23
+
24
+ padded_img = np.ones((self.image_size[0], self.image_size[1], 3), dtype=np.uint8) * 114
25
+ r = min(self.image_size[0] / img.shape[0], self.image_size[1] / img.shape[1])
26
+ resized_img = cv2.resize(img, (int(img.shape[1] * r), int(img.shape[0] * r)), interpolation=cv2.INTER_LINEAR).astype(np.uint8)
27
+ padded_img[: int(img.shape[0] * r), : int(img.shape[1] * r)] = resized_img
28
+ padded_img = padded_img.transpose(swap)
29
+ padded_img = np.ascontiguousarray(padded_img, dtype=np.float32)
30
+ return padded_img, r
31
+
32
+
33
+ @staticmethod
34
+ def __new_nms(boxes, scores, iou_thresh):
35
+ x1 = boxes[:, 0]
36
+ y1 = boxes[:, 1]
37
+ x2 = boxes[:, 2]
38
+ y2 = boxes[:, 3]
39
+ areas = (x2 - x1 + 1) * (y2 - y1 + 1)
40
+ order = scores.argsort()[::-1]
41
+ keep = []
42
+ while order.size > 0:
43
+ i = order[0]
44
+ keep.append(i)
45
+ xx1 = np.maximum(x1[i], x1[order[1:]])
46
+ yy1 = np.maximum(y1[i], y1[order[1:]])
47
+ xx2 = np.minimum(x2[i], x2[order[1:]])
48
+ yy2 = np.minimum(y2[i], y2[order[1:]])
49
+ w = np.maximum(0.0, xx2 - xx1 + 1)
50
+ h = np.maximum(0.0, yy2 - yy1 + 1)
51
+ inter = w * h
52
+ ovr = inter / (areas[i] + areas[order[1:]] - inter)
53
+ inds = np.where(ovr <= iou_thresh)[0]
54
+ order = order[inds + 1]
55
+
56
+ return keep
57
+
58
+
59
+ def __parse_output_data(self, outputs):
60
+ grids = []
61
+ expanded_strides = []
62
+ strides = [8, 16, 32]
63
+ hsizes = [self.image_size[0] // stride for stride in strides]
64
+ wsizes = [self.image_size[1] // stride for stride in strides]
65
+ for hsize, wsize, stride in zip(hsizes, wsizes, strides):
66
+ xv, yv = np.meshgrid(np.arange(wsize), np.arange(hsize))
67
+ grid = np.stack((xv, yv), 2).reshape(1, -1, 2)
68
+ grids.append(grid)
69
+ shape = grid.shape[:2]
70
+ expanded_strides.append(np.full((*shape, 1), stride))
71
+ grids = np.concatenate(grids, 1)
72
+ expanded_strides = np.concatenate(expanded_strides, 1)
73
+ outputs[..., :2] = (outputs[..., :2] + grids) * expanded_strides
74
+ outputs[..., 2:4] = np.exp(outputs[..., 2:4]) * expanded_strides
75
+ return outputs[0]
76
+
77
+ def __decode_prediction(self, prediction, img_size, resize_ratio, score_thresh, iou_thresh):
78
+
79
+ boxes = prediction[:, :4]
80
+ classes = prediction[:, 4:5] * prediction[:, 5:]
81
+ scores = np.amax(classes, axis=1)
82
+ classes = np.argmax(classes, axis=1)
83
+
84
+
85
+ valid_score_mask = scores > score_thresh
86
+ if valid_score_mask.sum() == 0:
87
+ return np.array([]), np.array([]), np.array([])
88
+ valid_scores = scores[valid_score_mask]
89
+ valid_boxes = boxes[valid_score_mask]
90
+ valid_classes = classes[valid_score_mask]
91
+
92
+
93
+ valid_boxes_xyxy = np.ones_like(valid_boxes)
94
+ valid_boxes_xyxy[:, 0] = valid_boxes[:, 0] - valid_boxes[:, 2]/2.
95
+ valid_boxes_xyxy[:, 1] = valid_boxes[:, 1] - valid_boxes[:, 3]/2.
96
+ valid_boxes_xyxy[:, 2] = valid_boxes[:, 0] + valid_boxes[:, 2]/2.
97
+ valid_boxes_xyxy[:, 3] = valid_boxes[:, 1] + valid_boxes[:, 3]/2.
98
+ valid_boxes_xyxy /= resize_ratio
99
+
100
+ indices = self.__new_nms(valid_boxes_xyxy, valid_scores, iou_thresh)
101
+ valid_boxes_xyxy = valid_boxes_xyxy[indices, :]
102
+ valid_scores = valid_scores[indices]
103
+ valid_classes = valid_classes[indices].astype('int')
104
+
105
+ #valid_boxes_xyxy, valid_scores, valid_classes = self.__remove_duplicates(valid_boxes_xyxy, valid_scores, valid_classes)
106
+
107
+
108
+ return valid_boxes_xyxy, valid_scores, valid_classes
109
+
110
+ def draw_boxes(self,img, boxes, scores=None, classes=None, labels=None):
111
+
112
+
113
+ for i in range(boxes.shape[0]):
114
+ cv2.rectangle(img,
115
+ (int(boxes[i,0]), int(boxes[i,1])),
116
+ (int(boxes[i,2]), int(boxes[i,3])),
117
+ (0, 128, 0),
118
+ int(0.005*img.shape[1]))
119
+
120
+ ### not drawing classes since num_classes is 1(pedestrian) and text not greatly visible in gradio UI
121
+ # text_label = ''
122
+ # if labels is not None:
123
+ # if classes is not None:
124
+ # text_label = labels[classes[i]]
125
+ # if scores is not None:
126
+ # text_label+= ' ' + str("%.2f" % round(scores[i],2))
127
+ # elif scores is not None:
128
+ # text_label = str("%.2f" % round(scores[i],2))
129
+
130
+ #w, h = cv2.getTextSize(text_label, 0, fontScale=0.5, thickness=1)[0]
131
+ # cv2.putText(img,
132
+ # text_label,
133
+ # (int(boxes[i,0]) if int(boxes[i,0])+w<img.shape[1] else img.shape[1]-w, int(boxes[i,1])-2 if (int(boxes[i,1])-h>=3) else int(boxes[i,1])+h+2),
134
+ # 0,
135
+ # 0.5,
136
+ # (0,0,255),
137
+ # thickness= int(0.005*img.shape[1]),
138
+ # lineType=cv2.LINE_AA)
139
+ return img
140
+
141
+ def predict(self, image, score_thresh=0.5, iou_thresh=0.4):
142
+ h,w = image.shape[:2]
143
+ origin_img=np.copy(image)
144
+ model_input = np.copy(image)
145
+ model_input, resize_ratio = self.__preprocess_image(model_input)
146
+ #print(model_input.shape)
147
+ #print('input mean:', np.mean(model_input))
148
+ start_time=time()
149
+ prediction = self.model.run(None, {self.model.get_inputs()[0].name: model_input[None, :, :, :]})
150
+ #print(self.model.get_inputs()[0].name)
151
+ #print('output mean:',np.mean(prediction))
152
+ prediction = self.__parse_output_data(prediction[0])
153
+ d_boxes, d_scores, d_classes=self.__decode_prediction(prediction, (h,w), resize_ratio, score_thresh, iou_thresh)
154
+ self.output_img = self.draw_boxes(origin_img, d_boxes,None, d_classes, self.labels_map)
155
+ print('elapsed time:',time()-start_time)
156
+
157
+ return d_boxes, d_scores, d_classes
158
+
159
+