njsmith / colorspacious

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

Documented scale of CIELAB wrong? #20

Closed maxnoe closed 5 years ago

maxnoe commented 5 years ago

The documentation says CIELab values for a and be should be between -50 and 50.

However, I get sensible results, comparable to wikipedia here: https://en.wikipedia.org/wiki/CIELAB_color_space#/media/File:Lab_color_space.png

When using a range of -100, 100:

import matplotlib.pyplot as plt
import colorspacious
import numpy as np

N = 1200
a, b = np.meshgrid(np.linspace(-100, 100, N), np.linspace(-100, 100, N))

for L in (20, 50, 80):
    lab = np.full((N, N, 3), L)
    lab[:, :, 1] = a
    lab[:, :, 2] = b

    rgb = colorspacious.cspace_convert(lab, 'CIELab', 'sRGB1')
    # rgb = np.clip(rgb, 0, 1)
    rgb[np.any((rgb < 0) | (rgb > 1), axis=-1)] = 0

    w, h = plt.rcParams['figure.figsize']
    fig = plt.figure(figsize=(h, h))

    ax = fig.add_subplot(1, 1, 1)
    img = plt.imshow(rgb[::-1], extent=[-100, 100, -100, 100])
    img.set_rasterized(True)

    ax.set_title(f'$L* = {L}$')
    ax.set_xlabel('a*')
    ax.set_ylabel('b*')

    fig.tight_layout()
    fig.savefig(f'build/plots/lab_{L}.pdf')
maxnoe commented 5 years ago

I also see pronounced steps, is this some numerical issue?

KelSolaar commented 5 years ago

CIE L*a*b* is not technically bounded, the common [-128, +128] boundaries are appropriate for sRGB but larger gamuts will go beyond that. For example, ACES2065-1 has the following limits in CIE L*a*b*:

array([[ -58.99202084,  102.47216286],
       [-404.18830391,  317.50827994],
       [-274.02976251,  174.47162964]])
maxnoe commented 5 years ago

The documentation states:

L is scaled to vary from 0 to 100; a and b* are likewise scaled to roughly the range -50 to 50

https://colorspacious.readthedocs.io/en/latest/reference.html

KelSolaar commented 5 years ago

This should probably updated accordingly!

njsmith commented 5 years ago

Notice the word "roughly" :-) Maybe the numbers in the docs should be tweaked, but all that sentence is trying to do is to give a rough idea of which scale we're on (e.g. they're not all floating point values <1).

maxnoe commented 5 years ago

I understand that, still, the -50 to 50 seem very rough, for sRGB the primaries are:

In [1]: from colorspacious import cspace_convert

In [2]: cspace_convert((1, 0, 0), 'sRGB1', 'CIELab')
Out[2]: array([53.23138711, 80.11440251, 67.21999924])

In [3]: cspace_convert((0, 1, 0), 'sRGB1', 'CIELab')
Out[3]: array([ 87.73559768, -86.18402274,  83.18300646])

In [4]: cspace_convert((0, 0, 1), 'sRGB1', 'CIELab')
Out[4]: array([  32.30269787,   79.19228008, -107.86329661])

So I'll probably go for [-100, 100]

KelSolaar commented 5 years ago

What @njsmith is trying to say is that you should open a PR :D

maxnoe commented 5 years ago

Already did ;-)

21