-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Specrtal range and Color-matching functions #12
Comments
OK, I established that the CMF are indeed the 1931/2. But the values are incorrect. |
Hi Roger, I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress. To get in some more technical details and provide some answers for your questions; The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations. I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet. The sources I used are coming directly from CIE: The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments. |
Hi rvan, As I searched my file library and CIE documentation for references with regards to your "CMF", it dawned on me that you could have pre-multiplied the functions by the normalization constant "k", in an effort to simplify and speed up the code, since your code is aimed at "performance". But I wasn't entirely sure. Your approach is sound and I will lookup ColorPy for curiosity :-) My orientation is "graphic arts". I live in a world of Photoshop and ICC profiling color management. I took a seminar at Munsell Color Science Institute in Rochester, many ears ago, and I recently became intersted in "acrylic prigments" mixing. To make a long story short, I ended up on this web site, https://goldenartistcolors.com/mixer/acrylic, where visitors can experiment color mixing based on Kubelka-Monk. I use paints by Liquitex but they seem to have much in common with these guys's paints. The part I was especially interested was the ability to load up an RGB image, click on some pixels and have the system suggest tubes of paints with quanitites of each to match the color. Wow! I still don't know how I am going to introduce this "notion" into my Photoshop class at the university where I teach (www.uqam.com) in Montréal. At this point, my goal is to understand the application of the Kulbelka-Monk theory in practice and your Spectral.js implementation is the closest thing I found on the internet to step by step application. You see, when I look at an image and try to match the color, I may get the intuition of which paints to mix but it is not obvious especially with certain colors? That is why I was looking for a way to overcome this lack of experience at mixing artists acrylic paints. One of the ways I think I'm going to introduce this technique to my students is to select a number of colors out of an sRGB image and use the Golden system to figure which paints to mix in order to match the color. I realize with experience, a person could evolve a way to mix paints without the need to use a computerized matching system. But with my Graphic design Photoshop students, I am trying to come up with approaches that will speed up their learning. So, one of the things I intend to do is to substite your "block dyes" (CMYRGB) with actual spectral reflectances and I think the best way to experiement would be to use ColorChecker spectral reflectances for the Cyan, Magenta, Yellow, Red, Green and Blue patches. Another thing I will do is to come up with D50 "CMF" because Photoshop is D50 and all the student's "interactions" with color is through Photoshop. I want to avoid the complications of chromatic adaptation. I'm curious about your RGB "Spectral Reflectance Estimation" technique? |
Found the Scott Burns "Color Projects" web page. |
Hi Ronald,
I am struggling with understanding your Kulbelka-Monk code.
This line of code, for example
KS = (1 - t) * ((1 - R1[i]) ** 2 / (2 * R1[i])) + t * ((1 - R2[i]) ** 2 / (2 * R2[i]))
corresponds to this equation
[cid:ac379e4e-5f7b-4800-a8ce-19ffbd64d381]
Right?
The
(1 - t)
term allows creating a KS that is a linear combination of more than one colorant, if I am not mistaking and could be extended to more than two colorants.
This expression
KM = 1 + KS - (KS ** 2 + 2 * KS) ** 0.5
computes the spectral reflectance?
Did you find any of this on ColorPy (ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>)?
I will take a look.
Thank you so much for your kind help and patience,
/ Roger
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Friday, March 29, 2024 5:16 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress.
To get in some more technical details and provide some answers for your questions;
The CMF are CIE 1931 2deg.
The spectral range is 380 to 730 in 10 nm steps.
As this library is specifically aimed for sRGB output the D65 standard illuminant is used.
The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations.
(The summed values for the XYZ bar are 0.95, 1.00 and 1.08 which should be familiar: Standard illuminant - Wikipedia<https://en.wikipedia.org/wiki/Standard_illuminant#D65_values>)
This is similar to what ColorPy does: ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>.
I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet<https://docs.google.com/spreadsheets/d/1U6utrBNvuvXn9kt8DQi32kT8WjnUSMnUmuBDTp5y9y0/edit?usp=sharing>.
The sources I used are coming directly from CIE:
CMF<https://cie.co.at/datatable/cie-1931-colour-matching-functions-2-degree-observer>
D65<https://cie.co.at/datatable/cie-standard-illuminant-d65>
The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments.
They are 'best fit' for the specific color using the CMF with the D65 illuminant: Generating Reflectance Curves from sRGB Triplets<http://scottburns.us/reflectance-curves-from-srgb-10/>.
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5F3EZKXYWY4RUXBM3DY2UPM5AVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRWHEZDMMJTGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Hi Ronald,
After much reading and research, it seems that this equation
for i in range(SIZE):
KS = (1 - t) * ((1 - R1[i]) ** 2 / (2 * R1[i])) + t * ((1 - R2[i]) ** 2 / (2 * R2[i]))
KM = 1 + KS - (KS ** 2 + 2 * KS) ** 0.5
R[i] = KM
Corresponds to the Single-constant form of the theory and you have it as multicomponent system
(Henry Kang, Technology for electronic devices, page 49).
/ Roger
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Friday, March 29, 2024 5:16 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress.
To get in some more technical details and provide some answers for your questions;
The CMF are CIE 1931 2deg.
The spectral range is 380 to 730 in 10 nm steps.
As this library is specifically aimed for sRGB output the D65 standard illuminant is used.
The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations.
(The summed values for the XYZ bar are 0.95, 1.00 and 1.08 which should be familiar: Standard illuminant - Wikipedia<https://en.wikipedia.org/wiki/Standard_illuminant#D65_values>)
This is similar to what ColorPy does: ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>.
I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet<https://docs.google.com/spreadsheets/d/1U6utrBNvuvXn9kt8DQi32kT8WjnUSMnUmuBDTp5y9y0/edit?usp=sharing>.
The sources I used are coming directly from CIE:
CMF<https://cie.co.at/datatable/cie-1931-colour-matching-functions-2-degree-observer>
D65<https://cie.co.at/datatable/cie-standard-illuminant-d65>
The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments.
They are 'best fit' for the specific color using the CMF with the D65 illuminant: Generating Reflectance Curves from sRGB Triplets<http://scottburns.us/reflectance-curves-from-srgb-10/>.
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5F3EZKXYWY4RUXBM3DY2UPM5AVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRWHEZDMMJTGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Found the exact equations you use
[cid:9af6ec22-36b4-4378-9c03-f88014b4d5c6]
Which, apparently, reduces to
[cid:399c3857-6967-4449-8c46-164f261b0199]
Complicated stuff. Slowly getting there.
/ Roger
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Friday, March 29, 2024 5:16 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress.
To get in some more technical details and provide some answers for your questions;
The CMF are CIE 1931 2deg.
The spectral range is 380 to 730 in 10 nm steps.
As this library is specifically aimed for sRGB output the D65 standard illuminant is used.
The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations.
(The summed values for the XYZ bar are 0.95, 1.00 and 1.08 which should be familiar: Standard illuminant - Wikipedia<https://en.wikipedia.org/wiki/Standard_illuminant#D65_values>)
This is similar to what ColorPy does: ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>.
I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet<https://docs.google.com/spreadsheets/d/1U6utrBNvuvXn9kt8DQi32kT8WjnUSMnUmuBDTp5y9y0/edit?usp=sharing>.
The sources I used are coming directly from CIE:
CMF<https://cie.co.at/datatable/cie-1931-colour-matching-functions-2-degree-observer>
D65<https://cie.co.at/datatable/cie-standard-illuminant-d65>
The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments.
They are 'best fit' for the specific color using the CMF with the D65 illuminant: Generating Reflectance Curves from sRGB Triplets<http://scottburns.us/reflectance-curves-from-srgb-10/>.
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5F3EZKXYWY4RUXBM3DY2UPM5AVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRWHEZDMMJTGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Hi Roger, The images are not showing for me. A lot of the information for creating this library comes from the Mixbox paper, this can be found on their repositorie: https://github.com/scrtwpns/mixbox |
Good news!
I modified your python code to use D50 instead of D65 illuminant.
In addition to your python code, I manually created an Excel spreadsheet to manually carry essentially the same Kubelka-Munk calculations as your code.
For my comparison, I used two acrylic paints, Rose Madder and Artic Blue, mixed 40% Rose Madder with 60% Artic Blue.
Instead of using your t value based on some Luminance factor developed by your code, I chose to set the t value equal to the "proportion" of each color in the mix, what's often called "concentration".
Your code and my Excel sheet arrived at the same CIE XYZ values.
[cid:7b1d8398-2307-4156-a0e7-ce61026fe749]
At this point, I say "case closed", Ronald. I owe you a beer!
Now your implementation is called "Single-Constant" but I'm told, for acrylic paints, I need the "Two-Constant" approach.
Kindest regards / Roger Breton
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Monday, April 8, 2024 4:31 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
The images are not showing for me.
A lot of the information for creating this library comes from the Mixbox paper, this can be found on their repositorie: https://github.com/scrtwpns/mixbox
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5DOXZXKR4452L67C5DY4JIXRAVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANBSGE3DSNJTGQ>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Hello Ronald,
I made a few changes to your code for my needs but the Kubelka-Munk part remains the same.
It took me a while to figure out the difference between your results and my results.
In the end, the difference stems from the estimated spectral curves used between my real pigments and the RGB -> Spectral you use. I took me a long time to figure it out. On your demo site, I typed in the RGB values corresponding to my two test color, a blue (22 61 199) and a yellow (255, 226, 0). Your blend looked like this
[cid:eac699cc-72c1-4de4-bd28-84f67b497dc6]
But my blend looked like this, "dull"?
[cid:fe0b5e29-e7cd-49eb-a8a5-e05ec6e807c7]
I was convinced there was something wrong with my code but it turned out that the "culprit" is the spectral estimation technique.
Here is the difference between our two spectral reflectance curves:
[cid:f23ef3a8-cb0d-4096-baa1-490d6918c5e9]
Our blues are about the same:
[cid:79439fe4-116d-4d22-82de-0f9c5e31d1a7]
I learned a lot through your code.
In particular, you may be interested in using ASTM E308 Table 5.17 for your "CMF".
I attached a copy in case you're interested.
I would rather use this table than the complicated "pre-multiplied" table you use.
This, anyone can follow, because it is a "standard".
Best / Roger Breton
P.S. On my D50 (5000K) calibrated monitor, my blend looks "yellowish" but on your D65 calibrated monitor, it may look "better".
There is a technique I should use to "adapt" the colors from D65 to D50 called "Chromatic adaptation" but that would be the cherry on the icing. It might be interesting to my students... If ever I decide to apply it to my results, I'll share it with you.
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Friday, March 29, 2024 5:16 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress.
To get in some more technical details and provide some answers for your questions;
The CMF are CIE 1931 2deg.
The spectral range is 380 to 730 in 10 nm steps.
As this library is specifically aimed for sRGB output the D65 standard illuminant is used.
The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations.
(The summed values for the XYZ bar are 0.95, 1.00 and 1.08 which should be familiar: Standard illuminant - Wikipedia<https://en.wikipedia.org/wiki/Standard_illuminant#D65_values>)
This is similar to what ColorPy does: ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>.
I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet<https://docs.google.com/spreadsheets/d/1U6utrBNvuvXn9kt8DQi32kT8WjnUSMnUmuBDTp5y9y0/edit?usp=sharing>.
The sources I used are coming directly from CIE:
CMF<https://cie.co.at/datatable/cie-1931-colour-matching-functions-2-degree-observer>
D65<https://cie.co.at/datatable/cie-standard-illuminant-d65>
The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments.
They are 'best fit' for the specific color using the CMF with the D65 illuminant: Generating Reflectance Curves from sRGB Triplets<http://scottburns.us/reflectance-curves-from-srgb-10/>.
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5F3EZKXYWY4RUXBM3DY2UPM5AVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRWHEZDMMJTGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Hi Ronald,
I finally found a moment to paint and measure a swatch of Titanium White.
Now I can generate a "palette" like yours.
It's interesting to compare colors between the KM approach and Adobe's approach.
See below:
[cid:8d8ddd08-2970-4822-8d87-aa764f6f472e]
Regards / Roger
…________________________________
From: Ronald van Wijnen ***@***.***>
Sent: Friday, March 29, 2024 5:16 AM
To: rvanwijnen/spectral.js ***@***.***>
Cc: Roger-Breton ***@***.***>; Author ***@***.***>
Subject: Re: [rvanwijnen/spectral.js] Specrtal range and Color-matching functions (Issue #12)
Hi Roger,
I'm very interested in the things you are planning to do with real pigment data using the spectral.js library as reference, please keep me posted on your progress.
To get in some more technical details and provide some answers for your questions;
The CMF are CIE 1931 2deg.
The spectral range is 380 to 730 in 10 nm steps.
As this library is specifically aimed for sRGB output the D65 standard illuminant is used.
The CIE CMF arrays are multiplied with the D65 illuminant and then normalized by the summed value of Y to get the tristimulus (XYZ bar) values used for further calculations.
(The summed values for the XYZ bar are 0.95, 1.00 and 1.08 which should be familiar: Standard illuminant - Wikipedia<https://en.wikipedia.org/wiki/Standard_illuminant#D65_values>)
This is similar to what ColorPy does: ColorPy<https://github.com/markkness/ColorPy/blob/master/colorpy/illuminants.py#L634>.
I have created an online spreadsheet for you to see how I calculated the arrays: Spreadsheet<https://docs.google.com/spreadsheets/d/1U6utrBNvuvXn9kt8DQi32kT8WjnUSMnUmuBDTp5y9y0/edit?usp=sharing>.
The sources I used are coming directly from CIE:
CMF<https://cie.co.at/datatable/cie-1931-colour-matching-functions-2-degree-observer>
D65<https://cie.co.at/datatable/cie-standard-illuminant-d65>
The SPD's used for the different colors are generated based on work done by Scott Burns and are not representative of real world pigments.
They are 'best fit' for the specific color using the CMF with the D65 illuminant: Generating Reflectance Curves from sRGB Triplets<http://scottburns.us/reflectance-curves-from-srgb-10/>.
—
Reply to this email directly, view it on GitHub<#12 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEVBK5F3EZKXYWY4RUXBM3DY2UPM5AVCNFSM6AAAAABFNY5H6GVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRWHEZDMMJTGE>.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
I can’t see the images you posted, I DM’d you on X. |
First, what is the spectral range of the SPD_C and so on variables?
Is it 380 to 730?
Second, what CIE_CMF_X / Y / Z are you using?
Is it the 1931 2 degree CMF or the 1964 10 degree CMF?
Comparing with CIE published data, I can't make where you got the numbers from?
The text was updated successfully, but these errors were encountered: