Arnav Raina commited on
Commit
0e28ea3
·
1 Parent(s): c59d060

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +35 -0
  2. predict.py +114 -0
  3. utils.py +72 -0
app.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from predict import ONNXInference
3
+
4
+ PRED = []
5
+
6
+ def detect(files):
7
+ model = ONNXInference(
8
+ model_path="/home/neo/Downloads/torchFlow/models/torchFlow-ckpt.onnx",
9
+ files=files,
10
+ save_image=False,
11
+ save_path="/home/neo/Downloads/torchFlow/"
12
+ )
13
+ res = model.run()
14
+ img_id = res["IMG_ID"]
15
+ pred_lab = res["PRED_LAB"],
16
+ pred_ct = res["PRED_CT"],
17
+ geo_tag_url = res["GEO_TAG_URL"]
18
+ PRED.append(pred_ct)
19
+ return f"Predicted"
20
+
21
+ with gr.Blocks() as demo:
22
+ with gr.Row():
23
+ output=gr.Image()
24
+ with gr.Row():
25
+ btn = gr.UploadButton(
26
+ label="Upload Image",
27
+ file_types = ['.jpg','.jpeg'],
28
+ file_count = "multiple")
29
+ btn.upload(fn=detect, inputs=btn)
30
+ with gr.Column(scale=1, min_width=600):
31
+ gr.Markdown(f"Output here")
32
+ if PRED is not None:
33
+ gr.Markdown(f"Predicted: {PRED}")
34
+
35
+ demo.launch()
predict.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Inference script for YOLOv8 ONNX model
2
+
3
+ import os
4
+ import cv2
5
+ import numpy as np
6
+ import onnxruntime
7
+ import pandas as pd
8
+ from exif import Image
9
+ from pathlib import Path
10
+ from utils import load_img, nms, xywh2xyxy
11
+
12
+ class ONNXInference():
13
+ def __init__(self, model_path, files, save_image, save_path='./'):
14
+ self.model_path = model_path
15
+ self.files = files
16
+ self.conf_thres = 0.2 # confidence threshold for onnx model
17
+ self.iou_thres = 0.7 # intersection-over-union threshold for onnx model
18
+ self.save_image = save_image
19
+ self.save_path = save_path
20
+
21
+ def run(self):
22
+ opt_session = onnxruntime.SessionOptions()
23
+ opt_session.enable_mem_pattern = True # True: memory efficient
24
+ opt_session.enable_cpu_mem_arena = True # True: memory efficient
25
+ opt_session.graph_optimization_level = onnxruntime.GraphOptimizationLevel.ORT_ENABLE_ALL # ALL: for optimization
26
+
27
+ EP_list = ['CUDAExecutionProvider', 'CPUExecutionProvider'] # providers list
28
+ ort_session = onnxruntime.InferenceSession(self.model_path, sess_options=opt_session, providers=EP_list)
29
+
30
+ model_inputs = ort_session.get_inputs() # List of input nodes for loaded ONNX model
31
+ input_names = [model_inputs[i].name for i in range(len(model_inputs))] # names of the input nodes
32
+ input_shape = model_inputs[0].shape # shape of input
33
+ print(input_shape)
34
+ model_output = ort_session.get_outputs() # list of output nodes for loaded ONNX model
35
+ output_names = [model_output[i].name for i in range(len(model_output))] # list of output names
36
+
37
+ IMG_ID = []
38
+ PRED_LAB = []
39
+ GEO_TAG_URL = []
40
+ PRED_CT = []
41
+ file_paths = [file.name for file in self.files]
42
+
43
+ for i in file_paths:
44
+ # Loading images
45
+ image, image_height, image_width, input_height, input_width, input_tensor = load_img(
46
+ Path(i).as_posix(),
47
+ input_shape
48
+ )
49
+
50
+ # Run
51
+ outputs = ort_session.run(output_names, {input_names[0]: input_tensor})[0] # ONNX output as numpy array
52
+
53
+ predictions = np.squeeze(outputs).T
54
+ CONF_THRESHOLD = self.conf_thres
55
+ scores = np.max(predictions[:, 4:], axis=1)
56
+ predictions = predictions[scores > CONF_THRESHOLD, :] # Filter out object confidence scores below threshold
57
+ scores = scores[scores > CONF_THRESHOLD]
58
+ class_ids = np.argmax(predictions[:, 4:], axis=1)
59
+ boxes = predictions[:, :4] # (x,y,w,h)
60
+
61
+ #rescale box
62
+ input_shape = np.array([input_width, input_height, input_width, input_height])
63
+ boxes = np.divide(boxes, input_shape, dtype=np.float32)
64
+ boxes *= np.array([image_width, image_height, image_width, image_height])
65
+ boxes = boxes.astype(np.int32)
66
+
67
+
68
+ # Apply NMS to suppress weak, overlapping bounding boxes
69
+ IOU_THRESHOLD = self.iou_thres
70
+ indices = nms(xywh2xyxy(boxes), scores, IOU_THRESHOLD)
71
+
72
+ if self.save_image:
73
+ image_draw = image.copy()
74
+ for (bbox, score, label) in zip(xywh2xyxy(boxes[indices]), scores[indices], class_ids[indices]):
75
+ bbox = bbox.round().astype(np.int32).tolist()
76
+ cls_id = int(label)
77
+ CLASSES = ["plastic"]
78
+ cls = CLASSES[cls_id]
79
+ color = (0,255,0)
80
+ cv2.rectangle(image_draw, tuple(bbox[:2]), tuple(bbox[2:]), color, 2)
81
+ cv2.putText(image_draw,
82
+ f'{cls}:{int(score*100)}', (bbox[0], bbox[1] - 2),
83
+ cv2.FONT_HERSHEY_SIMPLEX,
84
+ 0.60, [225, 255, 255],
85
+ thickness=1)
86
+ cv2.imwrite(f"result_[0].jpg", image_draw)
87
+
88
+ # preds
89
+ boxes = boxes[indices]
90
+ scores = scores[indices]
91
+ pred_ct = len(scores)
92
+
93
+ # Getting geo-coordinates
94
+ with open(i, "rb") as image_geo:
95
+ my_image = Image(image_geo)
96
+ dd_lat = my_image.gps_latitude[0] + (my_image.gps_latitude[1]/60) + (my_image.gps_latitude[2]/3600)
97
+ dd_long = my_image.gps_longitude[0] + (my_image.gps_longitude[1]/60) + (my_image.gps_longitude[2]/3600)
98
+ url = f"https://www.google.com/maps?q={dd_lat:.7f}%2C{dd_long:.7f}"
99
+ GEO_TAG_URL.append(url)
100
+
101
+ if pred_ct is not None:
102
+ PRED_LAB.append("Yes")
103
+ IMG_ID.append(str(i))
104
+ PRED_CT.append(pred_ct)
105
+
106
+
107
+ result = {
108
+ "IMG_ID": IMG_ID,
109
+ "PRED_LAB": PRED_LAB,
110
+ "PRED_CT": PRED_CT,
111
+ "GEO_TAG_URL": GEO_TAG_URL
112
+ }
113
+
114
+ return result
utils.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Utilities
2
+
3
+ import cv2
4
+ import numpy as np
5
+ from PIL import Image
6
+
7
+ def load_img(img_path, input_shape):
8
+ # Loading image
9
+ image = cv2.imread(img_path)
10
+ image_height, image_width = image.shape[:2]
11
+ Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
12
+
13
+ input_height, input_width = input_shape[2:]
14
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
15
+ resized = cv2.resize(image_rgb, (input_width, input_height)) # image resized as req by onnx model
16
+
17
+ input_image = resized / 255.0 # scaling image
18
+ input_image = input_image.transpose(2,0,1) # dim rearranged as req by onnx (batch_size, channel, height, width)
19
+ input_tensor = input_image[np.newaxis, :, :, :].astype(np.float32)
20
+
21
+ return image, image_height, image_width, input_height, input_width, input_tensor
22
+
23
+ def nms(boxes, scores, iou_threshold):
24
+ # Sort by score
25
+ sorted_indices = np.argsort(scores)[::-1]
26
+
27
+ keep_boxes = []
28
+ while sorted_indices.size > 0:
29
+ # Pick the last box
30
+ box_id = sorted_indices[0]
31
+ keep_boxes.append(box_id)
32
+
33
+ # Compute IoU of the picked box with the rest
34
+ ious = compute_iou(boxes[box_id, :], boxes[sorted_indices[1:], :])
35
+
36
+ # Remove boxes with IoU over the threshold
37
+ keep_indices = np.where(ious < iou_threshold)[0]
38
+
39
+ # print(keep_indices.shape, sorted_indices.shape)
40
+ sorted_indices = sorted_indices[keep_indices + 1]
41
+
42
+ return keep_boxes
43
+
44
+ def compute_iou(box, boxes):
45
+ # Compute xmin, ymin, xmax, ymax for both boxes
46
+ xmin = np.maximum(box[0], boxes[:, 0])
47
+ ymin = np.maximum(box[1], boxes[:, 1])
48
+ xmax = np.minimum(box[2], boxes[:, 2])
49
+ ymax = np.minimum(box[3], boxes[:, 3])
50
+
51
+ # Compute intersection area
52
+ intersection_area = np.maximum(0, xmax - xmin) * np.maximum(0, ymax - ymin)
53
+
54
+ # Compute union area
55
+ box_area = (box[2] - box[0]) * (box[3] - box[1])
56
+ boxes_area = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
57
+ union_area = box_area + boxes_area - intersection_area
58
+
59
+ # Compute IoU
60
+ iou = intersection_area / union_area
61
+
62
+ return iou
63
+
64
+
65
+ def xywh2xyxy(x):
66
+ # Convert bounding box (x, y, w, h) to bounding box (x1, y1, x2, y2)
67
+ y = np.copy(x)
68
+ y[..., 0] = x[..., 0] - x[..., 2] / 2
69
+ y[..., 1] = x[..., 1] - x[..., 3] / 2
70
+ y[..., 2] = x[..., 0] + x[..., 2] / 2
71
+ y[..., 3] = x[..., 1] + x[..., 3] / 2
72
+ return y