TransWikia.com

Integrating over colors

Mathematica Asked by Diffycue on February 18, 2021

I’m trying to compute the following integral:

$$int_{380 , mathrm{nm}}^{700 , mathrm{nm}}mathbf{RGB}(mathrm{Hue}(lambda))frac{mathrm{d}lambda}{lambda^4}$$

where $mathbf{RBG}$ takes in a Hue and outputs a vector like {0., 1., 1.}.

This is how I’ve tried to implement this:

lambdaToHue[wavelength_] := Hue[-.8/(700 - 380) wavelength + 1.75]

which takes wavelengths into Hues, (evaluating it on 380 gives purple, on 700 gives red). Then

hueToRBG[hue_] := Table[ColorConvert[hue, "RGB"][[i]], {i, 1, 3}]

takes Hues into vectors, so e.g. evaluating it on lambdaToHue[380] gives {0.8, 0., 1.}. So I can put in values for wavelength and get numbers from hueToRBG[wavelengthToHue[wavelengths]]. So I should be able to compute an integral, like

NIntegrate[hueToRBG[lambdaToHue[l]]/l^4,{l,380,700}]

but in reality Mathematica complains:

"The integrand Hue[1.75 -0.0025 l] has evaluated to 
non-numerical values for all sampling points in the region with 
boundaries {{380,700}}"

How can I get mathematica to actually just compute the integral of this function which takes numbers into lists of numbers? It works fine, e.g., for

NIntegrate[{x,Sin[x],Sqrt[x]}/x^4,{x,2,4}].

Much thanks!

One Answer

As noted in this thread, the CIE sensitivity functions are built-in, yet undocumented:

ChromaticityPlot; (* force autoload *)
xyz = Interpolation[Transpose[{Image`ColorOperationsDump`$wavelengths, #}]] & /@ 
      Transpose[Image`ColorOperationsDump`tris];

However,

MinMax[Image`ColorOperationsDump`$wavelengths]
   {{385, 745}}

its coverage is a little off from the desired integral in the OP, so I'll just demonstrate the integral from $385$ to $700,mathrm{nm}$. (If wanted, you can download a finer tabulation with more coverage.)

From here, we can use the sRGB conversion functions from this answer, and then use NIntegrate[] with the setting Method -> "InterpolationPointsSubdivision":

(* gamma correction *)
sRGBGamma = Function[x, With[{z = Abs[x]},
                             Sign[x] Piecewise[{{12.92 z, z <= 0.0031308}},
                                               1.055 z^(1/2.4) - 0.055]],
                     Listable];

NIntegrate[Clip[#, {0, 1}]/λ^4, {λ, 385, 700},
           Method -> "InterpolationPointsSubdivision"] & /@ 
sRGBGamma[{{3.2404542, -1.5371385, -0.49853141},
           {-0.96926603, 1.8760108, 0.041556017},
           {0.055643431, -0.20402591, 1.0572252}}.Through[xyz[λ]]]
   {1.48544*10^-9, 1.36666*10^-9, 2.28451*10^-9}

Answered by J. M.'s ennui on February 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP