|
import gradio as gr |
|
from core import Ladeco |
|
from matplotlib.figure import Figure |
|
import matplotlib.pyplot as plt |
|
import matplotlib as mpl |
|
import spaces |
|
from PIL import Image |
|
|
|
|
|
plt.rcParams['figure.facecolor'] = '#0b0f19' |
|
plt.rcParams['text.color'] = '#aab6cc' |
|
ladeco = Ladeco() |
|
|
|
|
|
@spaces.GPU |
|
def infer(img: str) -> tuple[Figure, Figure]: |
|
out = ladeco.predict(img) |
|
|
|
seg = out.visualize(level=2)[0].image |
|
colormap = out.color_map(level=2) |
|
|
|
area = out.area()[0] |
|
|
|
|
|
colors = [] |
|
l2_area = {} |
|
for labelname, area_ratio in area.items(): |
|
if labelname.startswith("l2") and area_ratio > 0: |
|
colors.append(colormap[labelname]) |
|
labelname = labelname.replace("l2_", "").capitalize() |
|
l2_area[labelname] = area_ratio |
|
|
|
pie = plot_pie(l2_area, colors=colors) |
|
|
|
seg.set_dpi(96) |
|
seg.set_size_inches(256/96, 256/96) |
|
|
|
pie.set_dpi(96) |
|
pie.set_size_inches(256/96, 256/96) |
|
|
|
return seg, pie |
|
|
|
|
|
def plot_pie(data: dict[str, float], colors=None) -> Figure: |
|
fig, ax = plt.subplots() |
|
|
|
labels = list(data.keys()) |
|
sizes = list(data.values()) |
|
|
|
*_, autotexts = ax.pie(sizes, labels=labels, autopct="%1.1f%%", colors=colors) |
|
|
|
for percent_text in autotexts: |
|
percent_text.set_color("k") |
|
|
|
ax.axis("equal") |
|
|
|
return fig |
|
|
|
|
|
def choose_example(imgpath: str) -> gr.Image: |
|
img = Image.open(imgpath) |
|
width, height = img.size |
|
ratio = 512 / max(width, height) |
|
img = img.resize((int(width * ratio), int(height * ratio))) |
|
return gr.Image(value=img, label="輸入影像(不支援 SVG 格式)", type="filepath") |
|
|
|
|
|
css = """ |
|
.reference { |
|
text-align: center; |
|
font-size: 1.2em; |
|
color: #d1d5db; |
|
margin-bottom: 20px; |
|
} |
|
.reference a { |
|
color: #FB923C; |
|
text-decoration: none; |
|
} |
|
.reference a:hover { |
|
text-decoration: underline; |
|
color: #FB923C; |
|
} |
|
.description { |
|
text-align: center; |
|
font-size: 1.1em; |
|
color: #d1d5db; |
|
margin-bottom: 25px; |
|
} |
|
.footer { |
|
text-align: center; |
|
margin-top: 30px; |
|
padding-top: 20px; |
|
border-top: 1px solid #ddd; |
|
color: #d1d5db; |
|
font-size: 14px; |
|
} |
|
.main-title { |
|
font-size: 24px; |
|
font-weight: bold; |
|
text-align: center; |
|
margin-bottom: 20px; |
|
} |
|
.selected-image { |
|
height: 756px; |
|
} |
|
.example-image { |
|
height: 220px; |
|
padding: 25px; |
|
} |
|
""".strip() |
|
theme = gr.themes.Base( |
|
primary_hue="orange", |
|
secondary_hue="cyan", |
|
neutral_hue="gray", |
|
).set( |
|
body_text_color='*neutral_100', |
|
body_text_color_subdued='*neutral_600', |
|
background_fill_primary='*neutral_950', |
|
background_fill_secondary='*neutral_600', |
|
border_color_accent='*secondary_800', |
|
color_accent='*primary_50', |
|
color_accent_soft='*secondary_800', |
|
code_background_fill='*neutral_700', |
|
block_background_fill_dark='*body_background_fill', |
|
block_info_text_color='#6b7280', |
|
block_label_text_color='*neutral_300', |
|
block_label_text_weight='700', |
|
block_title_text_color='*block_label_text_color', |
|
block_title_text_weight='300', |
|
panel_background_fill='*neutral_800', |
|
table_text_color_dark='*secondary_800', |
|
checkbox_background_color_selected='*primary_500', |
|
checkbox_label_background_fill='*neutral_500', |
|
checkbox_label_background_fill_hover='*neutral_700', |
|
checkbox_label_text_color='*neutral_200', |
|
input_background_fill='*neutral_700', |
|
input_background_fill_focus='*neutral_600', |
|
slider_color='*primary_500', |
|
table_even_background_fill='*neutral_700', |
|
table_odd_background_fill='*neutral_600', |
|
table_row_focus='*neutral_800' |
|
) |
|
with gr.Blocks(css=css, theme=theme) as demo: |
|
gr.HTML( |
|
""" |
|
<div class="main-title">LaDeco 景觀環境影像語意分析模型</div> |
|
<div class="reference"> |
|
引用資料: |
|
<a href="https://www.sciencedirect.com/science/article/pii/S1574954123003187" target="_blank"> |
|
Li-Chih Ho (2023), LaDeco: A Tool to Analyze Visual Landscape Elements, Ecological Informatics, vol. 78. |
|
</a> |
|
</div> |
|
""".strip() |
|
) |
|
with gr.Row(equal_height=True): |
|
with gr.Group(): |
|
img = gr.Image( |
|
label="輸入影像(不支援 SVG 格式)", |
|
type="filepath", |
|
height="256px", |
|
|
|
) |
|
gr.Label("範例影像", show_label=False) |
|
with gr.Row(): |
|
ex1 = gr.Image( |
|
value="examples/beach.jpg", |
|
show_label=False, |
|
type="filepath", |
|
elem_classes="example-image", |
|
interactive=False, |
|
show_download_button=False, |
|
show_fullscreen_button=False, |
|
show_share_button=False, |
|
) |
|
ex2 = gr.Image( |
|
value="examples/field.jpg", |
|
show_label=False, |
|
type="filepath", |
|
elem_classes="example-image", |
|
interactive=False, |
|
show_download_button=False, |
|
show_fullscreen_button=False, |
|
show_share_button=False, |
|
) |
|
ex3 = gr.Image( |
|
value="examples/sky.jpg", |
|
show_label=False, |
|
type="filepath", |
|
elem_classes="example-image", |
|
interactive=False, |
|
show_download_button=False, |
|
show_fullscreen_button=False, |
|
show_share_button=False, |
|
) |
|
|
|
with gr.Column(): |
|
seg = gr.Plot(label="語意分割") |
|
pie = gr.Plot(label="元素面積比例") |
|
|
|
start = gr.Button("開始", variant="primary") |
|
|
|
gr.HTML( |
|
""" |
|
<div class="footer"> |
|
© 2024 LaDeco 版權所有<br> |
|
開發者:何立智、楊哲睿 |
|
</div> |
|
""".strip() |
|
) |
|
|
|
start.click(fn=infer, inputs=img, outputs=[seg, pie]) |
|
|
|
ex1.select(fn=choose_example, inputs=ex1, outputs=img) |
|
ex2.select(fn=choose_example, inputs=ex2, outputs=img) |
|
ex3.select(fn=choose_example, inputs=ex3, outputs=img) |
|
|
|
if __name__ == "__main__": |
|
demo.launch() |
|
|