njsmith / colorspacious

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

yikes, very different J s in JCh and Jab, CIECAM02 and CIECAM02-UCS #31

Open denis-bz opened 9 months ago

denis-bz commented 9 months ago

Hi Nate, I thought for years that JCh was Jab in polar coordinates, like LCh is Lab in polar coordinates. Not so -- which maybe everybody knows, but I didn't; they differ by quite a lot, run the simple test below. Different names for JCh and polar(Jab) would avoid the confusion, how about "Jpolar" ?

(transform_graph.py is brilliant -- have you thought of splitting it off ?)

cheers -- denis

#!/usr/bin/env python3
""" yikes, J in JCh != J in Jab
    JCh is CIECAM02, Jab is the improved CIECAM02-UCS
    unlike LCh, which is Lab in polar / cylindrical coordinates
"""
# use Jab and "Jpolar" == polar(Jab) -- don't use JCh
# Whenever something can be done in two ways, someone will get confused.

from itertools import product
import sys
from traceback import print_exc
import numpy as np
from colorspacious import cspace_convert, __version__
    # https://colorspacious.readthedocs.io/en/latest/reference.html#specifying-colorspaces
    # https://github.com/njsmith/colorspacious

def edgecolors( c=[200], verbose=1 ) -> "Nx3 0 0 c .. 255 255 c":
    c = [0] + c + [255]
    A = np.array( list( product( c, c, c )))
    A = A[1:-1]  # drop black, white
    if verbose:
        print( f"edgecolors {c}: {len(A)} \n{A.T} .T \n" )
    return A

def convert( rgb, to: "CAM02-UCS J JCh ..." ):
    print( "\n-- to", to )
    try:
        conv = cspace_convert( rgb, "sRGB255", to )  # .squeeze()
        print( ints( conv ).T )
        return conv
    except Exception:
        print_exc( limit=1 )
        # ValueError: No path found from {'name': 'sRGB255'} -> {'name': '"CAM02"'}
        # colorspacious/transform_graph.py dump the TransformGraph ?

def ints( x ):
    return np.asarray( x ).round().astype(int)

if __name__ == "__main__":

    np.set_printoptions( edgeitems=10, threshold=10, linewidth=120, formatter=dict(
            float = lambda x: "%.3g" % x ))
    print( 80 * "▄" )
    print( "colorspacious %s  numpy %s  python %s \n" % (
            __version__, np.__version__, sys.version.split()[0] ))

    #...........................................................................
    # cspace_convert some edgecolors to ... --
    rgb = edgecolors( c=[50, 200] )

    args = sys.argv[1:] or "CAM02-UCS JCh J CIELCh CAM02 J'a'b' ".split()
    for to in args:
        c = convert( rgb, to )