""" Gradio demo for TypoRef YOLOv8 Historical Document Detector. This script defines a simple Gradio interface that allows a user to upload an image of a historical document page. The interface loads a YOLOv8 object detection model and applies it to the input image, overlaying bounding boxes around detected ornaments, typography and other decorative elements. The resulting annotated image is returned for display in the browser. By default the demo uses a small pretrained YOLOv8 model from the ``ultralytics`` repository (``yolov8n``) so that it can run without any custom weights. If you have uploaded your own fine‑tuned weights to Hugging Face (e.g. ``martinbadrous/TypoRef-YOLOv8-Historical-Document-Detection``) you can replace the ``model_path`` value below with the repository ID for your model. The ``ultralytics`` package will automatically load the model from Hugging Face when given a repo ID. To launch the demo locally run ``python app.py``. When running as a Hugging Face Space this file will be executed automatically. """ import gradio as gr from PIL import Image from ultralytics import YOLO def load_model(model_path: str = "ultralytics/yolov8n.pt") -> YOLO: """Load a YOLOv8 model from a given path or Hugging Face repo. Args: model_path: Either a local path to a ``.pt`` file or a Hugging Face model repo ID. Defaults to the ultralytics YOLOv8 nano model. Returns: An instance of ``ultralytics.YOLO`` ready for inference. """ model = YOLO(model_path) return model def detect_objects(img: Image.Image, model: YOLO) -> Image.Image: """Run object detection on a single image and return a plotted result. The YOLOv8 model returns a list of ``Ultralytics.Results`` objects. The first element contains the detections for the provided image. The ``plot`` method draws the bounding boxes and class labels onto a numpy array. The array is then converted back into a PIL image for display in the Gradio interface. Args: img: Input PIL image of a document page. model: A loaded YOLOv8 model. Returns: PIL image with detection boxes overlaid. """ results = model(img) res = results[0] plotted = res.plot() return Image.fromarray(plotted) def build_interface() -> gr.Interface: """Construct and return the Gradio interface for the detection demo.""" model = load_model("ultralytics/yolov8n.pt") def _predict(image: Image.Image) -> Image.Image: return detect_objects(image, model) title = "TypoRef YOLOv8: Historical Document Ornament Detection" description = ( "Upload a scanned page from a historical book to see how a YOLOv8 model " "detects graphical ornaments, typography and decorations. This demo " "illustrates cultural heritage AI applied to the TypoRef dataset (16th–18th " "century prints). Replace the underlying model with your own fine‑tuned " "weights by modifying the `model_path` in `app.py`." ) iface = gr.Interface( fn=_predict, inputs=gr.Image(type="pil", label="Upload a document page"), outputs=gr.Image(type="pil", label="Detected ornaments & typography"), title=title, description=description, allow_flagging="never", ) return iface if __name__ == "__main__": interface = build_interface() interface.launch()