|
import gradio as gr |
|
import cv2 |
|
import numpy as np |
|
import os |
|
import tempfile |
|
from ultralytics import YOLO |
|
|
|
|
|
model_path = "latex2layout_object_detection_yolov8.pt" |
|
model = YOLO(model_path) |
|
|
|
def detect_and_visualize(image): |
|
""" |
|
Perform layout detection on the uploaded image using the Latex2Layout model and visualize the results. |
|
|
|
Args: |
|
image: The uploaded image |
|
|
|
Returns: |
|
annotated_image: Image with detection boxes |
|
layout_annotations: Annotations in YOLO format |
|
""" |
|
if image is None: |
|
return None, "Error: No image uploaded." |
|
|
|
|
|
results = model(image) |
|
result = results[0] |
|
|
|
|
|
annotated_image = image.copy() |
|
layout_annotations = [] |
|
|
|
|
|
img_height, img_width = image.shape[:2] |
|
|
|
|
|
for box in result.boxes: |
|
x1, y1, x2, y2 = map(int, box.xyxy[0].cpu().numpy()) |
|
conf = float(box.conf[0]) |
|
cls_id = int(box.cls[0]) |
|
cls_name = result.names[cls_id] |
|
|
|
|
|
color = tuple(np.random.randint(0, 255, 3).tolist()) |
|
|
|
|
|
cv2.rectangle(annotated_image, (x1, y1), (x2, y2), color, 2) |
|
label = f'{cls_name} {conf:.2f}' |
|
(label_width, label_height), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1) |
|
cv2.rectangle(annotated_image, (x1, y1-label_height-5), (x1+label_width, y1), color, -1) |
|
cv2.putText(annotated_image, label, (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1) |
|
|
|
|
|
x_center = (x1 + x2) / (2 * img_width) |
|
y_center = (y1 + y2) / (2 * img_height) |
|
width = (x2 - x1) / img_width |
|
height = (y2 - y1) / img_height |
|
layout_annotations.append(f"{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}") |
|
|
|
return annotated_image, "\n".join(layout_annotations) |
|
|
|
def save_layout_annotations(layout_annotations_str): |
|
""" |
|
Save layout annotations to a temporary file and return the file path. |
|
|
|
Args: |
|
layout_annotations_str: Annotations string in YOLO format |
|
|
|
Returns: |
|
file_path: Path to the saved annotation file |
|
""" |
|
if not layout_annotations_str: |
|
return None |
|
|
|
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".txt") |
|
with open(temp_file.name, "w") as f: |
|
f.write(layout_annotations_str) |
|
return temp_file.name |
|
|
|
|
|
custom_css = """ |
|
.container { max-width: 1200px; margin: auto; } |
|
.button-primary { background-color: #4CAF50; color: white; } |
|
.button-secondary { background-color: #008CBA; color: white; } |
|
.gr-image { border: 2px solid #ddd; border-radius: 5px; } |
|
.gr-textbox { font-family: monospace; } |
|
""" |
|
|
|
|
|
with gr.Blocks( |
|
title="Latex2Layout Detection", |
|
theme=gr.themes.Default(), |
|
css=custom_css |
|
) as demo: |
|
|
|
gr.Markdown( |
|
""" |
|
# Latex2Layout Layout Detection |
|
Upload an image to detect layout elements using the **Latex2Layout** model. View the annotated image and download the results in YOLO format. |
|
""" |
|
) |
|
|
|
|
|
with gr.Row(): |
|
|
|
with gr.Column(scale=1): |
|
input_image = gr.Image( |
|
label="Upload Image", |
|
type="numpy", |
|
height=400, |
|
elem_classes="gr-image" |
|
) |
|
detect_btn = gr.Button( |
|
"Start Detection", |
|
variant="primary", |
|
elem_classes="button-primary" |
|
) |
|
gr.Markdown("**Tip**: Upload a clear image for optimal detection results.") |
|
|
|
|
|
with gr.Column(scale=1): |
|
output_image = gr.Image( |
|
label="Detection Results", |
|
height=400, |
|
elem_classes="gr-image" |
|
) |
|
layout_annotations = gr.Textbox( |
|
label="Layout Annotations (YOLO Format)", |
|
lines=10, |
|
max_lines=15, |
|
elem_classes="gr-textbox" |
|
) |
|
download_btn = gr.Button( |
|
"Download Annotations", |
|
variant="secondary", |
|
elem_classes="button-secondary" |
|
) |
|
download_file = gr.File( |
|
label="Download File", |
|
interactive=False |
|
) |
|
|
|
|
|
with gr.Row(): |
|
gr.Button("Load Example Image").click( |
|
fn=lambda: cv2.imread("example_image.jpg"), |
|
outputs=input_image |
|
) |
|
|
|
|
|
detect_btn.click( |
|
fn=detect_and_visualize, |
|
inputs=input_image, |
|
outputs=[output_image, layout_annotations], |
|
_js="() => { document.querySelector('.button-primary').innerText = 'Processing...'; }", |
|
show_progress=True |
|
).then( |
|
fn=lambda: gr.update(value="Start Detection"), |
|
outputs=detect_btn, |
|
_js="() => { document.querySelector('.button-primary').innerText = 'Start Detection'; }" |
|
) |
|
|
|
download_btn.click( |
|
fn=save_layout_annotations, |
|
inputs=layout_annotations, |
|
outputs=download_file |
|
) |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch() |
|
|