Spaces:
Running
Running
KB Teo
commited on
Commit
·
d866b52
1
Parent(s):
1f83e60
Update interface
Browse files- app.py +17 -45
- examples.py +10 -0
- predict.py +38 -0
- utils.py +29 -0
app.py
CHANGED
@@ -1,67 +1,39 @@
|
|
1 |
from typing import *
|
2 |
-
import importlib
|
3 |
-
from pathlib import Path
|
4 |
|
5 |
-
import cv2
|
6 |
import gradio as gr
|
7 |
-
import numpy as np
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
last_model_path: str = None
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
def predict_openvino(
|
17 |
-
image: Union[str, Path, np.ndarray],
|
18 |
-
model_path: Union[str, Path],
|
19 |
-
device: str,
|
20 |
-
threshold: float) -> Dict[str, np.ndarray]:
|
21 |
-
global inferencer, last_model_path
|
22 |
-
if not isinstance(inferencer, OpenVINOInferencer) or last_model_path != str(model_path):
|
23 |
-
inferencer = OpenVINOInferencer(
|
24 |
-
path = model_path,
|
25 |
-
device=device.upper()
|
26 |
-
)
|
27 |
-
last_model_path = str(model_path)
|
28 |
-
inferencer.metadata["pixel_threshold"] = threshold
|
29 |
-
return inferencer(image)
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
return cv2.drawContours(image.copy(), contours, -1, color, thickness)
|
34 |
-
|
35 |
-
def convert_to_heatmap(heatmap):
|
36 |
-
heatmap = cv2.applyColorMap((heatmap*255).astype("uint8"), cv2.COLORMAP_HSV)
|
37 |
-
return heatmap
|
38 |
-
|
39 |
-
def predict(image, threshold, device, model_dir):
|
40 |
-
outputs = predict_openvino(image, model_dir, device, threshold)
|
41 |
-
out_image = draw_contour(image, outputs["pred_mask"])
|
42 |
-
heatmap = convert_to_heatmap(outputs["anomaly_map"])
|
43 |
-
return out_image, heatmap
|
44 |
|
45 |
def launch():
|
46 |
-
input_image = gr.Image(
|
47 |
-
|
48 |
-
value="images/171436008_Fail.jpeg"
|
49 |
-
)
|
50 |
-
threshold = gr.Slider(value=5.5, step=0.1, label="Threshold")
|
51 |
devices = gr.Radio(
|
52 |
label="Device",
|
53 |
choices=["AUTO", "CPU", "GPU"],
|
54 |
value="CPU",
|
55 |
interactive=False
|
56 |
)
|
|
|
|
|
57 |
output_image = gr.Image(label="Output image")
|
58 |
output_heatmap = gr.Image(label="Heatmap")
|
59 |
-
|
60 |
intf = gr.Interface(
|
61 |
title="Anomaly Detection",
|
62 |
-
|
|
|
63 |
inputs=[input_image, threshold, devices, model],
|
64 |
-
outputs=[output_image, output_heatmap]
|
|
|
|
|
65 |
)
|
66 |
intf.launch()
|
67 |
|
|
|
1 |
from typing import *
|
|
|
|
|
2 |
|
|
|
3 |
import gradio as gr
|
|
|
4 |
|
5 |
+
from predict import predict_fn
|
6 |
+
from utils import populate_examples
|
|
|
7 |
|
8 |
+
description = """
|
9 |
+
Anomaly detection models are trained with only <span style="color:lime;font-weight:bold">normal</span> images,
|
10 |
+
and aimed to segment <span style="color:red;font-weight:bold">anomalies (deviations)</span> in input images.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
|
12 |
+
Scroll to bottom of this demo for a list of pretrained examples.
|
13 |
+
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
def launch():
|
16 |
+
input_image = gr.Image(label="Input image")
|
17 |
+
threshold = gr.Slider(value=1, step=0.1, label="Threshold")
|
|
|
|
|
|
|
18 |
devices = gr.Radio(
|
19 |
label="Device",
|
20 |
choices=["AUTO", "CPU", "GPU"],
|
21 |
value="CPU",
|
22 |
interactive=False
|
23 |
)
|
24 |
+
model = gr.Text(label="Model", interactive=False)
|
25 |
+
|
26 |
output_image = gr.Image(label="Output image")
|
27 |
output_heatmap = gr.Image(label="Heatmap")
|
28 |
+
|
29 |
intf = gr.Interface(
|
30 |
title="Anomaly Detection",
|
31 |
+
description=description,
|
32 |
+
fn=predict_fn,
|
33 |
inputs=[input_image, threshold, devices, model],
|
34 |
+
outputs=[output_image, output_heatmap],
|
35 |
+
examples=populate_examples(),
|
36 |
+
allow_flagging="never"
|
37 |
)
|
38 |
intf.launch()
|
39 |
|
examples.py
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""List of example inputs, a dictionary where
|
2 |
+
key is model_name, and value is a list of (image_name, threshold).
|
3 |
+
"""
|
4 |
+
|
5 |
+
examples = {
|
6 |
+
"glass-tr-5-ov":
|
7 |
+
[
|
8 |
+
("171436008_Fail.jpeg", 5.5),
|
9 |
+
],
|
10 |
+
}
|
predict.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import *
|
2 |
+
from pathlib import Path
|
3 |
+
|
4 |
+
import cv2
|
5 |
+
from inference.openvino import OpenVINOInferencer
|
6 |
+
import numpy as np
|
7 |
+
|
8 |
+
inferencer = None
|
9 |
+
last_model_path: str = None
|
10 |
+
|
11 |
+
def predict_openvino(
|
12 |
+
image: Union[str, Path, np.ndarray],
|
13 |
+
model_path: Union[str, Path],
|
14 |
+
device: str,
|
15 |
+
threshold: float) -> Dict[str, np.ndarray]:
|
16 |
+
global inferencer, last_model_path
|
17 |
+
if not isinstance(inferencer, OpenVINOInferencer) or last_model_path != str(model_path):
|
18 |
+
inferencer = OpenVINOInferencer(
|
19 |
+
path = model_path,
|
20 |
+
device=device.upper()
|
21 |
+
)
|
22 |
+
last_model_path = str(model_path)
|
23 |
+
inferencer.metadata["pixel_threshold"] = threshold
|
24 |
+
return inferencer(image)
|
25 |
+
|
26 |
+
def draw_contour(image, mask, color=(255,0,0), thickness=3):
|
27 |
+
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
|
28 |
+
return cv2.drawContours(image.copy(), contours, -1, color, thickness)
|
29 |
+
|
30 |
+
def convert_to_heatmap(heatmap):
|
31 |
+
heatmap = cv2.applyColorMap((heatmap*255).astype("uint8"), cv2.COLORMAP_HSV)
|
32 |
+
return heatmap
|
33 |
+
|
34 |
+
def predict_fn(image, threshold, device, model_dir):
|
35 |
+
outputs = predict_openvino(image, model_dir, device, threshold)
|
36 |
+
out_image = draw_contour(image, outputs["pred_mask"])
|
37 |
+
heatmap = convert_to_heatmap(outputs["anomaly_map"])
|
38 |
+
return out_image, heatmap
|
utils.py
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import *
|
2 |
+
import os
|
3 |
+
|
4 |
+
from examples import examples as exp_dict
|
5 |
+
|
6 |
+
MODEL_DIR = "models"
|
7 |
+
IMAGE_DIR = "images"
|
8 |
+
|
9 |
+
def get_models() -> List[str]:
|
10 |
+
"""List all model names in MODEL_DIR."""
|
11 |
+
model_names = []
|
12 |
+
for p in os.listdir(MODEL_DIR):
|
13 |
+
if os.path.isdir(os.path.join(MODEL_DIR, p)):
|
14 |
+
model_names.append(p)
|
15 |
+
return model_names
|
16 |
+
|
17 |
+
def populate_examples() -> List[Any]:
|
18 |
+
"""Populate example inputs into a list."""
|
19 |
+
examples = []
|
20 |
+
for m in get_models():
|
21 |
+
if m in exp_dict:
|
22 |
+
for img, thres in exp_dict[m]:
|
23 |
+
examples.append([
|
24 |
+
f"{IMAGE_DIR}/{m}/{img}",
|
25 |
+
thres,
|
26 |
+
"CPU",
|
27 |
+
f"{MODEL_DIR}/{m}"
|
28 |
+
])
|
29 |
+
return examples
|