Andrei Cozma commited on
Commit
66bf7dc
·
1 Parent(s): 9483d3b
README.md CHANGED
@@ -10,4 +10,26 @@ pinned: false
10
  license: apache-2.0
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  license: apache-2.0
11
  ---
12
 
13
+ # Image FFT Playground
14
+
15
+ Gradio app to play with FFT of images.
16
+
17
+ Huggingface Spaces Demo: <https://huggingface.co/spaces/acozma/image_fft_playground>
18
+
19
+ ## Usage
20
+
21
+ - Upload your own input image, or use one of the example images
22
+ - Optionally draw on the input image to see how the FFT changes
23
+ - Mask out areas of the FFT magnitude and phase to see how the image changes
24
+ - Apply IFFT to the modified FFT to see the result
25
+
26
+ ## Example Screenshots
27
+
28
+ ![Generate FFT](image.png)
29
+
30
+ ![Generate IFFT](image-1.png)
31
+
32
+ ## Known Bugs
33
+
34
+ - Gradio Image canvas sometimes bugs out and unintentionally resizes/crops the images on the FFT Magnitude and Phase canvases. As a result, taking the IFFT will produce an error. To fix this, just refresh the page and try again.
35
+ - In the process of re-writing the app using Streamlit, since Gradio image canvas is not very stable and the API is not very flexible.
app.py CHANGED
@@ -5,6 +5,7 @@ import gradio as gr
5
  import numpy as np
6
  from PIL import Image, ImageChops, ImageOps
7
 
 
8
 
9
  class ImageInfo:
10
  def __init__(
@@ -290,7 +291,7 @@ def update_image_input(state, selection):
290
  None,
291
  )
292
 
293
- image_path = os.path.join("./images", selection)
294
  print(f"image_path: {image_path}")
295
  if not os.path.exists(image_path):
296
  raise gr.Error(f"Image not found: {image_path}")
@@ -353,7 +354,7 @@ with gr.Blocks(css=css) as demo:
353
  mask_opacity=1.0,
354
  elem_classes=["inp_img"],
355
  )
356
- files = os.listdir("./images")
357
  files = sorted(files)
358
  inp_samples = gr.Dropdown(
359
  choices=files,
 
5
  import numpy as np
6
  from PIL import Image, ImageChops, ImageOps
7
 
8
+ samples_dir = "./samples"
9
 
10
  class ImageInfo:
11
  def __init__(
 
291
  None,
292
  )
293
 
294
+ image_path = os.path.join(samples_dir, selection)
295
  print(f"image_path: {image_path}")
296
  if not os.path.exists(image_path):
297
  raise gr.Error(f"Image not found: {image_path}")
 
354
  mask_opacity=1.0,
355
  elem_classes=["inp_img"],
356
  )
357
+ files = os.listdir(samples_dir)
358
  files = sorted(files)
359
  inp_samples = gr.Dropdown(
360
  choices=files,
generate_samples.py CHANGED
@@ -6,25 +6,25 @@ from scipy.ndimage import gaussian_filter
6
 
7
 
8
  def create_blank_image(size=512):
9
- img = np.ones((size, size)) * 255
10
  return img.astype(np.uint8)
11
 
12
 
13
  def add_horizontal_lines(image, spacing=10):
14
  for i in range(0, image.shape[0], spacing):
15
- image[i, :] = 0
16
  return image
17
 
18
 
19
  def add_vertical_lines(image, spacing=10):
20
  for i in range(0, image.shape[1], spacing):
21
- image[:, i] = 0
22
  return image
23
 
24
 
25
  def add_diagonal_lines(image, spacing=10):
26
  for i in range(0, image.shape[0], spacing):
27
- np.fill_diagonal(image[i:, i:], 0)
28
  return image
29
 
30
 
@@ -35,18 +35,18 @@ def add_circle(image, radius=50):
35
  -center_y : image.shape[0] - center_y, -center_x : image.shape[1] - center_x
36
  ]
37
  mask = x * x + y * y <= radius * radius
38
- image[mask] = 0
39
  return image
40
 
41
 
42
  def add_checkerboard(image, square_size=16):
43
  for i in range(0, image.shape[0], square_size * 2):
44
  for j in range(0, image.shape[1], square_size * 2):
45
- image[i : i + square_size, j : j + square_size] = 0
46
  image[
47
  i + square_size : i + square_size * 2,
48
  j + square_size : j + square_size * 2,
49
- ] = 0
50
  return image
51
 
52
 
 
6
 
7
 
8
  def create_blank_image(size=512):
9
+ img = np.zeros((size, size))
10
  return img.astype(np.uint8)
11
 
12
 
13
  def add_horizontal_lines(image, spacing=10):
14
  for i in range(0, image.shape[0], spacing):
15
+ image[i, :] = 255
16
  return image
17
 
18
 
19
  def add_vertical_lines(image, spacing=10):
20
  for i in range(0, image.shape[1], spacing):
21
+ image[:, i] = 255
22
  return image
23
 
24
 
25
  def add_diagonal_lines(image, spacing=10):
26
  for i in range(0, image.shape[0], spacing):
27
+ np.fill_diagonal(image[i:, i:], 255)
28
  return image
29
 
30
 
 
35
  -center_y : image.shape[0] - center_y, -center_x : image.shape[1] - center_x
36
  ]
37
  mask = x * x + y * y <= radius * radius
38
+ image[mask] = 255
39
  return image
40
 
41
 
42
  def add_checkerboard(image, square_size=16):
43
  for i in range(0, image.shape[0], square_size * 2):
44
  for j in range(0, image.shape[1], square_size * 2):
45
+ image[i : i + square_size, j : j + square_size] = 255
46
  image[
47
  i + square_size : i + square_size * 2,
48
  j + square_size : j + square_size * 2,
49
+ ] = 255
50
  return image
51
 
52
 
images/blank.png CHANGED
images/checkerboard.png CHANGED
images/circle.png CHANGED
images/diagonal.png CHANGED
images/horizontal.png CHANGED
images/random_noise.png CHANGED
images/vertical.png CHANGED
requirements.txt CHANGED
@@ -2,3 +2,5 @@ gradio==3.50.2
2
  numpy==1.25.1
3
  Pillow==10.0.0
4
  scipy==1.11.1
 
 
 
2
  numpy==1.25.1
3
  Pillow==10.0.0
4
  scipy==1.11.1
5
+ streamlit==1.28.0
6
+ streamlit-drawable-canvas==0.9.3
samples/blank.png ADDED
samples/checkerboard.png ADDED
samples/circle.png ADDED
samples/diagonal.png ADDED
samples/horizontal.png ADDED
samples/horizontal_sinusoidal.png ADDED
samples/random_noise.png ADDED
samples/vertical.png ADDED
samples/vertical_sinusoidal.png ADDED