Rothfeld commited on
Commit
a3380d5
·
verified ·
1 Parent(s): 4beb161

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -10
app.py CHANGED
@@ -7,7 +7,7 @@ import numpy as np
7
  import gradio.components as gc
8
  import gradio as gr
9
 
10
-
11
  def pixart(
12
  i,
13
  block_size=4,
@@ -16,6 +16,8 @@ def pixart(
16
  local_contrast_blur_radius=51, # has to be odd
17
  upscale=True,
18
  seed=None,
 
 
19
  ):
20
  w, h = i.size
21
  dw = w//block_size
@@ -56,17 +58,35 @@ def pixart(
56
  most_sat_color = (hsv[label_grid == cluster] @
57
  np.array(hsv_weights)).argmax()
58
  return hsv[label_grid == cluster][most_sat_color]
 
59
  cluster_colors = np.array([
60
  pick_representative_pixel(c)
61
  for c in range(centers.shape[0])])
 
 
62
 
63
- # assign each pixel the color of its cluster
64
- ki = cluster_colors[label_grid]
 
 
 
 
 
 
 
 
 
 
 
65
 
66
  rgb = cv2.cvtColor(ki.astype(np.uint8), cv2.COLOR_HSV2RGB)
67
  i = Image.fromarray(rgb)
68
  if upscale:
69
  i = i.resize((w, h), Image.Resampling.NEAREST)
 
 
 
 
70
  return i, seed
71
 
72
 
@@ -77,6 +97,8 @@ def query(
77
  hsv_weights, # ='0,0,1'
78
  local_contrast_blur_radius, # =51 has to be odd
79
  seed, # =42,
 
 
80
  ):
81
  bs = float(block_size)
82
  w, h = i.size
@@ -95,12 +117,13 @@ def query(
95
  local_contrast_blur_radius=local_contrast_blur_radius,
96
  upscale=True,
97
  seed=int(seed) if seed != '' else None,
 
 
98
  )
99
- if n_clusters<=256:
100
- pxart=pxart.convert('P', palette=Image.Palette.ADAPTIVE, colors=n_clusters)
101
-
102
  return pxart, usedseed
103
-
104
 
105
 
106
  # %%
@@ -112,7 +135,7 @@ block_size = gc.Textbox(
112
  label='Block Size ',
113
  placeholder="e.g. 8 for 8 pixels. 0.01 for 1% of min(w,h) (<1 for percentages, >= 1 for pixels)")
114
  palette_size = gc.Slider(
115
- 1, 2048, 32, step=1, label='Palette Size (Number of Colors)')
116
  hsv_weights = gc.Textbox(
117
  "0,0,1",
118
  label='HSV Weights. Weights of the channels when selecting a "representative pixel"/centroid from a cluster of pixels',
@@ -126,14 +149,19 @@ seed = gc.Textbox(
126
  placeholder='e.g. 42')
127
 
128
  outimage = gc.Image(
129
- #shape=(224, 224),
130
  label="Output", type='pil')
131
  seedout = gc.Textbox(label='used seed')
132
 
 
 
 
 
 
133
 
134
  gr.Interface(
135
  query,
136
- [searchimage, block_size, palette_size, hsv_weights, lcbr, seed],
137
  [outimage, seedout],
138
  title="kmeans-Pixartifier",
139
  description=f"Turns images into pixel art using kmeans clustering",
 
7
  import gradio.components as gc
8
  import gradio as gr
9
 
10
+
11
  def pixart(
12
  i,
13
  block_size=4,
 
16
  local_contrast_blur_radius=51, # has to be odd
17
  upscale=True,
18
  seed=None,
19
+ output_scaling=1,
20
+ dither_amount=15
21
  ):
22
  w, h = i.size
23
  dw = w//block_size
 
58
  most_sat_color = (hsv[label_grid == cluster] @
59
  np.array(hsv_weights)).argmax()
60
  return hsv[label_grid == cluster][most_sat_color]
61
+
62
  cluster_colors = np.array([
63
  pick_representative_pixel(c)
64
  for c in range(centers.shape[0])])
65
+
66
+
67
 
68
+ if dither_amount == 0:
69
+ # assign each pixel the color of its cluster
70
+ ki = cluster_colors[label_grid]
71
+ else:
72
+ # add noise to the colors before selecting the nearest color, this acts as a dithering effect
73
+ noised_colors = hsv32 + np.random.normal(0, dither_amount, hsv.shape)
74
+ noised_colors = np.clip(noised_colors, 0, 255)
75
+ flattened = noised_colors.reshape(-1, 3)
76
+ # use the dot product to find the closest cluster (could also try euclidean distance)
77
+ closest_clusters = np.argmax(flattened @ centers.T,axis=1)
78
+ closest_clusters_eucledian = np.argmin(np.linalg.norm(centers - flattened[:, None], axis=-1), axis=1)
79
+ label_grid = closest_clusters_eucledian.reshape(hsv32.shape[:2])
80
+ ki = cluster_colors[label_grid]
81
 
82
  rgb = cv2.cvtColor(ki.astype(np.uint8), cv2.COLOR_HSV2RGB)
83
  i = Image.fromarray(rgb)
84
  if upscale:
85
  i = i.resize((w, h), Image.Resampling.NEAREST)
86
+
87
+ if output_scaling != 1:
88
+ i = i.resize(
89
+ (w*output_scaling, h*output_scaling), Image.Resampling.NEAREST)
90
  return i, seed
91
 
92
 
 
97
  hsv_weights, # ='0,0,1'
98
  local_contrast_blur_radius, # =51 has to be odd
99
  seed, # =42,
100
+ output_scaling,
101
+ dither_amount
102
  ):
103
  bs = float(block_size)
104
  w, h = i.size
 
117
  local_contrast_blur_radius=local_contrast_blur_radius,
118
  upscale=True,
119
  seed=int(seed) if seed != '' else None,
120
+ output_scaling=output_scaling,
121
+ dither_amount=dither_amount
122
  )
123
+ if n_clusters <= 256:
124
+ pxart = pxart.convert('P', palette=Image.Palette.ADAPTIVE, colors=n_clusters)
125
+ pxart.save('temp.bmp')
126
  return pxart, usedseed
 
127
 
128
 
129
  # %%
 
135
  label='Block Size ',
136
  placeholder="e.g. 8 for 8 pixels. 0.01 for 1% of min(w,h) (<1 for percentages, >= 1 for pixels)")
137
  palette_size = gc.Slider(
138
+ 1, 1024, 32, step=1, label='Palette Size (Number of Colors)')
139
  hsv_weights = gc.Textbox(
140
  "0,0,1",
141
  label='HSV Weights. Weights of the channels when selecting a "representative pixel"/centroid from a cluster of pixels',
 
149
  placeholder='e.g. 42')
150
 
151
  outimage = gc.Image(
152
+ # shape=(224, 224),
153
  label="Output", type='pil')
154
  seedout = gc.Textbox(label='used seed')
155
 
156
+ output_scaling = gc.Slider(
157
+ 0, 16, 1, step=1, label='Output scaling factor')
158
+
159
+ dither_amount = gc.Slider(
160
+ 0, 255, 0, step=1, label='Dithering amount')
161
 
162
  gr.Interface(
163
  query,
164
+ [searchimage, block_size, palette_size, hsv_weights, lcbr, seed, output_scaling, dither_amount],
165
  [outimage, seedout],
166
  title="kmeans-Pixartifier",
167
  description=f"Turns images into pixel art using kmeans clustering",