Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| from pathlib import Path | |
| from apps.functions import pdf_to_images, ensure_output_dir, get_temp_path, cleanup_temp | |
| from apps.services import SignatureDetector | |
| detector = SignatureDetector() | |
| ensure_output_dir("outputs") | |
| def process_pdf(pdf_file, conf_threshold, iou_threshold): | |
| if pdf_file is None: | |
| return [], "β οΈ Please upload a PDF file." | |
| detector.conf_threshold = conf_threshold | |
| detector.iou_threshold = iou_threshold | |
| pdf_path = pdf_file.name | |
| pages = pdf_to_images(pdf_path, dpi=200) | |
| signed_pages = [] | |
| summary_lines = [] | |
| total_signatures = 0 | |
| for page_num, img_bgr in pages: | |
| temp_path = get_temp_path(page_num) | |
| try: | |
| annotated_bgr, num_sigs = detector.detect(img_bgr, temp_path) | |
| finally: | |
| cleanup_temp(temp_path) | |
| if num_sigs > 0: | |
| annotated_rgb = cv2.cvtColor(annotated_bgr, cv2.COLOR_BGR2RGB) | |
| pil_img = Image.fromarray(annotated_rgb) | |
| signed_pages.append(pil_img) | |
| summary_lines.append(f"β Page {page_num}: {num_sigs} signature(s) detected") | |
| total_signatures += num_sigs | |
| else: | |
| summary_lines.append(f"β Page {page_num}: No signature found") | |
| if not signed_pages: | |
| summary_lines.append("\nπ No signatures found in this document.") | |
| else: | |
| summary_lines.append( | |
| f"\nπ Total: {total_signatures} signature(s) across {len(signed_pages)} page(s)" | |
| ) | |
| return signed_pages, "\n".join(summary_lines) | |
| with gr.Blocks( | |
| title="Signature Detector", | |
| theme=gr.themes.Base( | |
| primary_hue="green", | |
| neutral_hue="slate", | |
| font=gr.themes.GoogleFont("JetBrains Mono"), | |
| ), | |
| css=""" | |
| #header { | |
| text-align: center; | |
| padding: 2rem 0 1rem; | |
| border-bottom: 1px solid #334155; | |
| margin-bottom: 1.5rem; | |
| } | |
| #header h1 { font-size: 2rem; font-weight: 700; color: #22C55E; } | |
| #header p { color: #94A3B8; margin-top: 0.25rem; } | |
| .upload-box { border: 2px dashed #334155 !important; } | |
| #summary-box textarea { | |
| font-family: 'JetBrains Mono', monospace !important; | |
| font-size: 0.85rem !important; | |
| } | |
| """ | |
| ) as demo: | |
| gr.HTML(""" | |
| <div id="header"> | |
| <h1>ποΈ Signature Detector</h1> | |
| <p>Upload a PDF β pages containing signatures will be highlighted</p> | |
| </div> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| pdf_input = gr.File( | |
| label="π Upload PDF", | |
| file_types=[".pdf"], | |
| elem_classes=["upload-box"] | |
| ) | |
| conf_slider = gr.Slider( | |
| minimum=0.05, maximum=0.95, value=0.2, step=0.05, | |
| label="Confidence Threshold", | |
| info="Deteksi dengan score di bawah ini akan diabaikan" | |
| ) | |
| iou_slider = gr.Slider( | |
| minimum=0.1, maximum=0.9, value=0.45, step=0.05, | |
| label="IOU Threshold (NMS)", | |
| info="Semakin tinggi = lebih sedikit penggabungan bbox" | |
| ) | |
| run_btn = gr.Button("π Detect Signatures", variant="primary", size="lg") | |
| summary_output = gr.Textbox(label="π Detection Summary", lines=10, interactive=False) | |
| with gr.Column(scale=2): | |
| gallery_output = gr.Gallery( | |
| label="πΈ Pages with Signatures", | |
| columns=2, | |
| height=600, | |
| object_fit="contain", | |
| show_label=True | |
| ) | |
| run_btn.click( | |
| fn=process_pdf, | |
| inputs=[pdf_input, conf_slider, iou_slider], | |
| outputs=[gallery_output, summary_output], | |
| show_progress=True | |
| ) | |
| gr.HTML(""" | |
| <div style="text-align:center; padding: 1rem; color: #475569; font-size: 0.8rem; margin-top: 1rem;"> | |
| Powered by YOLOv8 Β· yolov8s-signature-detector | |
| </div> | |
| """) |