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:
parent
80885aabf9
commit
fb52815412
36
convert.py
36
convert.py
|
@ -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]()
|
||||
|
|
|
@ -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])
|
||||
|
|
Loading…
Reference in New Issue