prasannareddyp commited on
Commit
5226a32
·
verified ·
1 Parent(s): 6502a2e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -17
app.py CHANGED
@@ -1,16 +1,56 @@
1
  import gradio as gr
2
- from PIL import Image
3
  import numpy as np
4
- import io, os, zipfile, tempfile, time
5
  from spm import spm_augment
6
 
7
  TITLE = "Shuffle PatchMix (SPM) Augmentation"
8
  DESC = """
9
  Upload an image, choose **number of patches (N×N)**, and generate SPM-augmented variants.
10
- You can optionally **Enable Overlap Patch Blend** for smoother outputs.
11
- For batch processing, upload a .zip of images (PNG/JPG/JPEG), and download a .zip of outputs.
12
  """
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def _parse_grid(grid_choice: str) -> int:
15
  # Expect strings like "2x2", "4x4", "8x8", "16x16"
16
  try:
@@ -19,13 +59,13 @@ def _parse_grid(grid_choice: str) -> int:
19
  except Exception:
20
  return 4
21
 
22
- def run_single(image, grid_choice, use_overlap, overlap_px, mix_prob, beta_a, beta_b, num_augs, seed):
23
  if image is None:
24
  return []
25
  outs = []
26
  base_seed = int(seed) if seed is not None else None
27
  N = _parse_grid(grid_choice)
28
- ov = int(overlap_px) if use_overlap else 0
29
  for i in range(num_augs):
30
  s = (base_seed + i) if base_seed is not None else None
