Preserve palette order when deduplicating entries

Also make sure we're not mutating _global_palettes, though this should
currently be harmless.
This commit is contained in:
kris 2021-11-25 21:57:27 +00:00
parent 61b4cbb184
commit 25e6ed7b88
1 changed files with 18 additions and 14 deletions

View File

@ -231,7 +231,7 @@ class ClusterPalette:
self._palette_lines[palette_idx], :, :].reshape(-1, 3)) self._palette_lines[palette_idx], :, :].reshape(-1, 3))
# Fix reserved colours from the global palette. # Fix reserved colours from the global palette.
initial_centroids = self._global_palette initial_centroids = np.copy(self._global_palette)
pixels_rgb_iigs = dither_pyx.convert_cam16ucs_to_rgb12_iigs( pixels_rgb_iigs = dither_pyx.convert_cam16ucs_to_rgb12_iigs(
palette_pixels) palette_pixels)
seen_colours = set() seen_colours = set()
@ -258,8 +258,9 @@ class ClusterPalette:
key=lambda kv: kv[1], reverse=True) key=lambda kv: kv[1], reverse=True)
fixed_colours = self._fixed_colours fixed_colours = self._fixed_colours
for colour, freq in most_frequent_colours: for colour, freq in most_frequent_colours:
if freq < (palette_pixels.shape[0] * if (freq < (palette_pixels.shape[0] *
fixed_colour_fraction_threshold): fixed_colour_fraction_threshold)) or (
fixed_colours == 16):
break break
if tuple(colour) not in seen_colours: if tuple(colour) not in seen_colours:
seen_colours.add(tuple(colour)) seen_colours.add(tuple(colour))
@ -267,11 +268,11 @@ class ClusterPalette:
fixed_colours += 1 fixed_colours += 1
palette_rgb12_iigs = dither_pyx.k_means_with_fixed_centroids( palette_rgb12_iigs = dither_pyx.k_means_with_fixed_centroids(
n_clusters=16, n_fixed=fixed_colours, n_clusters=16, n_fixed=fixed_colours,
samples=palette_pixels, samples=palette_pixels,
initial_centroids=initial_centroids, initial_centroids=initial_centroids,
max_iterations=1000, max_iterations=1000,
rgb12_iigs_to_cam16ucs=self._rgb12_iigs_to_cam16ucs) rgb12_iigs_to_cam16ucs=self._rgb12_iigs_to_cam16ucs)
# If the k-means clustering returned fewer than 16 unique colours, # If the k-means clustering returned fewer than 16 unique colours,
# fill out the remainder with the most common pixels colours that # fill out the remainder with the most common pixels colours that
# have not yet been used. # have not yet been used.
@ -315,9 +316,12 @@ class ClusterPalette:
def _fill_short_palette(self, palette_iigs_rgb, most_frequent_colours): def _fill_short_palette(self, palette_iigs_rgb, most_frequent_colours):
"""Fill out the palette to 16 unique entries.""" """Fill out the palette to 16 unique entries."""
palette_set = set() # We want to maintain order of insertion so that we respect the
# ordering of fixed colours in the palette. Python doesn't have an
# orderedset but dicts preserve insertion order.
palette_set = {}
for palette_entry in palette_iigs_rgb: for palette_entry in palette_iigs_rgb:
palette_set.add(tuple(palette_entry)) palette_set[tuple(palette_entry)] = True
if len(palette_set) == 16: if len(palette_set) == 16:
return palette_iigs_rgb return palette_iigs_rgb
@ -325,17 +329,17 @@ class ClusterPalette:
for colour, freq in most_frequent_colours: for colour, freq in most_frequent_colours:
if tuple(colour) in palette_set: if tuple(colour) in palette_set:
continue continue
palette_set.add(tuple(colour)) palette_set[tuple(colour)] = True
# print("Added freq %d" % freq) # print("Added freq %d" % freq)
if len(palette_set) == 16: if len(palette_set) == 16:
break break
# We couldn't find any more unique colours, fill out with random ones. # We couldn't find any more unique colours, fill out with random ones.
while len(palette_set) < 16: while len(palette_set) < 16:
palette_set.add( palette_set[
tuple(np.random.randint(0, 16, size=3, dtype=np.uint8))) tuple(np.random.randint(0, 16, size=3, dtype=np.uint8))] = True
return np.array(tuple(palette_set), dtype=np.uint8) return np.array(tuple(palette_set.keys()), dtype=np.uint8)
def _reassign_unused_palettes(self, line_to_palette, palettes_iigs_rgb): def _reassign_unused_palettes(self, line_to_palette, palettes_iigs_rgb):
palettes_used = [False] * 16 palettes_used = [False] * 16