0

When I convert black (rgb(0,0,0)) to LAB and back again it comes out as 19, 0, 10.

Is there a modified formula that expands the Lab color-space for 1:1 conversion? And if not, are there any other color-spaces that maintain the property of "the same amount of numerical change in these values corresponds to roughly the same amount of visually perceived change"?

I want to run k-means clustering on some images and it works better in Lab space.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • If you add your code, we can check. In general: use floating point (they loss precision, but less then integers. You may want to use YCC (not much different lo CIELAB (by coincidence/human vision mechanisms), but the triplet is made for bytes. – Giacomo Catenazzi Dec 11 '19 at 15:57
  • @GiacomoCatenazzi I don't think the issue is with floating-point precision; AFAIK LAB and sRGB colorspaces simply don't fully overlap. If you want to see the code, I think this library first does [lab->xyz](https://github.com/colorjs/color-space/blob/e3580fb3a547aa71a854c4bb74575c2cc20d82ff/lab.js#L17-L36) and then [xyz->rgb](https://github.com/colorjs/color-space/blob/e3580fb3a547aa71a854c4bb74575c2cc20d82ff/xyz.js#L83-L112). YCC looks a little [constrained](https://github.com/colorjs/color-space/blob/master/ycbcr.js) too. – mpen Dec 12 '19 at 08:31
  • CIELAB has all colours of sRGB, and if you remove the constrain about range of sRGB (so allowing negative numbers, and overflow), you can describe all the colours. CIEXYZ is just a linear transformation of a RGB, but just to have always positive numbers [doing manual calculation in 1931...] – Giacomo Catenazzi Dec 12 '19 at 09:18
  • @GiacomoCatenazzi Why would my sRGB go into the negatives? My source image is in RGB. It's the LAB that needs to not be clamped. [Converting back](https://github.com/colorjs/color-space/blob/e3580fb3a547aa71a854c4bb74575c2cc20d82ff/xyz.js#L107-L109) is indeed clamped, but that doesn't explain why I'd get 19,0,10 because those numbers are clearly within range (well, maybe not the 0, but that's moot). – mpen Dec 12 '19 at 09:25
  • Without knowing your code, we cannot tell you. CIELAB to CIEXYZ is reversible. CIEXYZ to sRGB is just a matrix multiplication, so reversible. The gamma could be tricky: RGB uses a "own" interpretation (easy to calculate), and some gamma are not reversible (per practical reasons, and just for the blacks/very dark colours). Check formula: https://en.wikipedia.org/wiki/CIELAB_color_space#CIELAB%E2%80%93CIEXYZ_conversions and https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation. – Giacomo Catenazzi Dec 12 '19 at 10:19
  • Black is (0,0,0) in sRGB, CIEXYZ, CIELAB. check in which step you have the error – Giacomo Catenazzi Dec 12 '19 at 10:20

1 Answers1

1

The short answer is the code library you are using has bugs.

And it does not seem to be actively maintained.

FWIW, when you are looking at values, remember that:

#000

sRGB 0,0,0 = linearRGB 0.0,0.0,0.0 = XYZ 0,0,0 = Lab 0,0,0
(All spaces 0,0,0)

#FFF

sRGB 255,255,255 = linearRGB 1.0,1.0,1.0 = XYZ 0.9505,1.0,1.0888 = Lab 100,0,0
(sRGB is D65, this assumes D65 2° observer)

#777

sRGB 119,119,119 = linearRGB 0.1845,0.1845,0.1845 = XYZ 0.1753,0.1845,0.2009 = Lab 50.03,0,0
(using BruceLindbloom Matrix)

Pseudocode

More correct code can be found here:

https://www.easyrgb.com/en/math.php

However, this code is NOT javascript — the code on this site is pseudocode, and so it needs to be modified (i.e. you need to use Math.pow and not ^ )

Python

There is a good Python based library here, and it is actively maintained:

https://github.com/colour-science/colour

MATH

The actual math and discussion can be found on Bruce Lindbloom's site:

http://www.brucelindbloom.com/index.html?Math.html

He also has some color calculators that are JS that might be helpful to you.

Happy to answer other questions, lemme know...

Myndex
  • 3,952
  • 1
  • 9
  • 24
  • 1
    Math looks simple enough. I'll try re-implementing it in JS when I have a minute. Thanks! – mpen Dec 28 '19 at 23:22
  • @mpen no problem... you also might like this repository: https://github.com/pex-gl/pex-color – Myndex Dec 28 '19 at 23:40
  • 1
    Got it! https://gist.github.com/mnpenner/19840a89f3989b389cc2f3f721ff6511 – mpen Dec 29 '19 at 02:20
  • 1
    @mpen nice... there is something missing I think you may want—notice your LAB values for sRGB 128,128,128. The LAB should be 53.59,0.0,0.0 — what's missing is illuminant. sRGB is D65. Lines 43 and 45 need to be X /= 95.047; Z /= 108.883; and line 67 to be: return [X * 95.047, Y * 100, Z * 108.883]; If I understand that you want to do operations in LAB space, then I think you'll want to modify these lines as shown. – Myndex Dec 30 '19 at 06:05
  • 1
    Fixed. Comes out as `128,128,128 -> 53.6,-0.0000100,0.00000400 -> 128,128,128` now. Thanks for checking over my code! – mpen Dec 30 '19 at 21:58