Created
May 9, 2025 06:49
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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