Spaces:
Sleeping
Sleeping
File size: 4,489 Bytes
f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 340c680 f725299 8e67fbc f725299 8e67fbc f725299 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
"""
This script creates a Gradio GUI for detecting and classifying signature blocks in document images
using the SignatureBlockModel. It loads example images from the /assets directory, displays
bounding boxes in the result image, and shows signature crops with labels in a gallery.
"""
import gradio as gr
import numpy as np
from PIL import Image
from typing import Tuple, List
import os
from scripts.signature_blocks import SignatureBlockModel
ASSETS_DIR = os.path.join(os.path.dirname(__file__), "assets")
def process_image(
image: np.ndarray,
) -> Tuple[np.ndarray, str, List[Tuple[np.ndarray, str]]]:
"""
Process an input image using the SignatureBlockModel.
Args:
image (np.ndarray): Input image as a numpy array.
Returns:
Tuple[np.ndarray, str, List[Tuple[np.ndarray, str]]]: Processed image, status, and list of crops with labels.
"""
# Convert numpy array to PIL Image
pil_image = Image.fromarray(image)
# Initialize the model
model = SignatureBlockModel(pil_image)
# Get processed image with boxes
image_with_boxes = model.draw_boxes()
# Get signature crops
signature_crops = create_signature_crops(model)
# Determine status
labels = model.get_labels()
if not labels.any():
status = "Unsigned"
elif all(label == 1 for label in labels):
status = "Fully Executed"
elif all(label == 2 for label in labels):
status = "Unsigned"
else:
status = "Partially Executed"
return np.array(image_with_boxes), status, signature_crops
def create_signature_crops(model: SignatureBlockModel) -> List[Tuple[np.ndarray, str]]:
"""
Create individual images for each signature crop with label and score information.
Args:
model (SignatureBlockModel): The initialized SignatureBlockModel.
Returns:
List[Tuple[np.ndarray, str]]: List of tuples containing crop images and labels.
"""
boxes = model.get_boxes()
scores = model.get_scores()
labels = model.get_labels()
classes = model.classes
crop_data = []
for box, label, score in zip(boxes, labels, scores):
crop = model.extract_box(box)
# resized_crop = resize_crop(crop)
label_text = f"{classes[label]}, Score: {score:.2f}"
crop_data.append((crop, label_text))
return crop_data
def resize_crop(crop: np.ndarray, max_height: int = 200) -> np.ndarray:
"""
Resize a crop to a maximum height while maintaining aspect ratio.
Args:
crop (np.ndarray): Input crop as a numpy array.
max_height (int): Maximum height for the crop.
Returns:
np.ndarray: Resized crop.
"""
crop_image = Image.fromarray(crop)
aspect_ratio = crop_image.width / crop_image.height
new_height = min(crop_image.height, max_height)
new_width = int(new_height * aspect_ratio)
resized_crop = crop_image.resize((new_width, new_height), Image.LANCZOS)
return np.array(resized_crop)
def load_examples():
"""
Load example images from the /assets directory.
Returns:
List[List[str]]: List of example image paths.
"""
examples = []
for filename in os.listdir(ASSETS_DIR):
if filename.lower().endswith((".png", ".jpg", ".jpeg")):
examples.append([os.path.join(ASSETS_DIR, filename)])
return examples
with gr.Blocks() as demo:
gr.Markdown("# Signature Block Detection")
gr.Markdown("Upload a document image to detect and classify signature blocks.")
with gr.Row():
input_image = gr.Image(label="Upload Document Image", type="numpy", height=500)
output_image = gr.Image(label="Processed Image", type="numpy", height=500)
signature_crops = gr.Gallery(
label="Signature Crops",
show_label=True,
elem_id="gallery",
columns=[6],
rows=[1],
allow_preview=True,
object_fit="contain",
height=250,
)
with gr.Row():
status_box = gr.Textbox(label="Document Status")
process_btn = gr.Button("Process Image")
examples = gr.Examples(
examples=load_examples(),
fn=process_image,
inputs=input_image,
outputs=[output_image, status_box, signature_crops],
cache_examples=True,
)
process_btn.click(
fn=process_image,
inputs=input_image,
outputs=[output_image, status_box, signature_crops],
)
if __name__ == "__main__":
demo.launch()
|