File size: 6,290 Bytes
aa83289 9e65958 aa83289 19c3c5f f23cdff aa83289 19c3c5f aa83289 | 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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | import openvino as ov
import gradio as gr
import yaml
import cv2
import numpy as np
from ultralytics.utils.plotting import colors
core = ov.Core()
model = core.read_model(model = "models/best.xml")
compiled_model = core.compile_model(model = model, device_name = "AUTO")
input_layer = compiled_model.input(0)
output_layer = compiled_model.output(0)
with open('models/metadata.yaml') as info:
info_dict = yaml.load(info, Loader=yaml.Loader)
labels = info_dict['names']
def prepare_data(image, input_layer):
input_w, input_h = input_layer.shape[2], input_layer.shape[3]
input_image = cv2.resize(image, (input_w, input_h))
input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2RGB)
input_image = input_image/255
input_image = input_image.transpose(2,0,1)
input_image = np.expand_dims(input_image, 0)
return input_image
def evaluate(output, conf_threshold):
boxes = []
scores = []
label_key = []
label_index = 0
for class_ in output[0][4:]:
for index in range (len(class_)):
confidence = class_[index]
if confidence > conf_threshold:
xcen = output[0][0][index]
ycen = output[0][1][index]
w = output[0][2][index]
h = output[0][3][index]
xmin = int(xcen - (w/2))
xmax = int(xcen + (w/2))
ymin = int(ycen - (h/2))
ymax = int(ycen + (h/2))
box = (xmin, ymin, xmax, ymax)
boxes.append(box)
scores.append(confidence)
label_key.append(label_index)
label_index += 1
boxes = np.array(boxes)
scores = np.array(scores)
return boxes, scores, label_key
def non_max_suppression(boxes, scores, threshold):
assert boxes.shape[0] == scores.shape[0]
# bottom-left origin
ys1 = boxes[:, 0]
xs1 = boxes[:, 1]
# top-right target
ys2 = boxes[:, 2]
xs2 = boxes[:, 3]
# box coordinate ranges are inclusive-inclusive
areas = (ys2 - ys1) * (xs2 - xs1)
scores_indexes = scores.argsort().tolist()
boxes_keep_index = []
while len(scores_indexes):
index = scores_indexes.pop()
boxes_keep_index.append(index)
if not len(scores_indexes):
break
ious = compute_iou(boxes[index], boxes[scores_indexes], areas[index],
areas[scores_indexes])
filtered_indexes = set((ious > threshold).nonzero()[0])
# if there are no more scores_index
# then we should pop it
scores_indexes = [
v for (i, v) in enumerate(scores_indexes)
if i not in filtered_indexes
]
return np.array(boxes_keep_index)
def compute_iou(box, boxes, box_area, boxes_area):
# this is the iou of the box against all other boxes
assert boxes.shape[0] == boxes_area.shape[0]
# get all the origin-ys
# push up all the lower origin-xs, while keeping the higher origin-xs
ys1 = np.maximum(box[0], boxes[:, 0])
# get all the origin-xs
# push right all the lower origin-xs, while keeping higher origin-xs
xs1 = np.maximum(box[1], boxes[:, 1])
# get all the target-ys
# pull down all the higher target-ys, while keeping lower origin-ys
ys2 = np.minimum(box[2], boxes[:, 2])
# get all the target-xs
# pull left all the higher target-xs, while keeping lower target-xs
xs2 = np.minimum(box[3], boxes[:, 3])
# each intersection area is calculated by the
# pulled target-x minus the pushed origin-x
# multiplying
# pulled target-y minus the pushed origin-y
# we ignore areas where the intersection side would be negative
# this is done by using maxing the side length by 0
intersections = np.maximum(ys2 - ys1, 0) * np.maximum(xs2 - xs1, 0)
# each union is then the box area
# added to each other box area minusing their intersection calculated above
unions = box_area + boxes_area - intersections
# element wise division
# if the intersection is 0, then their ratio is 0
ious = intersections / unions
return ious
def visualize(image, nms_output, boxes, label_key,scores, conf_threshold):
image_h, image_w, c = image.shape
input_w, input_h = input_layer.shape[2], input_layer.shape[3]
for i in nms_output:
xmin, ymin, xmax, ymax = boxes[i]
xmin = int(xmin*image_w/input_w)
xmax = int(xmax*image_w/input_w)
ymin = int(ymin*image_h/input_h)
ymax = int(ymax*image_h/input_h)
label = label_key[i]
color = colors(label)
cv2.rectangle(image, (xmin, ymin), (xmax, ymax), color, 1)
font = cv2.FONT_HERSHEY_SIMPLEX
text = str(int(scores[i]*100)) + "%" + labels[label]
font_scale= (image_w/1000)
label_width, label_height = cv2.getTextSize(text, font,font_scale, 1)[0]
cv2.rectangle(image, (xmin, ymin-label_height), (xmin + label_width, ymin), color, -1)
cv2.putText(image, text, (xmin+2, ymin), font, font_scale, (255,255,255), 1, cv2.LINE_AA)
return image
def predict_image(image, conf_threshold = .4):
if image is not None:
image_RGB = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
input_image = prepare_data(image_RGB, input_layer)
output = compiled_model([input_image])[output_layer]
boxes, scores, label_key = evaluate(output, conf_threshold)
if len(boxes):
nms_output = non_max_suppression(boxes, scores, conf_threshold)
visualized_image = visualize(image_RGB, nms_output, boxes, label_key,scores, conf_threshold)
visualized_image = cv2.cvtColor(visualized_image, cv2.COLOR_BGR2RGB)
return visualized_image
else:
return image
image_interface = gr.Interface(
fn = predict_image,
inputs = [gr.Image(label="Upload Image"),
gr.Slider(minimum=0.05, maximum = 1, value = .4, label = "Confidence")
],
outputs = gr.Image(label="Results"),
title = "AI Kickboard Safety Project",
description = "Upload images for Inference on YOLOv8.",
live = True
)
if __name__=="__main__":
image_interface.launch(share=True)
|