Skip to content

Instantly share code, notes, and snippets.

@BIGBALLON
Created May 9, 2025 06:49
Show Gist options
  • Save BIGBALLON/ce18dd2fb8ead69f08cdd10395ae7d47 to your computer and use it in GitHub Desktop.
Save BIGBALLON/ce18dd2fb8ead69f08cdd10395ae7d47 to your computer and use it in GitHub Desktop.
This Python script creates an interactive Gradio interface for annotating images with bounding boxes. Users can upload an image, click two points to draw a box, and view its coordinates and area ratio.
import gradio as gr
import numpy as np
# Global variable to store the first click coordinates
start_point = None
def draw_bounding_box(image: np.ndarray, event: gr.SelectData) -> tuple:
"""
Handle click events to draw a bounding box on the image.
Args:
image (np.ndarray): Input image as a NumPy array
event (gr.SelectData): Gradio event data containing click coordinates
Returns:
tuple: Contains:
- (image, annotations): Tuple of image and list of bounding box annotations
- str: Bounding box coordinates as text
- str: Area ratio of bounding box to image
"""
global start_point
x, y = event.index # Extract click coordinates
# First click: store starting point
if start_point is None:
start_point = (x, y)
return (image, []), "Click second point to complete bounding box", ""
# Second click: calculate bounding box
x0, y0 = start_point
x1, y1 = x, y
start_point = None # Reset for next bounding box
# Normalize coordinates to ensure top-left and bottom-right corners
x_min, x_max = sorted([x0, x1])
y_min, y_max = sorted([y0, y1])
bbox = (x_min, y_min, x_max, y_max)
# Create annotation in format [(bbox, label)]
annotations = [(bbox, "bounding_box")]
# Calculate area ratio
height, width = image.shape[:2]
bbox_area = (x_max - x_min) * (y_max - y_min)
image_area = width * height
area_ratio = bbox_area / image_area if image_area > 0 else 0
# Format output
bbox_text = f"Bounding Box: (x1={x_min}, y1={y_min}, x2={x_max}, y2={y_max})"
ratio_text = f"Area Ratio: {area_ratio:.4f}"
return (image, annotations), bbox_text, ratio_text
def create_interface() -> gr.Blocks:
"""
Create the Gradio interface for the bounding box annotation tool.
Returns:
gr.Blocks: Configured Gradio interface
"""
with gr.Blocks(title="Image Bounding Box Annotator") as demo:
gr.Markdown("""
# Image Bounding Box Annotation Tool
Upload an image and click two points to draw a bounding box.
The tool displays the box coordinates and its area ratio relative to the image.
""")
with gr.Row():
image_input = gr.Image(
type="numpy",
label="Input Image",
interactive=True,
height=400
)
annotated_image = gr.AnnotatedImage(
label="Annotated Output",
height=400
)
with gr.Row():
bbox_text = gr.Textbox(label="Bounding Box Coordinates", interactive=False)
ratio_text = gr.Textbox(label="Area Ratio", interactive=False)
# Bind click event to the image input
image_input.select(
fn=draw_bounding_box,
inputs=[image_input],
outputs=[annotated_image, bbox_text, ratio_text]
)
return demo
def main():
"""Launch the Gradio interface."""
try:
interface = create_interface()
interface.launch()
except Exception as e:
print(f"Error launching interface: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment