¿Cómo reducir la paleta de imágenes a colores específicos?

Estoy jugando con un progtwig en Python para crear esquemas de punto de cruz y necesito reducir los colores de una imagen a colores de hilo específicos como este . No es necesario utilizar todos los colores de la paleta de hilo dental. En Python o Pseudocódigo.

Ejemplo

La paleta personalizada (en PILL / Pillow por ejemplo) no es situable. Hay 256 colores como máximo, pero la paleta de seda tiene alrededor de 450 colores y planeo usar varias tablas de colores de diferentes fabricantes.

El dithering tampoco puede situarse en punto de cruz.

Creo que esto podría ser algo como:

result = [] for pixel_color in image: nearest = None for floss_color in floss_palette: distance = delta_e_cie2000(pixel_color, floss_color) if distance < nearest: nearest = floss_color result.append(nearest) 

Puede ser que haya un algoritmo más rápido? (image_width * image_heigh * colors in palette = 112M delta_e cálculos y comparaciones en una imagen promedio de 500x500px. Es mucho.)

Dictonary para el delta ya calculado? ¿Otro algoritmo / enfoque / optimización?

Aquí hay un ejemplo de memoize. También he usado el min Incorporado

 def nearest(pixel_color, mem={}): if pixel_color in mem: return mem[pixel_color] n = min(floss_palette, key=lambda fc:delta_e_cie2000(pixel_color, fc)) mem[pixel_color] = n return mem[pixel_color] result = [nearest(pixel_color) for pixel_color in image]