mirror of
https://github.com/KrisKennaway/ii-pix.git
synced 2024-06-14 14:29:29 +00:00
Cleanup
This commit is contained in:
parent
613a36909c
commit
bb70eea7b0
65
dither.pyx
65
dither.pyx
|
@ -335,11 +335,12 @@ def dither_image(
|
||||||
free(cdither.pattern)
|
free(cdither.pattern)
|
||||||
return image_nbit_to_bitmap(image_nbit, xres, yres, palette_depth)
|
return image_nbit_to_bitmap(image_nbit, xres, yres, palette_depth)
|
||||||
|
|
||||||
import colour
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
@cython.boundscheck(False)
|
||||||
@cython.wraparound(False)
|
@cython.wraparound(False)
|
||||||
def dither_shr(float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[:, :, ::1] palettes_rgb, float[:,::1] rgb_to_cam16ucs, float penalty):
|
def dither_shr(
|
||||||
|
float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[:, :, ::1] palettes_rgb,
|
||||||
|
float[:,::1] rgb_to_cam16ucs, float penalty):
|
||||||
cdef int y, x, idx, best_colour_idx, best_palette
|
cdef int y, x, idx, best_colour_idx, best_palette
|
||||||
cdef double best_distance, distance, total_image_error
|
cdef double best_distance, distance, total_image_error
|
||||||
cdef float[::1] best_colour_rgb, pixel_cam, colour_rgb, colour_cam
|
cdef float[::1] best_colour_rgb, pixel_cam, colour_rgb, colour_cam
|
||||||
|
@ -355,14 +356,12 @@ def dither_shr(float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[
|
||||||
best_palette = 15
|
best_palette = 15
|
||||||
total_image_error = 0.0
|
total_image_error = 0.0
|
||||||
for y in range(200):
|
for y in range(200):
|
||||||
# print(y)
|
|
||||||
for x in range(320):
|
for x in range(320):
|
||||||
colour_cam = convert_rgb_to_cam16ucs(
|
colour_cam = convert_rgb_to_cam16ucs(
|
||||||
rgb_to_cam16ucs, working_image[y,x,0], working_image[y,x,1], working_image[y,x,2])
|
rgb_to_cam16ucs, working_image[y,x,0], working_image[y,x,1], working_image[y,x,2])
|
||||||
line_cam[x, :] = colour_cam
|
line_cam[x, :] = colour_cam
|
||||||
|
|
||||||
best_palette = best_palette_for_line(line_cam, palettes_cam, <int>(y * 16 / 200), best_palette, penalty)
|
best_palette = best_palette_for_line(line_cam, palettes_cam, <int>(y * 16 / 200), best_palette, penalty)
|
||||||
# print("-->", best_palette)
|
|
||||||
palette_rgb = palettes_rgb[best_palette, :, :]
|
palette_rgb = palettes_rgb[best_palette, :, :]
|
||||||
line_to_palette[y] = best_palette
|
line_to_palette[y] = best_palette
|
||||||
|
|
||||||
|
@ -382,7 +381,6 @@ def dither_shr(float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[
|
||||||
best_colour_rgb = palette_rgb[best_colour_idx]
|
best_colour_rgb = palette_rgb[best_colour_idx]
|
||||||
output_4bit[y, x] = best_colour_idx
|
output_4bit[y, x] = best_colour_idx
|
||||||
total_image_error += best_distance
|
total_image_error += best_distance
|
||||||
# print(y,x,best_distance,total_image_error)
|
|
||||||
|
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
quant_error = working_image[y, x, i] - best_colour_rgb[i]
|
quant_error = working_image[y, x, i] - best_colour_rgb[i]
|
||||||
|
@ -395,6 +393,7 @@ def dither_shr(float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[
|
||||||
working_image[y, x + 1, i] = clip(
|
working_image[y, x + 1, i] = clip(
|
||||||
working_image[y, x + 1, i] + quant_error * (7 / 16), 0, 1)
|
working_image[y, x + 1, i] + quant_error * (7 / 16), 0, 1)
|
||||||
if y < 199:
|
if y < 199:
|
||||||
|
# TODO: parametrize the 0.5x decay factor
|
||||||
if x > 0:
|
if x > 0:
|
||||||
working_image[y + 1, x - 1, i] = clip(
|
working_image[y + 1, x - 1, i] = clip(
|
||||||
working_image[y + 1, x - 1, i] + quant_error * (3 / 32), 0, 1)
|
working_image[y + 1, x - 1, i] + quant_error * (3 / 32), 0, 1)
|
||||||
|
@ -454,62 +453,6 @@ def dither_shr(float[:, :, ::1] input_rgb, float[:, :, ::1] palettes_cam, float[
|
||||||
|
|
||||||
return np.array(output_4bit, dtype=np.uint8), line_to_palette, total_image_error
|
return np.array(output_4bit, dtype=np.uint8), line_to_palette, total_image_error
|
||||||
|
|
||||||
import collections
|
|
||||||
import random
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
|
||||||
@cython.wraparound(False)
|
|
||||||
def k_means_with_fixed_centroids(
|
|
||||||
int n_clusters, float[:, ::1] data, float[:, ::1] fixed_centroids = None,
|
|
||||||
int iterations = 10000, float tolerance = 1e-3):
|
|
||||||
cdef int i, iteration, centroid_idx, num_fixed_centroids, num_random_centroids, best_centroid_idx
|
|
||||||
cdef float[::1] point, centroid, new_centroid, old_centroid
|
|
||||||
cdef float[:, ::1] centroids
|
|
||||||
cdef float best_dist, centroid_movement, dist
|
|
||||||
|
|
||||||
centroids = np.zeros((n_clusters, 3), dtype=np.float32)
|
|
||||||
if fixed_centroids is not None:
|
|
||||||
centroids[:fixed_centroids.shape[0], :] = fixed_centroids
|
|
||||||
num_fixed_centroids = fixed_centroids.shape[0] if fixed_centroids is not None else 0
|
|
||||||
num_random_centroids = n_clusters - num_fixed_centroids
|
|
||||||
|
|
||||||
# TODO: kmeans++ initialization
|
|
||||||
cdef int rand_idx = random.randint(0, data.shape[0])
|
|
||||||
for i in range(num_random_centroids):
|
|
||||||
centroids[num_fixed_centroids + i, :] = data[rand_idx, :]
|
|
||||||
|
|
||||||
cdef int[::1] centroid_weights = np.zeros(n_clusters, dtype=np.int32)
|
|
||||||
for iteration in range(iterations):
|
|
||||||
# print("centroids ", centroids)
|
|
||||||
closest_points = collections.defaultdict(list)
|
|
||||||
for point in data:
|
|
||||||
best_dist = 1e9
|
|
||||||
best_centroid_idx = 0
|
|
||||||
for centroid_idx in range(n_clusters):
|
|
||||||
centroid = centroids[centroid_idx, :]
|
|
||||||
dist = colour_distance(centroid, point)
|
|
||||||
if dist < best_dist:
|
|
||||||
best_dist = dist
|
|
||||||
best_centroid_idx = centroid_idx
|
|
||||||
closest_points[best_centroid_idx].append(point)
|
|
||||||
|
|
||||||
centroid_movement = 0
|
|
||||||
for centroid_idx, points in closest_points.items():
|
|
||||||
centroid_weights[centroid_idx] = len(points)
|
|
||||||
if centroid_idx < num_fixed_centroids:
|
|
||||||
continue
|
|
||||||
new_centroid = np.median(np.array(points), axis=0)
|
|
||||||
old_centroid = centroids[centroid_idx]
|
|
||||||
centroid_movement += colour_distance(old_centroid, new_centroid)
|
|
||||||
centroids[centroid_idx, :] = new_centroid
|
|
||||||
# print("iteration %d: movement %f" % (iteration, centroid_movement))
|
|
||||||
if centroid_movement < tolerance:
|
|
||||||
break
|
|
||||||
|
|
||||||
weighted_centroids = list(zip(centroid_weights, [tuple(c) for c in centroids]))
|
|
||||||
print(weighted_centroids)
|
|
||||||
return np.array([c for w, c in sorted(weighted_centroids, reverse=True)], dtype=np.float32)
|
|
||||||
|
|
||||||
@cython.boundscheck(False)
|
@cython.boundscheck(False)
|
||||||
@cython.wraparound(False)
|
@cython.wraparound(False)
|
||||||
cdef int best_palette_for_line(float [:, ::1] line_cam, float[:, :, ::1] palettes_cam, int base_palette_idx, int last_palette_idx, float last_penalty) nogil:
|
cdef int best_palette_for_line(float [:, ::1] line_cam, float[:, :, ::1] palettes_cam, int base_palette_idx, int last_palette_idx, float last_penalty) nogil:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user