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:
parent
61b4cbb184
commit
25e6ed7b88
32
convert.py
32
convert.py
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue