MalikShehram commited on
Commit
5ee48fa
·
verified ·
1 Parent(s): 67f0a0e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -24
app.py CHANGED
@@ -8,12 +8,9 @@ def reconstruct_shape(image):
8
 
9
  # Check if the image has an alpha (transparency) channel
10
  if image.shape[2] == 4:
11
- # Use the alpha channel to create a mask of the object
12
  mask = image[:, :, 3]
13
- # Get the color channels (RGB)
14
  color_img = image[:, :, :3]
15
  else:
16
- # If no alpha channel, assume a white or black background and threshold
17
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
18
  _, mask = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
19
  color_img = image
@@ -22,66 +19,66 @@ def reconstruct_shape(image):
22
  contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
23
 
24
  if not contours:
25
- return image # Return original if no shape is found
26
 
27
  # Find the largest contour (the main object)
28
  c = max(contours, key=cv2.contourArea)
29
 
30
- # Extract the average color of the original shape
31
  mean_val = cv2.mean(color_img, mask=mask)
32
- dominant_color = (int(mean_val[0]), int(mean_val[1]), int(mean_val[2]), 255) # RGBA
 
33
 
34
  # --- Shape Classification ---
35
- # Calculate bounding rectangle
36
  x, y, w, h = cv2.boundingRect(c)
37
  rect_area = w * h
38
 
39
- # Calculate minimum enclosing circle
40
  (cx, cy), radius = cv2.minEnclosingCircle(c)
41
  circle_area = np.pi * (radius ** 2)
42
-
43
- # Actual contour area
44
  contour_area = cv2.contourArea(c)
45
 
46
- # Determine which regular shape fits better by comparing area ratios
47
- # The one with the ratio closer to 1 is the likely original shape
48
  rect_ratio = contour_area / rect_area if rect_area > 0 else 0
49
  circle_ratio = contour_area / circle_area if circle_area > 0 else 0
50
 
51
- # Create a blank transparent canvas of the same size
52
  output_image = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
53
 
54
- # --- Shape Reconstruction ---
55
  if circle_ratio > rect_ratio:
56
- # Reconstruct as a Circle
57
  center = (int(cx), int(cy))
58
  cv2.circle(output_image, center, int(radius), dominant_color, -1)
59
- shape_detected = "Circle"
60
  else:
61
- # Reconstruct as a Rectangle/Square
62
- # Check if it's close to a square
63
  if 0.85 <= w / h <= 1.15:
64
- # Make it a perfect square
65
  side = max(w, h)
66
  cv2.rectangle(output_image, (x, y), (x + side, y + side), dominant_color, -1)
67
- shape_detected = "Square"
68
  else:
69
  cv2.rectangle(output_image, (x, y), (x + w, y + h), dominant_color, -1)
70
- shape_detected = "Rectangle"
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  return output_image
73
 
74
  # --- Gradio Interface Setup ---
75
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
76
- gr.Markdown("# 🔷 Irregular to Regular Shape Reconstructor")
77
- gr.Markdown("Upload an image of an irregular shape with missing parts (preferably with a transparent background). The algorithm will detect if it was originally a rectangle, square, or circle, and reconstruct its full geometric shape matching the original color.")
78
 
79
  with gr.Row():
80
  with gr.Column():
81
  input_image = gr.Image(label="Upload Irregular Shape", image_mode="RGBA", type="numpy")
82
  submit_btn = gr.Button("Reconstruct Shape", variant="primary")
83
  with gr.Column():
84
- output_image = gr.Image(label="Reconstructed Regular Shape", image_mode="RGBA")
85
 
86
  submit_btn.click(fn=reconstruct_shape, inputs=input_image, outputs=output_image)
87
 
 
8
 
9
  # Check if the image has an alpha (transparency) channel
10
  if image.shape[2] == 4:
 
11
  mask = image[:, :, 3]
 
12
  color_img = image[:, :, :3]
13
  else:
 
14
  gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
15
  _, mask = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)
16
  color_img = image
 
19
  contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
20
 
21
  if not contours:
22
+ return image
23
 
24
  # Find the largest contour (the main object)
25
  c = max(contours, key=cv2.contourArea)
26
 
27
+ # Extract the average color of the original shape for the reconstructed parts
28
  mean_val = cv2.mean(color_img, mask=mask)
29
+ # Make the reconstructed part slightly distinct, or keep it exactly the average color
30
+ dominant_color = (int(mean_val[0]), int(mean_val[1]), int(mean_val[2]), 255)
31
 
32
  # --- Shape Classification ---
 
33
  x, y, w, h = cv2.boundingRect(c)
34
  rect_area = w * h
35
 
 
36
  (cx, cy), radius = cv2.minEnclosingCircle(c)
37
  circle_area = np.pi * (radius ** 2)
 
 
38
  contour_area = cv2.contourArea(c)
39
 
 
 
40
  rect_ratio = contour_area / rect_area if rect_area > 0 else 0
41
  circle_ratio = contour_area / circle_area if circle_area > 0 else 0
42
 
43
+ # Create a blank transparent canvas for the output
44
  output_image = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
45
 
46
+ # --- Step 1: Draw the Reconstructed Base Shape ---
47
  if circle_ratio > rect_ratio:
 
48
  center = (int(cx), int(cy))
49
  cv2.circle(output_image, center, int(radius), dominant_color, -1)
 
50
  else:
 
 
51
  if 0.85 <= w / h <= 1.15:
 
52
  side = max(w, h)
53
  cv2.rectangle(output_image, (x, y), (x + side, y + side), dominant_color, -1)
 
54
  else:
55
  cv2.rectangle(output_image, (x, y), (x + w, y + h), dominant_color, -1)
56
+
57
+ # --- Step 2: Paste the Original Image Over the Base ---
58
+ # This keeps the original texture intact while the missing parts show the dominant color
59
+ original_area = mask > 0
60
+ output_image[original_area] = image[original_area]
61
+
62
+ # --- Step 3: Draw the "Crack" / Seam ---
63
+ # Draw a dark line along the boundary of the original shape to show where it was reconstructed
64
+ crack_color = (40, 40, 40, 255) # Dark gray/black line for the crack
65
+ crack_thickness = 3 # Adjust thickness of the line here
66
+
67
+ cv2.drawContours(output_image, [c], -1, crack_color, crack_thickness)
68
 
69
  return output_image
70
 
71
  # --- Gradio Interface Setup ---
72
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
73
+ gr.Markdown("# 🔷 Irregular Shape Reconstructor (With Visible Seams)")
74
+ gr.Markdown("Upload an image of an irregular shape. The algorithm reconstructs its original geometric form and draws a visible 'crack' line to show exactly where the new parts were glued on.")
75
 
76
  with gr.Row():
77
  with gr.Column():
78
  input_image = gr.Image(label="Upload Irregular Shape", image_mode="RGBA", type="numpy")
79
  submit_btn = gr.Button("Reconstruct Shape", variant="primary")
80
  with gr.Column():
81
+ output_image = gr.Image(label="Reconstructed Shape with Crack", image_mode="RGBA")
82
 
83
  submit_btn.click(fn=reconstruct_shape, inputs=input_image, outputs=output_image)
84