Spaces:
Sleeping
Sleeping
update: dynamic html support
Browse files
app.py
CHANGED
@@ -1,56 +1,68 @@
|
|
1 |
import gradio as gr
|
|
|
2 |
import os
|
|
|
3 |
import time
|
|
|
4 |
import cv2
|
5 |
import numpy as np
|
6 |
-
from PIL import Image
|
7 |
from yolov5 import xai_yolov5
|
8 |
from yolov8 import xai_yolov8s
|
9 |
|
10 |
-
#
|
11 |
sample_images = {
|
12 |
"Sample 1": os.path.join(os.getcwd(), "data/xai/sample1.jpeg"),
|
13 |
"Sample 2": os.path.join(os.getcwd(), "data/xai/sample2.jpg"),
|
14 |
}
|
15 |
-
preloaded_model_file = os.path.join(os.getcwd(), "weight_files/yolov5.onnx") # Update as needed
|
16 |
-
netron_html_file = os.path.join(os.getcwd(), "model_visualization.html") # Netron exported file
|
17 |
|
18 |
-
#
|
|
|
|
|
19 |
def load_sample_image(sample_name):
|
20 |
image_path = sample_images.get(sample_name)
|
21 |
if image_path and os.path.exists(image_path):
|
22 |
return Image.open(image_path)
|
23 |
return None
|
24 |
|
25 |
-
# Process image with YOLO models
|
26 |
def process_image(sample_choice, uploaded_image, yolo_versions):
|
|
|
27 |
if uploaded_image is not None:
|
28 |
image = uploaded_image
|
29 |
else:
|
30 |
image = load_sample_image(sample_choice)
|
31 |
|
|
|
32 |
image = np.array(image)
|
33 |
image = cv2.resize(image, (640, 640))
|
34 |
result_images = []
|
35 |
|
36 |
for yolo_version in yolo_versions:
|
37 |
if yolo_version == "yolov5":
|
38 |
-
result_images.append(xai_yolov5(image))
|
39 |
elif yolo_version == "yolov8s":
|
40 |
result_images.append(xai_yolov8s(image))
|
41 |
else:
|
42 |
-
result_images.append((Image.fromarray(image), f"{yolo_version} not
|
43 |
|
44 |
return result_images
|
45 |
|
46 |
-
|
47 |
-
def
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
# Custom CSS for styling (optional)
|
56 |
custom_css = """
|
@@ -63,13 +75,15 @@ custom_css = """
|
|
63 |
}
|
64 |
"""
|
65 |
|
66 |
-
# Gradio
|
67 |
with gr.Blocks(css=custom_css) as interface:
|
68 |
-
gr.Markdown("# XAI: Visualize Object Detection
|
69 |
|
|
|
70 |
default_sample = "Sample 1"
|
71 |
|
72 |
with gr.Row():
|
|
|
73 |
with gr.Column():
|
74 |
sample_selection = gr.Radio(
|
75 |
choices=list(sample_images.keys()),
|
@@ -78,10 +92,7 @@ with gr.Blocks(css=custom_css) as interface:
|
|
78 |
value=default_sample,
|
79 |
)
|
80 |
|
81 |
-
upload_image = gr.Image(
|
82 |
-
label="Upload an Image",
|
83 |
-
type="pil",
|
84 |
-
)
|
85 |
|
86 |
selected_models = gr.CheckboxGroup(
|
87 |
choices=["yolov5", "yolov8s"],
|
@@ -91,13 +102,14 @@ with gr.Blocks(css=custom_css) as interface:
|
|
91 |
|
92 |
run_button = gr.Button("Run", elem_id="run_button")
|
93 |
|
|
|
94 |
with gr.Column():
|
95 |
sample_display = gr.Image(
|
96 |
-
value=load_sample_image(default_sample),
|
97 |
label="Selected Sample Image",
|
98 |
)
|
99 |
|
100 |
-
# Results and Netron
|
101 |
with gr.Row():
|
102 |
result_gallery = gr.Gallery(
|
103 |
label="Results",
|
@@ -105,24 +117,26 @@ with gr.Blocks(css=custom_css) as interface:
|
|
105 |
rows=1,
|
106 |
height=500,
|
107 |
)
|
108 |
-
netron_display = gr.HTML(label="Model Architecture")
|
109 |
|
110 |
-
|
|
|
|
|
111 |
sample_selection.change(
|
112 |
fn=load_sample_image,
|
113 |
inputs=sample_selection,
|
114 |
outputs=sample_display,
|
115 |
)
|
116 |
|
|
|
117 |
run_button.click(
|
118 |
fn=process_image,
|
119 |
inputs=[sample_selection, upload_image, selected_models],
|
120 |
outputs=[result_gallery],
|
121 |
)
|
122 |
|
123 |
-
#
|
124 |
-
netron_display.value =
|
125 |
|
126 |
-
# Launch Gradio
|
127 |
if __name__ == "__main__":
|
128 |
interface.launch(share=True)
|
|
|
1 |
import gradio as gr
|
2 |
+
import netron
|
3 |
import os
|
4 |
+
import threading
|
5 |
import time
|
6 |
+
from PIL import Image
|
7 |
import cv2
|
8 |
import numpy as np
|
|
|
9 |
from yolov5 import xai_yolov5
|
10 |
from yolov8 import xai_yolov8s
|
11 |
|
12 |
+
# Sample images directory
|
13 |
sample_images = {
|
14 |
"Sample 1": os.path.join(os.getcwd(), "data/xai/sample1.jpeg"),
|
15 |
"Sample 2": os.path.join(os.getcwd(), "data/xai/sample2.jpg"),
|
16 |
}
|
|
|
|
|
17 |
|
18 |
+
# Preloaded model file path
|
19 |
+
preloaded_model_file = os.path.join(os.getcwd(), "weight_files/yolov5.onnx") # Example path
|
20 |
+
|
21 |
def load_sample_image(sample_name):
|
22 |
image_path = sample_images.get(sample_name)
|
23 |
if image_path and os.path.exists(image_path):
|
24 |
return Image.open(image_path)
|
25 |
return None
|
26 |
|
|
|
27 |
def process_image(sample_choice, uploaded_image, yolo_versions):
|
28 |
+
# Use uploaded or sample image
|
29 |
if uploaded_image is not None:
|
30 |
image = uploaded_image
|
31 |
else:
|
32 |
image = load_sample_image(sample_choice)
|
33 |
|
34 |
+
# Resize and process the image
|
35 |
image = np.array(image)
|
36 |
image = cv2.resize(image, (640, 640))
|
37 |
result_images = []
|
38 |
|
39 |
for yolo_version in yolo_versions:
|
40 |
if yolo_version == "yolov5":
|
41 |
+
result_images.append(xai_yolov5(image))
|
42 |
elif yolo_version == "yolov8s":
|
43 |
result_images.append(xai_yolov8s(image))
|
44 |
else:
|
45 |
+
result_images.append((Image.fromarray(image), f"{yolo_version} not implemented."))
|
46 |
|
47 |
return result_images
|
48 |
|
49 |
+
def start_netron_backend(model_file):
|
50 |
+
def serve_netron():
|
51 |
+
netron.start(model_file, port=8080) # Start Netron on port 8080
|
52 |
+
|
53 |
+
# Launch Netron in a separate thread
|
54 |
+
threading.Thread(target=serve_netron, daemon=True).start()
|
55 |
+
time.sleep(2) # Allow server to initialize
|
56 |
+
|
57 |
+
def view_netron_model():
|
58 |
+
# Ensure model exists
|
59 |
+
if not os.path.exists(preloaded_model_file):
|
60 |
+
return "Model file not found."
|
61 |
+
|
62 |
+
# Start Netron backend
|
63 |
+
start_netron_backend(preloaded_model_file)
|
64 |
+
return '<iframe src="http://localhost:8080/" width="100%" height="600px"></iframe>'
|
65 |
+
|
66 |
|
67 |
# Custom CSS for styling (optional)
|
68 |
custom_css = """
|
|
|
75 |
}
|
76 |
"""
|
77 |
|
78 |
+
# Gradio UI
|
79 |
with gr.Blocks(css=custom_css) as interface:
|
80 |
+
gr.Markdown("# XAI: Visualize Object Detection of Your Models")
|
81 |
|
82 |
+
# Default sample
|
83 |
default_sample = "Sample 1"
|
84 |
|
85 |
with gr.Row():
|
86 |
+
# Left: Select sample or upload image
|
87 |
with gr.Column():
|
88 |
sample_selection = gr.Radio(
|
89 |
choices=list(sample_images.keys()),
|
|
|
92 |
value=default_sample,
|
93 |
)
|
94 |
|
95 |
+
upload_image = gr.Image(label="Upload an Image", type="pil")
|
|
|
|
|
|
|
96 |
|
97 |
selected_models = gr.CheckboxGroup(
|
98 |
choices=["yolov5", "yolov8s"],
|
|
|
102 |
|
103 |
run_button = gr.Button("Run", elem_id="run_button")
|
104 |
|
105 |
+
# Right: Display sample image
|
106 |
with gr.Column():
|
107 |
sample_display = gr.Image(
|
108 |
+
value=load_sample_image(default_sample),
|
109 |
label="Selected Sample Image",
|
110 |
)
|
111 |
|
112 |
+
# Results and Netron
|
113 |
with gr.Row():
|
114 |
result_gallery = gr.Gallery(
|
115 |
label="Results",
|
|
|
117 |
rows=1,
|
118 |
height=500,
|
119 |
)
|
|
|
120 |
|
121 |
+
netron_display = gr.HTML(label="Model Visualization")
|
122 |
+
|
123 |
+
# Sample selection update
|
124 |
sample_selection.change(
|
125 |
fn=load_sample_image,
|
126 |
inputs=sample_selection,
|
127 |
outputs=sample_display,
|
128 |
)
|
129 |
|
130 |
+
# Process image
|
131 |
run_button.click(
|
132 |
fn=process_image,
|
133 |
inputs=[sample_selection, upload_image, selected_models],
|
134 |
outputs=[result_gallery],
|
135 |
)
|
136 |
|
137 |
+
# Netron model visualization
|
138 |
+
netron_display.value = view_netron_model()
|
139 |
|
140 |
+
# Launch Gradio app
|
141 |
if __name__ == "__main__":
|
142 |
interface.launch(share=True)
|