nishanth-saka commited on
Commit
f4c65f1
Β·
verified Β·
1 Parent(s): 27c6775
Files changed (1) hide show
  1. app.py +5 -19
app.py CHANGED
@@ -4,26 +4,17 @@ import numpy as np
4
  from PIL import Image
5
 
6
  def flatten_image(img, points):
7
- """
8
- img: PIL.Image
9
- points: list of (x, y) tuples in order [TL, TR, BR, BL]
10
- """
11
  if img is None or not points or len(points) != 4:
12
  return None, "Please click exactly 4 points (TL, TR, BR, BL)."
13
 
14
- # Convert to numpy array
15
  image_np = np.array(img)
16
  h, w = image_np.shape[:2]
17
-
18
- # Convert input points to float32 numpy array
19
  src_pts = np.array(points, dtype=np.float32)
20
 
21
- # Compute output rectangle size using distances
22
  width_top = np.linalg.norm(src_pts[0] - src_pts[1])
23
  width_bottom = np.linalg.norm(src_pts[3] - src_pts[2])
24
  height_left = np.linalg.norm(src_pts[0] - src_pts[3])
25
  height_right = np.linalg.norm(src_pts[1] - src_pts[2])
26
-
27
  max_width = int(max(width_top, width_bottom))
28
  max_height = int(max(height_left, height_right))
29
 
@@ -34,21 +25,16 @@ def flatten_image(img, points):
34
  [0, max_height - 1]
35
  ], dtype=np.float32)
36
 
37
- # Compute homography
38
  M = cv2.getPerspectiveTransform(src_pts, dst_pts)
39
-
40
- # Apply perspective warp
41
  warped = cv2.warpPerspective(image_np, M, (max_width, max_height), flags=cv2.INTER_CUBIC)
42
-
43
- warped_pil = Image.fromarray(warped)
44
- return warped_pil, None
45
 
46
 
47
  with gr.Blocks() as demo:
48
  gr.Markdown("## πŸ“Έ Perspective Flatten Tool\nUpload an image, click 4 corners (Top-Left β†’ Top-Right β†’ Bottom-Right β†’ Bottom-Left), then flatten!")
49
 
50
  with gr.Row():
51
- input_image = gr.Image(label="Upload Image", tool="select", type="pil")
52
  output_image = gr.Image(label="Flattened Output")
53
 
54
  coords = gr.State([])
@@ -56,17 +42,17 @@ with gr.Blocks() as demo:
56
  def collect_points(evt: gr.SelectData, points):
57
  if points is None:
58
  points = []
59
- points.append(evt.index) # evt.index returns (x, y)
60
  if len(points) > 4:
61
- points = points[-4:] # keep only last 4
62
  return points, f"Selected {len(points)}/4 points: {points}"
63
 
64
  points_output = gr.Textbox(label="Selected Points", interactive=False)
65
 
 
66
  input_image.select(fn=collect_points, inputs=coords, outputs=[coords, points_output])
67
 
68
  flatten_btn = gr.Button("πŸ”„ Flatten Image")
69
-
70
  error_box = gr.Textbox(label="Messages", interactive=False)
71
 
72
  flatten_btn.click(fn=flatten_image, inputs=[input_image, coords], outputs=[output_image, error_box])
 
4
  from PIL import Image
5
 
6
  def flatten_image(img, points):
 
 
 
 
7
  if img is None or not points or len(points) != 4:
8
  return None, "Please click exactly 4 points (TL, TR, BR, BL)."
9
 
 
10
  image_np = np.array(img)
11
  h, w = image_np.shape[:2]
 
 
12
  src_pts = np.array(points, dtype=np.float32)
13
 
 
14
  width_top = np.linalg.norm(src_pts[0] - src_pts[1])
15
  width_bottom = np.linalg.norm(src_pts[3] - src_pts[2])
16
  height_left = np.linalg.norm(src_pts[0] - src_pts[3])
17
  height_right = np.linalg.norm(src_pts[1] - src_pts[2])
 
18
  max_width = int(max(width_top, width_bottom))
19
  max_height = int(max(height_left, height_right))
20
 
 
25
  [0, max_height - 1]
26
  ], dtype=np.float32)
27
 
 
28
  M = cv2.getPerspectiveTransform(src_pts, dst_pts)
 
 
29
  warped = cv2.warpPerspective(image_np, M, (max_width, max_height), flags=cv2.INTER_CUBIC)
30
+ return Image.fromarray(warped), None
 
 
31
 
32
 
33
  with gr.Blocks() as demo:
34
  gr.Markdown("## πŸ“Έ Perspective Flatten Tool\nUpload an image, click 4 corners (Top-Left β†’ Top-Right β†’ Bottom-Right β†’ Bottom-Left), then flatten!")
35
 
36
  with gr.Row():
37
+ input_image = gr.Image(label="Upload Image", type="pil")
38
  output_image = gr.Image(label="Flattened Output")
39
 
40
  coords = gr.State([])
 
42
  def collect_points(evt: gr.SelectData, points):
43
  if points is None:
44
  points = []
45
+ points.append(evt.index) # evt.index = (x, y)
46
  if len(points) > 4:
47
+ points = points[-4:]
48
  return points, f"Selected {len(points)}/4 points: {points}"
49
 
50
  points_output = gr.Textbox(label="Selected Points", interactive=False)
51
 
52
+ # The .select event still works; we just don’t declare tool="select"
53
  input_image.select(fn=collect_points, inputs=coords, outputs=[coords, points_output])
54
 
55
  flatten_btn = gr.Button("πŸ”„ Flatten Image")
 
56
  error_box = gr.Textbox(label="Messages", interactive=False)
57
 
58
  flatten_btn.click(fn=flatten_image, inputs=[input_image, coords], outputs=[output_image, error_box])