Python- Is there a function or formula to find the complementary colour of a rgb code?
colors, python, python-3.5, rgb
Solution
Here's how to calculate the complement of an RGB colour directly. It gives the same results as the algorithm using `colorsys` as shown in Iva Klass's answer, but in my tests it's about 50% faster. Note that it works for any RGB scheme, it doesn't matter whether the RGB components are integers or floats (as long as each component uses the same range!).
The function `hilo` implements a simple sorting network to sort the RGB components.
# 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))
Here's a short demo, using PIL / Pillow.
#!/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()
Input image
Output image
Here's a Numpy version of `complement_image`. On my machine it processes the "Glasses" image about 3.7 times faster than the previous version.
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)
Here's a brief demo using scikit-image (and Numpy) to create complementary colours in the more perceptually uniform CIELuv colourspace.
from skimage.color import rgb2luv, luv2rgb
from skimage.util import img_as_ubyte
luv_data = rgb2luv(in_data) * (1, -1, -1)
out_data = img_as_ubyte(luv2rgb(luv_data))
Problem
I have tried to find a good formula in Python 3 to calculate the complementary colour of a rgb code eg. complementary of a = b. Is there any way to do this?