Experiment with striping 16 palettes contiguously across line ranges.

As expected it has clear banding.  A better approach (though still not optimal)
might be to assign lines to palettes randomly.
This commit is contained in:
kris 2021-11-09 22:42:27 +00:00
parent 80885aabf9
commit fb52815412
2 changed files with 27 additions and 15 deletions

View File

@ -28,15 +28,18 @@ def cluster_palette(image: Image):
colours_cam = colour.convert(colours_rgb, "RGB",
"CAM16UCS").astype(np.float32)
kmeans = KMeans(n_clusters=16, max_iter=10000)
kmeans.fit_predict(colours_cam)
palette_cam = kmeans.cluster_centers_
with colour.utilities.suppress_warnings(colour_usage_warnings=True):
palette_rgb = colour.convert(palette_cam, "CAM16UCS", "RGB")
# SHR colour palette only uses 4-bit values
palette_rgb = np.round(palette_rgb * 15) / 15
# palette_rgb = palette_rgb.astype(np.float32) / 255
return palette_rgb.astype(np.float32)
palettes_rgb = {}
for palette in range(16):
kmeans = KMeans(n_clusters=16, max_iter=10000)
kmeans.fit_predict(colours_cam[palette*320*12:(palette+1)*320*12])
palette_cam = kmeans.cluster_centers_
with colour.utilities.suppress_warnings(colour_usage_warnings=True):
palette_rgb = colour.convert(palette_cam, "CAM16UCS", "RGB")
# SHR colour palette only uses 4-bit values
palette_rgb = np.round(palette_rgb * 15) / 15
# palette_rgb = palette_rgb.astype(np.float32) / 255
palettes_rgb[palette] = palette_rgb.astype(np.float32)
return palettes_rgb
@ -100,15 +103,22 @@ def main():
gamma=args.gamma_correct, srgb_output=True)).astype(
np.float32) / 255
palette_rgb = cluster_palette(rgb)
palettes_rgb = cluster_palette(rgb)
# print(palette_rgb)
# screen.set_palette(0, (image_py.linear_to_srgb_array(palette_rgb) *
# 15).astype(np.uint8))
screen.set_palette(0, (np.round(palette_rgb * 15)).astype(np.uint8))
for i, p in palettes_rgb.items():
screen.set_palette(i, (np.round(p * 15)).astype(np.uint8))
output_4bit = dither_pyx.dither_shr(rgb, palette_rgb, rgb_to_cam16)
output_4bit = dither_pyx.dither_shr(rgb, palettes_rgb, rgb_to_cam16)
screen.set_pixels(output_4bit)
output_rgb = (palette_rgb[output_4bit] * 255).astype(np.uint8)
for i in range(200):
screen.line_palette[i] = i // 12
output_rgb = np.zeros((200, 320, 3), dtype=np.uint8)
for i, p in palettes_rgb.items():
output_rgb[i*12:(i+1)*12, :, :] = (p[output_4bit[i*12:(i+1)*12,
:]] * 255).astype(
np.uint8)
output_srgb = image_py.linear_to_srgb(output_rgb).astype(np.uint8)
# dither = dither_pattern.PATTERNS[args.dither]()

View File

@ -328,16 +328,18 @@ import colour
@cython.boundscheck(False)
@cython.wraparound(False)
def dither_shr(float[:, :, ::1] working_image, float[:, ::1] palette_rgb, float[:,::1] rgb_to_cam16ucs):
def dither_shr(float[:, :, ::1] working_image, object palettes_rgb, float[:,::1] rgb_to_cam16ucs):
cdef int y, x, idx, best_colour_idx
cdef float best_distance, distance
cdef float[::1] best_colour_rgb, pixel_cam, colour_rgb, colour_cam
cdef float[3] quant_error
cdef float[:, ::1] palette_rgb
cdef (unsigned char)[:, ::1] output_4bit = np.zeros((200, 320), dtype=np.uint8)
for y in range(200):
for y in range(192):
print(y)
palette_rgb = palettes_rgb[y // 12]
for x in range(320):
pixel_cam = convert_rgb_to_cam16ucs(
rgb_to_cam16ucs, working_image[y, x, 0], working_image[y, x, 1], working_image[y, x, 2])