njsmith / colorspacious

A powerful, accurate, and easy-to-use Python library for doing colorspace conversions
MIT License
169 stars 16 forks source link

perceptually uniform hue vs desaturation #17

Closed JohannesBuchner closed 6 years ago

JohannesBuchner commented 6 years ago

Hi,

I would like to make a two-axis color coding that has hue on one axis (e.g. going from green to blue or whatever) and saturation/lightness on the other (from saturated to white).

I tried to follow your talk (14:25 in https://www.youtube.com/embed/xAoljeRJ3lU) to get a uniform color at constant lightness. In the end however I always get curves in the image.

Is there a way to solve this?

Here is my code:

import numpy
import matplotlib.pyplot as plt
from colorspacious import cspace_convert

x = numpy.linspace(-1,1, 500)
y = numpy.linspace(-1,1, 500)
X, Y = numpy.meshgrid(x, y)

# the two axes
value = (-Y+1)/2.
error = (X+1)/2.

# the two axes:
h = value
l = error**0.5

l[l<0]=0
l[l>1]=1
total = numpy.zeros((value.shape[0], value.shape[1], 3))

Jmax = 100
Jp = Jmax * l + 20
radius = 40
b0 = 0
a0 = 0
circle_fraction = 0.25

ap = radius * numpy.sin(h * 2 * numpy.pi * circle_fraction) + a0
bp = radius * numpy.cos(h * 2 * numpy.pi * circle_fraction) + b0

colors = numpy.dstack((Jp, ap, bp))
total = cspace_convert(colors, 'CAM02-UCS', 'sRGB1')

total[total<0] = 0
total[total>1] = 1
plt.imshow(total)
plt.savefig('cam-CAM.jpg', bbox_inches='tight')
plt.close()

#  J (for lightness), C (for chroma), and h (for hue)
H = 100 * h
#J = l * 110 + 10
J = 50 + 0 * l
C = 250 * (1 - l)
colors = numpy.dstack((J, C, H))
total = cspace_convert(colors, "JCh", "sRGB1")

total[total<0] = 0
total[total>1] = 1
plt.imshow(total)
plt.savefig('cam-JCh.jpg', bbox_inches='tight')
plt.close()
JohannesBuchner commented 6 years ago

Here are the output images: CAM02-UCS: cam-cam

JCh: cam-jch

Maybe what I want just isn't possible.

njsmith commented 6 years ago

The first thing that jumps out at me is that you say you want constant lightness, and Jp / J are the lightness coordinate, but your code doesn't keep them constant...

JohannesBuchner commented 6 years ago

Well the lightness goes with the x-axis. At a fixed x, the lightness should be constant. But looking vertically, there are jumps.

In the meantime, I found a solution using saturations, which I documented here: https://github.com/JohannesBuchner/uncertaincolors Basically I have to first normalise the saturation at error=0, so that all colors show similar saturations. Then I can desaturate and it looks OK.

If you have further suggestions I would be happy to hear them. In the meantime, I am closing this bug. Thanks!