Python: ¿Existe una función o fórmula para encontrar el color complementario de un código rgb?

He intentado encontrar una buena fórmula en Python 3 para calcular el color complementario de un código rgb, por ejemplo. complementario de a = b. ¿Hay alguna manera de hacer esto?

Aquí es cómo calcular el complemento de un color RGB directamente. Da los mismos resultados que el algoritmo que usa colorsys como se muestra en la respuesta de Iva Klass, pero en mis pruebas es aproximadamente un 50% más rápido. Tenga en cuenta que funciona con cualquier esquema RGB, no importa si los componentes RGB son enteros o flotantes (¡siempre que cada componente use el mismo rango!).

La función hilo implementa una red de clasificación simple para ordenar los componentes RGB.

 # Sum of the min & max of (a, b, c) def hilo(a, b, c): if c < b: b, c = c, b if b < a: a, b = b, a if c < b: b, c = c, b return a + c def complement(r, g, b): k = hilo(r, g, b) return tuple(k - u for u in (r, g, b)) 

Aquí hay una breve demostración, utilizando PIL / almohada.

 #!/usr/bin/env python3 ''' Complement the colours in a RGB image Written by PM 2Ring 2016.10.08 ''' import sys from PIL import Image # Sum of the min & max of (a, b, c) def hilo(a, b, c): if c < b: b, c = c, b if b < a: a, b = b, a if c < b: b, c = c, b return a + c def complement(r, g, b): k = hilo(r, g, b) return tuple(k - u for u in (r, g, b)) def complement_image(iname, oname): print('Loading', iname) img = Image.open(iname) #img.show() size = img.size mode = img.mode in_data = img.getdata() print('Complementing...') out_img = Image.new(mode, size) out_img.putdata([complement(*rgb) for rgb in in_data]) out_img.show() out_img.save(oname) print('Saved to', oname) def main(): if len(sys.argv) == 3: complement_image(*sys.argv[1:]) else: fmt = 'Complement colours.\nUsage: {} input_image output_image' print(fmt.format(sys.argv[0])) if __name__ == '__main__': main() 

imagen de entrada

source image

imagen de salida

output image


Aquí hay una versión Numpy de complement_image . En mi máquina, procesa la imagen de "Gafas" aproximadamente 3.7 veces más rápido que la versión anterior.

 import numpy as np def complement_image(iname, oname): print('Loading', iname) img = Image.open(iname) #img.show() in_data = np.asarray(img) #print(in_data.shape) print('Complementing...') lo = np.amin(in_data, axis=2, keepdims=True) hi = np.amax(in_data, axis=2, keepdims=True) out_data = (lo + hi) - in_data out_img = Image.fromarray(out_data) #out_img.show() out_img.save(oname) print('Saved to', oname) 

No creo que haya una solución lista para esto, pero hay un módulo colorsys en la biblioteca estándar, que puede ayudar.

Creo que primero necesita convertir RGB en HSV o HSL , luego “rotar” el tono y volver a convertir a RGB, si lo necesita. Por ejemplo (no estoy seguro de la rotación adecuada):

 from colorsys import rgb_to_hsv, hsv_to_rgb def complementary(r, g, b): """returns RGB components of complementary color""" hsv = rgb_to_hsv(r, g, b) return hsv_to_rgb((hsv[0] + 0.5) % 1, hsv[1], hsv[2])