roman
commited on
Commit
•
334d3f1
1
Parent(s):
cc43c1d
add app
Browse files
main.py
ADDED
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from detectron2.utils.logger import setup_logger
|
2 |
+
|
3 |
+
import streamlit as st
|
4 |
+
|
5 |
+
setup_logger()
|
6 |
+
|
7 |
+
import collections
|
8 |
+
|
9 |
+
import torch, torchvision
|
10 |
+
|
11 |
+
from detectron2 import model_zoo
|
12 |
+
from detectron2.engine import DefaultPredictor
|
13 |
+
from detectron2.config import get_cfg
|
14 |
+
from detectron2.data import MetadataCatalog
|
15 |
+
from detectron2.structures import masks
|
16 |
+
|
17 |
+
from detectron2.evaluation import COCOEvaluator, inference_on_dataset
|
18 |
+
from detectron2.data import build_detection_test_loader
|
19 |
+
|
20 |
+
import detectron2.data.transforms as T
|
21 |
+
from detectron2.data import DatasetMapper # the default mapper
|
22 |
+
|
23 |
+
import os
|
24 |
+
import cv2
|
25 |
+
from matplotlib import pyplot as plt
|
26 |
+
|
27 |
+
from IPython.display import display
|
28 |
+
from PIL import Image
|
29 |
+
|
30 |
+
|
31 |
+
# Some basic setup:
|
32 |
+
# Setup detectron2 logger
|
33 |
+
import detectron2
|
34 |
+
from detectron2.utils.logger import setup_logger
|
35 |
+
setup_logger()
|
36 |
+
|
37 |
+
# import some common libraries
|
38 |
+
import numpy as np
|
39 |
+
import os, json, cv2, random
|
40 |
+
import copy
|
41 |
+
# from google.colab.patches import cv2_imshow
|
42 |
+
|
43 |
+
# import some common detectron2 utilities
|
44 |
+
from detectron2 import model_zoo
|
45 |
+
from detectron2.engine import DefaultPredictor
|
46 |
+
from detectron2.config import get_cfg
|
47 |
+
from detectron2.utils.visualizer import Visualizer
|
48 |
+
|
49 |
+
# Зарегистрировать как коко формат
|
50 |
+
from detectron2.data.datasets import register_coco_instances
|
51 |
+
from detectron2.engine import DefaultTrainer
|
52 |
+
|
53 |
+
from detectron2.evaluation import COCOEvaluator, inference_on_dataset
|
54 |
+
from detectron2.data import DatasetCatalog, MetadataCatalog, build_detection_test_loader, build_detection_train_loader
|
55 |
+
|
56 |
+
from detectron2.data import transforms as T
|
57 |
+
from detectron2.data import detection_utils as utils
|
58 |
+
|
59 |
+
|
60 |
+
def predictor_define(cfg, CONFIDENCE=0.7):
|
61 |
+
cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, "model_final.pth") # path to the model we just trained
|
62 |
+
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = CONFIDENCE # set a custom testing threshold 0.7
|
63 |
+
predictor = DefaultPredictor(cfg)
|
64 |
+
|
65 |
+
|
66 |
+
def inference(image, THR=0.5, path_to_model="/content/output/model_final.pth"):
|
67 |
+
cfg = get_cfg()
|
68 |
+
cfg.MODEL.DEVICE = "cuda" # 'cpu' or 'cuda'
|
69 |
+
|
70 |
+
out_dct = dict()
|
71 |
+
|
72 |
+
cat_lst = ["0.2", "0.3", "0.5", "0.8"]
|
73 |
+
|
74 |
+
cfg.merge_from_file(
|
75 |
+
model_zoo.get_config_file("COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml")
|
76 |
+
)
|
77 |
+
cfg.MODEL.ROI_HEADS.NUM_CLASSES = 4
|
78 |
+
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = THR
|
79 |
+
cfg.MODEL.WEIGHTS = path_to_model
|
80 |
+
MetadataCatalog.get("dataset").thing_classes = cat_lst
|
81 |
+
|
82 |
+
predictor = DefaultPredictor(cfg)
|
83 |
+
outputs = predictor(image)
|
84 |
+
|
85 |
+
box_lst = [i.tolist() for i in outputs["instances"].pred_boxes]
|
86 |
+
cl_lst = outputs["instances"].pred_classes.tolist()
|
87 |
+
score_lst = outputs["instances"].scores.tolist()
|
88 |
+
|
89 |
+
out_dct["box_lst"] = box_lst
|
90 |
+
out_dct["cl_lst"] = [cat_lst[i] for i in cl_lst]
|
91 |
+
out_dct["scores"] = score_lst
|
92 |
+
|
93 |
+
return out_dct
|
94 |
+
|
95 |
+
|
96 |
+
def inference_2(image, path_to_model, dataset_name, YAML_FILE, cat_lst=["0.2", "0.3", "0.5", "0.8"], thr=0.25,
|
97 |
+
aa_dct='None', device='cuda', loader='default', aug=[ T.Resize((512, 512)) ]):
|
98 |
+
cfg = get_cfg()
|
99 |
+
cfg.MODEL.DEVICE = device
|
100 |
+
|
101 |
+
out_dct = dict()
|
102 |
+
|
103 |
+
cfg.merge_from_file(
|
104 |
+
model_zoo.get_config_file(YAML_FILE)
|
105 |
+
)
|
106 |
+
cfg.MODEL.ROI_HEADS.NUM_CLASSES = len(cat_lst)
|
107 |
+
cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = thr
|
108 |
+
cfg.INPUT.MIN_SIZE_TEST = 900
|
109 |
+
cfg.INPUT.MAX_SIZE_TEST = 1000
|
110 |
+
cfg.MODEL.WEIGHTS = path_to_model
|
111 |
+
|
112 |
+
if aa_dct != 'None':
|
113 |
+
cfg.MODEL.ANCHOR_GENERATOR.SIZES = aa_dct['anchor_sizes']
|
114 |
+
cfg.MODEL.ANCHOR_GENERATOR.ASPECT_RATIOS = aa_dct['aspect_ratio']
|
115 |
+
|
116 |
+
# MetadataCatalog.get(dataset_name).thing_classes = cat_lst
|
117 |
+
predictor = DefaultPredictor(cfg)
|
118 |
+
|
119 |
+
# if loader == 'default':
|
120 |
+
# val_loader = build_detection_test_loader(cfg, dataset_name)
|
121 |
+
# else:
|
122 |
+
# val_loader = build_detection_test_loader(cfg, dataset_name, mapper=DatasetMapper(cfg, is_train=False, augmentations = aug))
|
123 |
+
|
124 |
+
# return_inference = inference_on_dataset(predictor.model, val_loader, evaluator)
|
125 |
+
|
126 |
+
outputs = predictor(image)
|
127 |
+
|
128 |
+
box_lst = [i.tolist() for i in outputs["instances"].pred_boxes]
|
129 |
+
cl_lst = outputs["instances"].pred_classes.tolist()
|
130 |
+
score_lst = outputs["instances"].scores.tolist()
|
131 |
+
|
132 |
+
out_dct["box_lst"] = box_lst
|
133 |
+
out_dct["cl_lst"] = [cat_lst[i] for i in cl_lst]
|
134 |
+
out_dct["scores"] = score_lst
|
135 |
+
|
136 |
+
return out_dct
|
137 |
+
|
138 |
+
|
139 |
+
def imagename(str):
|
140 |
+
return str.split('/')[-1]
|
141 |
+
|
142 |
+
|
143 |
+
def read_image(im_path, YAML_FILE, path_to_model, THR=0.5, dim=(500, 500),
|
144 |
+
cat_lst=['pomeranc', 'poteklina']):
|
145 |
+
|
146 |
+
out_dct = {}
|
147 |
+
|
148 |
+
im_name = imagename(im_path)
|
149 |
+
# img = cv2.imread(os.path.join(root_path, d["file_name"]))
|
150 |
+
img = cv2.imread(im_path)
|
151 |
+
out_dct[im_name] = inference_2(image=img, path_to_model=path_to_model,
|
152 |
+
dataset_name=None, YAML_FILE=YAML_FILE,
|
153 |
+
cat_lst=cat_lst, thr=THR)
|
154 |
+
print(im_path)
|
155 |
+
# print(os.path.join(im_path, d["file_name"]))
|
156 |
+
labels_list = []
|
157 |
+
boxes = []
|
158 |
+
name_dict = {}
|
159 |
+
|
160 |
+
for i in range(len(out_dct[im_name]['cl_lst'])):
|
161 |
+
box = out_dct[im_name]['box_lst'][i]
|
162 |
+
box = [int(i) for i in box]
|
163 |
+
label = out_dct[im_name]['cl_lst'][i]
|
164 |
+
scores = out_dct[im_name]['scores'][i]
|
165 |
+
# print(label, scores)
|
166 |
+
# print(box)
|
167 |
+
labels_list.append(label)
|
168 |
+
boxes.append(box[0])
|
169 |
+
|
170 |
+
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 1)
|
171 |
+
cv2.putText(img, label, (box[0], box[3]), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 4)
|
172 |
+
# cv2.putText(img, str(int(scores*100)), (box[0], box[3]),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
|
173 |
+
# print(d["file_name"])
|
174 |
+
# print(labels_list)
|
175 |
+
|
176 |
+
for num, name in zip(boxes, labels_list):
|
177 |
+
name_dict[num] = name
|
178 |
+
|
179 |
+
# print(name_dict)
|
180 |
+
|
181 |
+
od = collections.OrderedDict(sorted(name_dict.items()))
|
182 |
+
digits_out_sorted = []
|
183 |
+
for k, v in od.items():
|
184 |
+
digits_out_sorted.append(v)
|
185 |
+
|
186 |
+
# print(od)
|
187 |
+
|
188 |
+
print(digits_out_sorted)
|
189 |
+
|
190 |
+
# resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
|
191 |
+
im_output_path = ROOT_FOLDER + 'output_images/' + im_path.split('/')[-1]
|
192 |
+
print(im_output_path)
|
193 |
+
cv2.imwrite(im_output_path, img)
|
194 |
+
|
195 |
+
def process_one_image(img, im_name, YAML_FILE, path_to_model, THR=0.5, dim=(500, 500),
|
196 |
+
cat_lst=['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']):
|
197 |
+
|
198 |
+
out_dct = {}
|
199 |
+
|
200 |
+
# im_name = imagename(im_path)
|
201 |
+
# img = cv2.imread(os.path.join(root_path, d["file_name"]))
|
202 |
+
# img = cv2.imread(im_path)
|
203 |
+
out_dct[im_name] = inference_2(image=img, path_to_model=path_to_model,
|
204 |
+
dataset_name=None, YAML_FILE=YAML_FILE,
|
205 |
+
cat_lst=cat_lst, thr=THR)
|
206 |
+
# print(im_path)
|
207 |
+
# print(os.path.join(im_path, d["file_name"]))
|
208 |
+
labels_list = []
|
209 |
+
boxes = []
|
210 |
+
name_dict = {}
|
211 |
+
|
212 |
+
for i in range(len(out_dct[im_name]['cl_lst'])):
|
213 |
+
box = out_dct[im_name]['box_lst'][i]
|
214 |
+
box = [int(i) for i in box]
|
215 |
+
label = out_dct[im_name]['cl_lst'][i]
|
216 |
+
scores = out_dct[im_name]['scores'][i]
|
217 |
+
# print(label, scores)
|
218 |
+
# print(box)
|
219 |
+
labels_list.append(label)
|
220 |
+
boxes.append(box[0])
|
221 |
+
|
222 |
+
cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 255, 0), 1)
|
223 |
+
cv2.putText(img, label, (box[0], box[3]), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 4)
|
224 |
+
# cv2.putText(img, str(int(scores*100)), (box[0], box[3]),cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
|
225 |
+
# print(d["file_name"])
|
226 |
+
# print(labels_list)
|
227 |
+
|
228 |
+
for num, name in zip(boxes, labels_list):
|
229 |
+
name_dict[num] = name
|
230 |
+
|
231 |
+
# print(name_dict)
|
232 |
+
|
233 |
+
od = collections.OrderedDict(sorted(name_dict.items()))
|
234 |
+
digits_out_sorted = []
|
235 |
+
for k, v in od.items():
|
236 |
+
digits_out_sorted.append(v)
|
237 |
+
|
238 |
+
# print(od)
|
239 |
+
|
240 |
+
print(digits_out_sorted)
|
241 |
+
|
242 |
+
# resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
|
243 |
+
# im_output_path = ROOT_FOLDER + 'output_images/' + im_path.split('/')[-1]
|
244 |
+
# print(im_output_path)
|
245 |
+
# cv2.imwrite(im_output_path, img)
|
246 |
+
|
247 |
+
return img, digits_out_sorted
|
248 |
+
|
249 |
+
ROOT_FOLDER = '/home/roman/PycharmProjects/streamlit/digits/'
|
250 |
+
|
251 |
+
train_dct1 = {
|
252 |
+
'10cl':
|
253 |
+
{
|
254 |
+
'cat_lst': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
|
255 |
+
'train': {
|
256 |
+
'13': {
|
257 |
+
'json': ROOT_FOLDER + '/json/digits-13.json',
|
258 |
+
'data': ROOT_FOLDER + '/data/train/',
|
259 |
+
|
260 |
+
},
|
261 |
+
'14': {
|
262 |
+
'json': ROOT_FOLDER + '/json/digits-14.json',
|
263 |
+
'data': ROOT_FOLDER + '/data/train/',
|
264 |
+
|
265 |
+
},
|
266 |
+
'17': {
|
267 |
+
'json': ROOT_FOLDER + '/annotations/digits_04-17.json',
|
268 |
+
'data': ROOT_FOLDER + '/images/train/',
|
269 |
+
|
270 |
+
},
|
271 |
+
},
|
272 |
+
'val': {
|
273 |
+
'16': {
|
274 |
+
'json': ROOT_FOLDER + '/annotations/digits_02-16.json',
|
275 |
+
'data': ROOT_FOLDER + '/images/val/',
|
276 |
+
|
277 |
+
},
|
278 |
+
}
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
if __name__ == '__main__':
|
283 |
+
|
284 |
+
st.title('DIGITS')
|
285 |
+
|
286 |
+
model_name = 'model_final' # '30im_10cl_2000it_faster_rcnn_R_50_FPN_3x_None'
|
287 |
+
model_name = 'model_0003999'
|
288 |
+
# model_name = 'model_final_8000'
|
289 |
+
# model_name = 'model_final_4000_nms_01'
|
290 |
+
model_path = ROOT_FOLDER + 'output/' + model_name + '.pth'
|
291 |
+
|
292 |
+
YAML_FILE = 'Misc/cascade_mask_rcnn_R_50_FPN_3x.yaml'
|
293 |
+
# YAML_FILE = 'COCO-Detection/faster_rcnn_R_50_FPN_3x.yaml'
|
294 |
+
|
295 |
+
DATASET_NAME = model_name
|
296 |
+
|
297 |
+
val_dataset_name = DATASET_NAME + "_val_" + str(random.randint(1, 1000))
|
298 |
+
|
299 |
+
num_classes = '10cl' # 'poteklina' # '1cl'
|
300 |
+
dataset = '16' #
|
301 |
+
|
302 |
+
# MetadataCatalog.get(val_dataset_name).thing_classes = train_dct1['10cl']['cat_lst'] #["person", "dog"]
|
303 |
+
register_coco_instances(val_dataset_name, {}, train_dct1[num_classes]['val'][dataset]['json'],
|
304 |
+
train_dct1[num_classes]['val'][dataset]['data'])
|
305 |
+
dataset_dicts = DatasetCatalog.get(val_dataset_name)
|
306 |
+
|
307 |
+
filenames = []
|
308 |
+
uploaded_files = st.file_uploader("Choose a images", accept_multiple_files=True, type=["png", "jpg", "jpeg"])
|
309 |
+
|
310 |
+
num_ok = 0
|
311 |
+
num_nok = 0
|
312 |
+
for uploaded_file in uploaded_files:
|
313 |
+
|
314 |
+
image = Image.open(uploaded_file).convert("RGB")
|
315 |
+
# Convert PIL image to array
|
316 |
+
image = np.array(image)
|
317 |
+
|
318 |
+
img, predicted_digits = process_one_image(image, uploaded_file.name, YAML_FILE=YAML_FILE, path_to_model=model_path, THR = 0.7)
|
319 |
+
|
320 |
+
print(uploaded_file.name)
|
321 |
+
print(predicted_digits)
|
322 |
+
st.image(image)
|
323 |
+
|
324 |
+
wrong_indexes = []
|
325 |
+
result_in_string = ''
|
326 |
+
|
327 |
+
for el in predicted_digits:
|
328 |
+
result_in_string += el
|
329 |
+
|
330 |
+
if len(predicted_digits) >= 6:
|
331 |
+
for num, el in enumerate(uploaded_file.name[:6]):
|
332 |
+
|
333 |
+
if el != predicted_digits[num]:
|
334 |
+
wrong_indexes.append(num)
|
335 |
+
print(el, num)
|
336 |
+
else:
|
337 |
+
wrong_indexes = ['0']
|
338 |
+
|
339 |
+
status = 'NOK'
|
340 |
+
if len(wrong_indexes) == 0:
|
341 |
+
status = 'OK'
|
342 |
+
|
343 |
+
if status == 'OK':
|
344 |
+
num_ok +=1
|
345 |
+
else:
|
346 |
+
num_nok +=1
|
347 |
+
|
348 |
+
file_details = {"filename": uploaded_file.name, "detection_result": result_in_string,
|
349 |
+
"status": status}
|
350 |
+
|
351 |
+
st.write(file_details)
|
352 |
+
|
353 |
+
st.write('Точність визначення = ', num_ok /(num_ok + num_nok) * 100, ' %')
|
354 |
+
st.write('NOK = ', num_nok, 'OK = ', num_ok)
|