regen / app.py
nishanth-saka's picture
FIX
d6ccb8b verified
raw
history blame
2.22 kB
import gradio as gr
import cv2
import numpy as np
from PIL import Image
def flatten_image(img, points):
if img is None or not points or len(points) != 4:
return None, "Please click exactly 4 points (TL, TR, BR, BL)."
image_np = np.array(img)
h, w = image_np.shape[:2]
src_pts = np.array(points, dtype=np.float32)
width_top = np.linalg.norm(src_pts[0] - src_pts[1])
width_bottom = np.linalg.norm(src_pts[3] - src_pts[2])
height_left = np.linalg.norm(src_pts[0] - src_pts[3])
height_right = np.linalg.norm(src_pts[1] - src_pts[2])
max_width = int(max(width_top, width_bottom))
max_height = int(max(height_left, height_right))
dst_pts = np.array([
[0, 0],
[max_width - 1, 0],
[max_width - 1, max_height - 1],
[0, max_height - 1]
], dtype=np.float32)
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped = cv2.warpPerspective(image_np, M, (max_width, max_height), flags=cv2.INTER_CUBIC)
return Image.fromarray(warped), None
with gr.Blocks() as demo:
gr.Markdown("## ๐Ÿ“ธ Perspective Flatten Tool\nUpload an image, click 4 corners (Top-Left โ†’ Top-Right โ†’ Bottom-Right โ†’ Bottom-Left), then flatten!")
with gr.Row():
input_image = gr.Image(label="Upload Image", type="pil")
output_image = gr.Image(label="Flattened Output")
coords = gr.State([])
def collect_points(evt: gr.SelectData, points):
if points is None:
points = []
points.append(evt.index) # evt.index = (x, y)
if len(points) > 4:
points = points[-4:]
return points, f"Selected {len(points)}/4 points: {points}"
points_output = gr.Textbox(label="Selected Points", interactive=False)
# The .select event still works; we just donโ€™t declare tool="select"
input_image.select(fn=collect_points, inputs=coords, outputs=[coords, points_output])
flatten_btn = gr.Button("๐Ÿ”„ Flatten Image")
error_box = gr.Textbox(label="Messages", interactive=False)
flatten_btn.click(fn=flatten_image, inputs=[input_image, coords], outputs=[output_image, error_box])
gr.Markdown("Tip: Re-upload image to reset point selection.")
demo.launch()