thalismind commited on
Commit
c913ad2
·
1 Parent(s): 36b6206

fix pixelization

Browse files
Files changed (2) hide show
  1. README.md +10 -0
  2. pixelize.py +58 -13
README.md CHANGED
@@ -79,6 +79,16 @@ Please prepare the repository for use with HuggingFace Spaces. Make sure it has
79
 
80
  Followed by manually updating the Gradio version in the README.md frontmatter and the requirements.txt file to use the latest version.
81
 
 
 
 
 
 
 
 
 
 
 
82
  ## License
83
 
84
  This project is open source and available under the MIT License.
 
79
 
80
  Followed by manually updating the Gradio version in the README.md frontmatter and the requirements.txt file to use the latest version.
81
 
82
+ The pixelization process was not implemented correctly and was resizing the image. That was fixed with the following prompt:
83
+
84
+ ```none
85
+ The pixel_size parameter currently makes the image larger, but it should make the pixels larger within the image, by combining groups of pixels on the grid given by the pixel_size. For example, if pixel_size is 2, then every 2x2 group should be the same color. If pixel_size is 4, then the groups are 4x4. Use the best color for each group based on the pixels within it.
86
+ ```
87
+
88
+ ```none
89
+ The average color may not be the best color for each pixel. Try both the mean and mode, and see which one is closer to the palette colors.
90
+ ```
91
+
92
  ## License
93
 
94
  This project is open source and available under the MIT License.
pixelize.py CHANGED
@@ -2,6 +2,7 @@ import numpy as np
2
  from PIL import Image
3
  from sklearn.cluster import KMeans
4
  import gradio as gr
 
5
 
6
  def extract_palette_from_image(palette_image):
7
  """Extract unique colors from a palette image."""
@@ -71,13 +72,35 @@ def rgb_to_hsv(rgb):
71
  h = (h / 6.0) % 1.0
72
  return h, s, v
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  def pixelize_image(image, palette, mode='rgb', pixel_size=1):
75
  """Convert image to pixel art using the given palette."""
76
  img = Image.open(image)
77
  img_array = np.array(img)
78
 
79
- # Reshape to get all pixels
80
- pixels = img_array.reshape(-1, 3)
 
 
 
 
 
 
 
81
 
82
  # Choose distance function based on mode
83
  if mode == 'rgb':
@@ -87,20 +110,42 @@ def pixelize_image(image, palette, mode='rgb', pixel_size=1):
87
  else: # brightness
88
  distance_func = brightness_distance
89
 
90
- # Find closest palette color for each pixel
91
- distances = np.array([[distance_func(pixel, palette_color) for palette_color in palette] for pixel in pixels])
92
- closest_colors = palette[np.argmin(distances, axis=1)]
93
-
94
- # Reshape back to image dimensions
95
- result = closest_colors.reshape(img_array.shape)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  # Create output image
98
- output = Image.fromarray(result.astype(np.uint8))
99
 
100
- # Resize if pixel_size > 1
101
- if pixel_size > 1:
102
- width, height = output.size
103
- output = output.resize((width * pixel_size, height * pixel_size), Image.NEAREST)
104
 
105
  return output
106
 
 
2
  from PIL import Image
3
  from sklearn.cluster import KMeans
4
  import gradio as gr
5
+ from collections import Counter
6
 
7
  def extract_palette_from_image(palette_image):
8
  """Extract unique colors from a palette image."""
 
72
  h = (h / 6.0) % 1.0
73
  return h, s, v
74
 
75
+ def get_mode_color(pixel_group):
76
+ """Calculate the mode color of a pixel group."""
77
+ # Reshape to get all pixels
78
+ pixels = pixel_group.reshape(-1, 3)
79
+
80
+ # Convert to tuple for counting
81
+ pixel_tuples = [tuple(pixel) for pixel in pixels]
82
+
83
+ # Count occurrences of each color
84
+ color_counts = Counter(pixel_tuples)
85
+
86
+ # Get the most common color
87
+ mode_color = np.array(color_counts.most_common(1)[0][0])
88
+ return mode_color
89
+
90
  def pixelize_image(image, palette, mode='rgb', pixel_size=1):
91
  """Convert image to pixel art using the given palette."""
92
  img = Image.open(image)
93
  img_array = np.array(img)
94
 
95
+ # Get image dimensions
96
+ height, width = img_array.shape[:2]
97
+
98
+ # Calculate new dimensions based on pixel_size
99
+ new_height = height // pixel_size
100
+ new_width = width // pixel_size
101
+
102
+ # Initialize output array
103
+ output_array = np.zeros((new_height, new_width, 3), dtype=np.uint8)
104
 
105
  # Choose distance function based on mode
106
  if mode == 'rgb':
 
110
  else: # brightness
111
  distance_func = brightness_distance
112
 
113
+ # Process each pixel group
114
+ for y in range(new_height):
115
+ for x in range(new_width):
116
+ # Get the pixel group
117
+ y_start = y * pixel_size
118
+ y_end = min((y + 1) * pixel_size, height)
119
+ x_start = x * pixel_size
120
+ x_end = min((x + 1) * pixel_size, width)
121
+
122
+ pixel_group = img_array[y_start:y_end, x_start:x_end]
123
+
124
+ # Calculate mean and mode colors
125
+ mean_color = np.mean(pixel_group, axis=(0, 1)).astype(int)
126
+ mode_color = get_mode_color(pixel_group)
127
+
128
+ # Find closest palette color for mean
129
+ mean_distances = np.array([distance_func(mean_color, palette_color) for palette_color in palette])
130
+ mean_closest_color = palette[np.argmin(mean_distances)]
131
+ mean_min_distance = np.min(mean_distances)
132
+
133
+ # Find closest palette color for mode
134
+ mode_distances = np.array([distance_func(mode_color, palette_color) for palette_color in palette])
135
+ mode_closest_color = palette[np.argmin(mode_distances)]
136
+ mode_min_distance = np.min(mode_distances)
137
+
138
+ # Choose the color with the smaller distance to palette
139
+ if mean_min_distance <= mode_min_distance:
140
+ output_array[y, x] = mean_closest_color
141
+ else:
142
+ output_array[y, x] = mode_closest_color
143
 
144
  # Create output image
145
+ output = Image.fromarray(output_array)
146
 
147
+ # Resize back to original dimensions
148
+ output = output.resize((width, height), Image.NEAREST)
 
 
149
 
150
  return output
151