Fix next_level image quantization to preserve dark tones using fixed thresholds

This commit is contained in:
2026-06-23 22:12:43 +02:00
parent cb19677f98
commit d8fd7460ae
4 changed files with 267 additions and 277 deletions
+10 -24
View File
@@ -1,34 +1,20 @@
from PIL import Image
import numpy as np
from scipy.cluster.vq import kmeans, vq
# Open original and convert to grayscale
img = Image.open('assets/next_level_original.png').convert('L')
pixels = np.array(img, dtype=float)
pixels = np.array(img, dtype=np.uint8)
# Flatten for clustering
flat_pixels = pixels.flatten()
# Fixed thresholds for Game Boy colors
quantized_pixels = np.zeros_like(pixels)
# Find 4 clusters
centroids, _ = kmeans(flat_pixels, 4)
# Sort centroids by brightness (dark to light)
sorted_centroids = np.sort(centroids)
# Map centroids to GB colors
# GB palette: 0=Black, 1=Dark Gray, 2=Light Gray, 3=White
gb_colors = np.array([0, 85, 170, 255])
# Find the closest centroid for each pixel
# Assign the corresponding GB color
quantized_pixels = np.zeros_like(flat_pixels, dtype=np.uint8)
for i, p in enumerate(flat_pixels):
dist = np.abs(sorted_centroids - p)
closest_idx = np.argmin(dist)
quantized_pixels[i] = gb_colors[closest_idx]
# Map based on standard thresholds to preserve darkness
quantized_pixels[pixels < 40] = 0 # Black
quantized_pixels[(pixels >= 40) & (pixels < 128)] = 85 # Dark Gray
quantized_pixels[(pixels >= 128) & (pixels < 200)] = 170 # Light Gray
quantized_pixels[pixels >= 200] = 255 # White
# Reshape back to image
quantized_img_data = quantized_pixels.reshape(pixels.shape)
new_img = Image.fromarray(quantized_img_data, mode='L').convert('RGB')
new_img = Image.fromarray(quantized_pixels, mode='L').convert('RGB')
new_img.save('assets/next_level.png')
print("Processed next_level.png with k-means clustering!")
print("Processed next_level.png with fixed thresholds!")