BrainAI-1 commited on
Commit
aa83289
·
verified ·
1 Parent(s): c756688

Upload 5 files

Browse files
Files changed (5) hide show
  1. app.py +188 -0
  2. models/best.bin +3 -0
  3. models/best.xml +0 -0
  4. models/metadata.yaml +15 -0
  5. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import openvino as ov
2
+ import gradio as gr
3
+ import yaml
4
+ import cv2
5
+ import numpy as np
6
+ from ultralytics.utils.plotting import colors
7
+
8
+ model = core.read_model(model = "models_512/best.xml")
9
+ compiled_model = core.compile_model(model = model, device_name = device.value)
10
+
11
+ input_layer = compiled_model.input(0)
12
+ output_layer = compiled_model.output(0)
13
+
14
+ with open('models_512/metadata.yaml') as info:
15
+ info_dict = yaml.load(info, Loader=yaml.Loader)
16
+
17
+ labels = info_dict['names']
18
+
19
+ def prepare_data(image, input_layer):
20
+ input_w, input_h = input_layer.shape[2], input_layer.shape[3]
21
+
22
+ input_image = cv2.resize(image, (input_w, input_h))
23
+ input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)
24
+ input_image = input_image/255
25
+ input_image = input_image.transpose(2,0,1)
26
+ input_image = np.expand_dims(input_image, 0)
27
+
28
+ return input_image
29
+
30
+ def evaluate(output, conf_threshold):
31
+
32
+ boxes = []
33
+ scores = []
34
+ label_key = []
35
+ label_index = 0
36
+
37
+ for class_ in output[0][4:]:
38
+
39
+ for index in range (len(class_)):
40
+ confidence = class_[index]
41
+
42
+ if confidence > conf_threshold:
43
+
44
+ xcen = output[0][0][index]
45
+ ycen = output[0][1][index]
46
+ w = output[0][2][index]
47
+ h = output[0][3][index]
48
+
49
+ xmin = int(xcen - (w/2))
50
+ xmax = int(xcen + (w/2))
51
+ ymin = int(ycen - (h/2))
52
+ ymax = int(ycen + (h/2))
53
+
54
+ box = (xmin, ymin, xmax, ymax)
55
+ boxes.append(box)
56
+ scores.append(confidence)
57
+
58
+ label_key.append(label_index)
59
+
60
+ label_index += 1
61
+
62
+ boxes = np.array(boxes)
63
+ scores = np.array(scores)
64
+
65
+ return boxes, scores, label_key
66
+
67
+ def non_max_suppression(boxes, scores, threshold):
68
+ assert boxes.shape[0] == scores.shape[0]
69
+ # bottom-left origin
70
+ ys1 = boxes[:, 0]
71
+ xs1 = boxes[:, 1]
72
+ # top-right target
73
+ ys2 = boxes[:, 2]
74
+ xs2 = boxes[:, 3]
75
+ # box coordinate ranges are inclusive-inclusive
76
+ areas = (ys2 - ys1) * (xs2 - xs1)
77
+ scores_indexes = scores.argsort().tolist()
78
+ boxes_keep_index = []
79
+ while len(scores_indexes):
80
+ index = scores_indexes.pop()
81
+ boxes_keep_index.append(index)
82
+ if not len(scores_indexes):
83
+ break
84
+ ious = compute_iou(boxes[index], boxes[scores_indexes], areas[index],
85
+ areas[scores_indexes])
86
+ filtered_indexes = set((ious > threshold).nonzero()[0])
87
+ # if there are no more scores_index
88
+ # then we should pop it
89
+ scores_indexes = [
90
+ v for (i, v) in enumerate(scores_indexes)
91
+ if i not in filtered_indexes
92
+ ]
93
+ return np.array(boxes_keep_index)
94
+
95
+
96
+ def compute_iou(box, boxes, box_area, boxes_area):
97
+ # this is the iou of the box against all other boxes
98
+ assert boxes.shape[0] == boxes_area.shape[0]
99
+ # get all the origin-ys
100
+ # push up all the lower origin-xs, while keeping the higher origin-xs
101
+ ys1 = np.maximum(box[0], boxes[:, 0])
102
+ # get all the origin-xs
103
+ # push right all the lower origin-xs, while keeping higher origin-xs
104
+ xs1 = np.maximum(box[1], boxes[:, 1])
105
+ # get all the target-ys
106
+ # pull down all the higher target-ys, while keeping lower origin-ys
107
+ ys2 = np.minimum(box[2], boxes[:, 2])
108
+ # get all the target-xs
109
+ # pull left all the higher target-xs, while keeping lower target-xs
110
+ xs2 = np.minimum(box[3], boxes[:, 3])
111
+ # each intersection area is calculated by the
112
+ # pulled target-x minus the pushed origin-x
113
+ # multiplying
114
+ # pulled target-y minus the pushed origin-y
115
+ # we ignore areas where the intersection side would be negative
116
+ # this is done by using maxing the side length by 0
117
+ intersections = np.maximum(ys2 - ys1, 0) * np.maximum(xs2 - xs1, 0)
118
+ # each union is then the box area
119
+ # added to each other box area minusing their intersection calculated above
120
+ unions = box_area + boxes_area - intersections
121
+ # element wise division
122
+ # if the intersection is 0, then their ratio is 0
123
+ ious = intersections / unions
124
+ return ious
125
+
126
+ def visualize(image, nms_output, boxes, label_key,scores, conf_threshold):
127
+ image_h, image_w, c = image.shape
128
+ input_w, input_h = input_layer.shape[2], input_layer.shape[3]
129
+
130
+ for i in nms_output:
131
+ xmin, ymin, xmax, ymax = boxes[i]
132
+
133
+ xmin = int(xmin*image_w/input_w)
134
+ xmax = int(xmax*image_w/input_w)
135
+ ymin = int(ymin*image_h/input_h)
136
+ ymax = int(ymax*image_h/input_h)
137
+
138
+ label = label_key[i]
139
+ color = colors(label)
140
+ cv2.rectangle(image, (xmin, ymin), (xmax, ymax), color, 1)
141
+ font = cv2.FONT_HERSHEY_SIMPLEX
142
+ text = str(int(scores[i]*100)) + "%" + labels[label]
143
+ font_scale= (image_w/1000)
144
+ label_width, label_height = cv2.getTextSize(text, font,font_scale, 1)[0]
145
+ cv2.rectangle(image, (xmin, ymin-label_height), (xmin + label_width, ymin), color, -1)
146
+
147
+ cv2.putText(image, text, (xmin+2, ymin), font, font_scale, (255,255,255), 1, cv2.LINE_AA)
148
+ return image
149
+
150
+ def predict_image(image, conf_threshold = .4):
151
+
152
+ if image is not None:
153
+ image_RGB = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
154
+ input_image = prepare_data(image_RGB, input_layer)
155
+ output = compiled_model([input_image])[output_layer]
156
+ boxes, scores, label_key = evaluate(output, conf_threshold)
157
+
158
+ if len(boxes):
159
+ nms_output = non_max_suppression(boxes, scores, conf_threshold)
160
+
161
+ visualized_image = visualize(image_RGB, nms_output, boxes, label_key,scores, conf_threshold)
162
+ visualized_image = cv2.cvtColor(visualized_image, cv2.COLOR_BGR2RGB)
163
+ return visualized_image
164
+ else:
165
+ return image
166
+
167
+ image_interface = gr.Interface(
168
+ fn = predict_image,
169
+ inputs = [gr.Image(label="Upload Image"),
170
+ gr.Slider(minimum=0.05, maximum = 1, value = .4, label = "Confidence")
171
+ ],
172
+ outputs = gr.Image(label="Results"),
173
+ title = "AI Kickboard Safety Project",
174
+ description = "Upload images for Inference on YOLOv8.",
175
+ live = True
176
+ )
177
+
178
+
179
+ if __name__=="__main__":
180
+ image_interface.launch(share=True)
181
+
182
+
183
+
184
+
185
+
186
+
187
+
188
+
models/best.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a9d6a3002f27c3705b5f8c39f859e34de0f2edd5cdaa9eeb2890a6382bfa0219
3
+ size 44521776
models/best.xml ADDED
The diff for this file is too large to render. See raw diff
 
models/metadata.yaml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ description: Ultralytics best model trained on kickboard-1/data.yaml
2
+ author: Ultralytics
3
+ date: '2024-07-01T16:55:37.972910'
4
+ version: 8.2.48
5
+ license: AGPL-3.0 License (https://ultralytics.com/license)
6
+ docs: https://docs.ultralytics.com
7
+ stride: 32
8
+ task: detect
9
+ batch: 1
10
+ imgsz:
11
+ - 256
12
+ - 256
13
+ names:
14
+ 0: no helmet
15
+ 1: helmet
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ openvino==2024.0.0
2
+ pyyaml==6.0.1
3
+ opencv-python-headless==4.10.0.84
4
+ numpy==1.26.4
5
+ ultralytics==8.2.63