31
  out_img = spm_augment(
@@ -34,26 +74,27 @@ def run_single(image, grid_choice, use_overlap, overlap_px, mix_prob, beta_a, be
34
  mix_prob=float(mix_prob),
35
  beta_a=float(beta_a),
36
  beta_b=float(beta_b),
37
- overlap_px=ov,
38
  seed=s
39
  )
40
  outs.append(out_img)
41
  return outs
42
 
43
- def run_batch(zip_file, grid_choice, use_overlap, overlap_px, mix_prob, beta_a, beta_b, seed):
44
  if zip_file is None:
45
  return None, "Please upload a .zip file with images."
46
  tempdir = tempfile.mkdtemp()
47
  outdir = os.path.join(tempdir, "outputs")
48
  os.makedirs(outdir, exist_ok=True)
49
- # Extract
50
  with zipfile.ZipFile(zip_file, 'r') as zf:
51
  zf.extractall(tempdir)
52
- # Collect images
53
  valid_exts = {".png", ".jpg", ".jpeg"}
54
  count_in, count_out = 0, 0
55
  N = _parse_grid(grid_choice)
56
- ov = int(overlap_px) if use_overlap else 0
 
57
  for root_dir, _, files in os.walk(tempdir):
58
  for f in files:
59
  if f.lower().endswith(tuple(valid_exts)):
@@ -69,7 +110,7 @@ def run_batch(zip_file, grid_choice, use_overlap, overlap_px, mix_prob, beta_a,
69
  mix_prob=float(mix_prob),
70
  beta_a=float(beta_a),
71
  beta_b=float(beta_b),
72
- overlap_px=ov,
73
  seed=int(seed) if seed is not None else None
74
  )
75
  rel = os.path.relpath(in_path, tempdir)
@@ -77,7 +118,7 @@ def run_batch(zip_file, grid_choice, use_overlap, overlap_px, mix_prob, beta_a,
77
  os.makedirs(os.path.dirname(out_path), exist_ok=True)
78
  out_img.save(out_path)
79
  count_out += 1
80
- # Zip results
81
  out_zip = os.path.join(tempdir, f"spm_outputs_{int(time.time())}.zip")
82
  with zipfile.ZipFile(out_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
83
  for root_dir, _, files in os.walk(outdir):
@@ -85,20 +126,25 @@ def run_batch(zip_file, grid_choice, use_overlap, overlap_px, mix_prob, beta_a,
85
  p = os.path.join(root_dir, f)
86
  arc = os.path.relpath(p, outdir)
87
  zf.write(p, arcname=arc)
 
88
  msg = f"Processed {count_out}/{count_in} files."
89
  return out_zip, msg
90
 
91
  with gr.Blocks() as demo:
92
  gr.Markdown(f"# {TITLE}")
93
  gr.Markdown(DESC)
 
 
 
94
  with gr.Tabs():
95
  with gr.TabItem("Single Image"):
96
  with gr.Row():
97
  with gr.Column(scale=1):
98
  inp = gr.Image(label="Input image", type="pil")
 
99
  grid_choice = gr.Radio(choices=["2x2","4x4","8x8","16x16"], value="8x8", label="Grid (N×N)")
100
  use_overlap = gr.Checkbox(value=True, label="Enable Overlap Patch Blend")
101
- overlap_px = gr.Slider(1, 64, value=8, step=1, label="Overlap (px)")
102
  mix_prob = gr.Slider(0, 1, value=0.8, step=0.05, label="Mix probability (per patch)")
103
  with gr.Row():
104
  beta_a = gr.Slider(0.1, 8, value=2.0, step=0.1, label="Beta(α, β), α =")
@@ -110,16 +156,17 @@ with gr.Blocks() as demo:
110
  gallery = gr.Gallery(label="Augmented outputs", columns=2, height="auto")
111
  run_btn.click(
112
  fn=run_single,
113
- inputs=[inp, grid_choice, use_overlap, overlap_px, mix_prob, beta_a, beta_b, num_augs, seed],
114
  outputs=[gallery]
115
  )
 
116
  with gr.TabItem("Batch (.zip)"):
117
  with gr.Row():
118
  with gr.Column(scale=1):
119
  zip_in = gr.File(label="Upload a .zip of images", file_types=[".zip"])
120
  grid_choice_b = gr.Radio(choices=["2x2","4x4","8x8","16x16"], value="8x8", label="Grid (N×N)")
121
  use_overlap_b = gr.Checkbox(value=True, label="Enable Overlap Patch Blend")
122
- overlap_px_b = gr.Slider(1, 64, value=8, step=1, label="Overlap (px)")
123
  mix_prob_b = gr.Slider(0, 1, value=0.8, step=0.05, label="Mix probability (per patch)")
124
  with gr.Row():
125
  beta_a_b = gr.Slider(0.1, 8, value=2.0, step=0.1, label="Beta(α, β), α =")
@@ -131,7 +178,7 @@ with gr.Blocks() as demo:
131
  status = gr.Markdown()
132
  run_b.click(
133
  fn=run_batch,
134
- inputs=[zip_in, grid_choice_b, use_overlap_b, overlap_px_b, mix_prob_b, beta_a_b, beta_b_b, seed_b],
135
  outputs=[zip_out, status]
136
  )
137
 
 
1
  import gradio as gr
2
+ from PIL import Image, ImageDraw
3
  import numpy as np
4
+ import os, zipfile, tempfile, time
5
  from spm import spm_augment
6
 
7
  TITLE = "Shuffle PatchMix (SPM) Augmentation"
8
  DESC = """
9
  Upload an image, choose **number of patches (N×N)**, and generate SPM-augmented variants.
10
+ Optionally enable **overlap (as % of patch size)** with feathered blending for smooth seams.
11
+ For batch processing, upload a .zip of images (PNG/JPG/JPEG) and download the outputs as a .zip.
12
  """
13
 
14
+ EXAMPLES_DIR = "examples"
15
+
16
+ def _ensure_examples():
17
+ os.makedirs(EXAMPLES_DIR, exist_ok=True)
18
+ paths = [
19
+ os.path.join(EXAMPLES_DIR, "checkerboard.png"),
20
+ os.path.join(EXAMPLES_DIR, "gradient.png"),
21
+ os.path.join(EXAMPLES_DIR, "shapes.png"),
22
+ ]
23
+ # 1) Checkerboard
24
+ if not os.path.exists(paths[0]):
25
+ cb = Image.new("RGB", (512, 512), "white")
26
+ draw = ImageDraw.Draw(cb)
27
+ tile = 64
28
+ for y in range(0, 512, tile):
29
+ for x in range(0, 512, tile):
30
+ if (x//tile + y//tile) % 2 == 0:
31
+ draw.rectangle([x, y, x+tile-1, y+tile-1], fill=(30, 30, 30))
32
+ cb.save(paths[0])
33
+ # 2) Gradient
34
+ if not os.path.exists(paths[1]):
35
+ arr = np.zeros((360, 640, 3), dtype=np.uint8)
36
+ for x in range(640):
37
+ arr[:, x, 0] = int(255 * x / 639)
38
+ for y in range(360):
39
+ arr[y, :, 1] = int(255 * y / 359)
40
+ arr[:, :, 2] = 160
41
+ Image.fromarray(arr).save(paths[1])
42
+ # 3) Shapes
43
+ if not os.path.exists(paths[2]):
44
+ sh = Image.new("RGB", (512, 384), "white")
45
+ d = ImageDraw.Draw(sh)
46
+ colors = [(220,20,60),(65,105,225),(60,179,113),(255,165,0),(148,0,211)]
47
+ for i,c in enumerate(colors):
48
+ d.rectangle([20+90*i, 30, 80+90*i, 180], fill=c, outline=(0,0,0), width=3)
49
+ for i in range(6):
50
+ d.ellipse([40+80*i, 200, 90+80*i, 350], fill=colors[i%len(colors)], outline=(0,0,0), width=3)
51
+ sh.save(paths[2])
52
+ return [[p] for p in paths]
53
+
54
  def _parse_grid(grid_choice: str) -> int:
55
  # Expect strings like "2x2", "4x4", "8x8", "16x16"
56
  try:
 
59
  except Exception:
60
  return 4
61
 
62
+ def run_single(image, grid_choice, use_overlap, overlap_pct, mix_prob, beta_a, beta_b, num_augs, seed):
63
  if image is None:
64
  return []
65
  outs = []
66
  base_seed = int(seed) if seed is not None else None
67
  N = _parse_grid(grid_choice)
68
+ pct = float(overlap_pct) if use_overlap else 0.0
69
  for i in range(num_augs):
70
  s = (base_seed + i) if base_seed is not None else None
71
  out_img = spm_augment(
 
74
  mix_prob=float(mix_prob),
75
  beta_a=float(beta_a),
76
  beta_b=float(beta_b),
77
+ overlap_pct=pct,
78
  seed=s
79
  )
80
  outs.append(out_img)
81
  return outs
82
 
83
+ def run_batch(zip_file, grid_choice, use_overlap, overlap_pct, mix_prob, beta_a, beta_b, seed):
84
  if zip_file is None:
85
  return None, "Please upload a .zip file with images."
86
  tempdir = tempfile.mkdtemp()
87
  outdir = os.path.join(tempdir, "outputs")
88
  os.makedirs(outdir, exist_ok=True)
89
+
90
  with zipfile.ZipFile(zip_file, 'r') as zf:
91
  zf.extractall(tempdir)
92
+
93
  valid_exts = {".png", ".jpg", ".jpeg"}
94
  count_in, count_out = 0, 0
95
  N = _parse_grid(grid_choice)
96
+ pct = float(overlap_pct) if use_overlap else 0.0
97
+
98
  for root_dir, _, files in os.walk(tempdir):
99
  for f in files:
100
  if f.lower().endswith(tuple(valid_exts)):
 
110
  mix_prob=float(mix_prob),
111
  beta_a=float(beta_a),
112
  beta_b=float(beta_b),
113
+ overlap_pct=pct,
114
  seed=int(seed) if seed is not None else None
115
  )
116
  rel = os.path.relpath(in_path, tempdir)
 
118
  os.makedirs(os.path.dirname(out_path), exist_ok=True)
119
  out_img.save(out_path)
120
  count_out += 1
121
+
122
  out_zip = os.path.join(tempdir, f"spm_outputs_{int(time.time())}.zip")
123
  with zipfile.ZipFile(out_zip, "w", compression=zipfile.ZIP_DEFLATED) as zf:
124
  for root_dir, _, files in os.walk(outdir):
 
126
  p = os.path.join(root_dir, f)
127
  arc = os.path.relpath(p, outdir)
128
  zf.write(p, arcname=arc)
129
+
130
  msg = f"Processed {count_out}/{count_in} files."
131
  return out_zip, msg
132
 
133
  with gr.Blocks() as demo:
134
  gr.Markdown(f"# {TITLE}")
135
  gr.Markdown(DESC)
136
+
137
+ examples = _ensure_examples()
138
+
139
  with gr.Tabs():
140
  with gr.TabItem("Single Image"):
141
  with gr.Row():
142
  with gr.Column(scale=1):
143
  inp = gr.Image(label="Input image", type="pil")
144
+ gr.Examples(examples, inputs=[inp], label="Try these")
145
  grid_choice = gr.Radio(choices=["2x2","4x4","8x8","16x16"], value="8x8", label="Grid (N×N)")
146
  use_overlap = gr.Checkbox(value=True, label="Enable Overlap Patch Blend")
147
+ overlap_pct = gr.Slider(0, 49, value=12, step=1, label="Overlap (% of patch)")
148
  mix_prob = gr.Slider(0, 1, value=0.8, step=0.05, label="Mix probability (per patch)")
149
  with gr.Row():
150
  beta_a = gr.Slider(0.1, 8, value=2.0, step=0.1, label="Beta(α, β), α =")
 
156
  gallery = gr.Gallery(label="Augmented outputs", columns=2, height="auto")
157
  run_btn.click(
158
  fn=run_single,
159
+ inputs=[inp, grid_choice, use_overlap, overlap_pct, mix_prob, beta_a, beta_b, num_augs, seed],
160
  outputs=[gallery]
161
  )
162
+
163
  with gr.TabItem("Batch (.zip)"):
164
  with gr.Row():
165
  with gr.Column(scale=1):
166
  zip_in = gr.File(label="Upload a .zip of images", file_types=[".zip"])
167
  grid_choice_b = gr.Radio(choices=["2x2","4x4","8x8","16x16"], value="8x8", label="Grid (N×N)")
168
  use_overlap_b = gr.Checkbox(value=True, label="Enable Overlap Patch Blend")
169
+ overlap_pct_b = gr.Slider(0, 49, value=12, step=1, label="Overlap (% of patch)")
170
  mix_prob_b = gr.Slider(0, 1, value=0.8, step=0.05, label="Mix probability (per patch)")
171
  with gr.Row():
172
  beta_a_b = gr.Slider(0.1, 8, value=2.0, step=0.1, label="Beta(α, β), α =")
 
178
  status = gr.Markdown()
179
  run_b.click(
180
  fn=run_batch,
181
+ inputs=[zip_in, grid_choice_b, use_overlap_b, overlap_pct_b, mix_prob_b, beta_a_b, beta_b_b, seed_b],
182
  outputs=[zip_out, status]
183
  )
184