Next: Color Difference Metrics, Previous: Color Spaces, Up: Color [Contents][Index]

The following functions compute colors from spectra, scale color luminance, and extract chromaticity. XYZ is used in the names of procedures for unnormalized colors; the coordinates of CIEXYZ colors are constrained as described in Color Spaces.

`(require 'color-space)`

A spectrum may be represented as:

- A procedure of one argument accepting real numbers from 380e-9 to 780e-9, the wavelength in meters; or
- A vector of real numbers representing intensity samples evenly spaced over some range of wavelengths overlapping the range 380e-9 to 780e-9.

CIEXYZ values are calculated as dot-product with the X, Y (Luminance),
and Z *Spectral Tristimulus Values*. The files `cie1931.xyz`
and `cie1964.xyz` in the distribution contain these CIE-defined
values.

- Feature:
**cie1964** -
Loads the Spectral Tristimulus Values CIE 1964 Supplementary Standard Colorimetric Observer, defining

`cie:x-bar`,`cie:y-bar`, and`cie:z-bar`.

- Feature:
**cie1931** -
Loads the Spectral Tristimulus Values CIE 1931 Supplementary Standard Colorimetric Observer, defining

`cie:x-bar`,`cie:y-bar`, and`cie:z-bar`.

- Feature:
**ciexyz** -
Requires Spectral Tristimulus Values, defaulting to cie1931, defining

`cie:x-bar`,`cie:y-bar`, and`cie:z-bar`.

`(require 'cie1964)`

or `(require 'cie1931)`

will
`load-ciexyz`

specific values used by the following spectrum
conversion procedures. The spectrum conversion procedures
`(require 'ciexyz)`

to assure that a set is loaded.

- Function:
**read-cie-illuminant***path* `path`must be a string naming a file consisting of 107 numbers for 5.nm intervals from 300.nm to 830.nm.`read-cie-illuminant`

reads (using Scheme`read`

) these numbers and returns a length 107 vector filled with them.

(define CIE:SI-D65 (read-CIE-illuminant (in-vicinity (library-vicinity) "ciesid65.dat"))) (spectrum->XYZ CIE:SI-D65 300e-9 830e-9) ⇒ (25.108569422374994 26.418013465625001 28.764075683374993)

- Function:
**read-normalized-illuminant***path* `path`must be a string naming a file consisting of 107 numbers for 5.nm intervals from 300.nm to 830.nm.`read-normalized-illuminant`

reads (using Scheme`read`

) these numbers and returns a length 107 vector filled with them, normalized so that`spectrum->XYZ`

of the illuminant returns its whitepoint.

CIE Standard Illuminants A and D65 are included with SLIB:

(define CIE:SI-A (read-normalized-illuminant (in-vicinity (library-vicinity) "ciesia.dat"))) (define CIE:SI-D65 (read-normalized-illuminant (in-vicinity (library-vicinity) "ciesid65.dat"))) (spectrum->XYZ CIE:SI-A 300e-9 830e-9) ⇒ (1.098499460820401 999.9999999999998e-3 355.8173930654951e-3) (CIEXYZ->sRGB (spectrum->XYZ CIE:SI-A 300e-9 830e-9)) ⇒ (255 234 133) (spectrum->XYZ CIE:SI-D65 300e-9 830e-9) ⇒ (950.4336673552745e-3 1.0000000000000002 1.0888053986649182) (CIEXYZ->sRGB (spectrum->XYZ CIE:SI-D65 300e-9 830e-9)) ⇒ (255 255 255)

- Function:
**illuminant-map***proc siv* `siv`must be a one-dimensional array or vector of 107 numbers.`illuminant-map`

returns a vector of length 107 containing the result of applying`proc`to each element of`siv`.

- Function:
**illuminant-map->XYZ***proc siv* `(spectrum->XYZ (illuminant-map`

`proc``siv`) 300e-9 830e-9)

- Function:
**spectrum->XYZ***proc* `proc`must be a function of one argument.`spectrum->XYZ`

computes the CIEXYZ(1931) values for the spectrum returned by`proc`when called with arguments from 380e-9 to 780e-9, the wavelength in meters.

- Function:
**spectrum->XYZ***spectrum x1 x2* `x1`and`x2`must be positive real numbers specifying the wavelengths (in meters) corresponding to the zeroth and last elements of vector or list`spectrum`.`spectrum->XYZ`

returns the CIEXYZ(1931) values for a light source with spectral values proportional to the elements of`spectrum`at evenly spaced wavelengths between`x1`and`x2`.Compute the colors of 6500.K and 5000.K blackbody radiation:

(require 'color-space) (define xyz (spectrum->XYZ (blackbody-spectrum 6500))) (define y_n (cadr xyz)) (map (lambda (x) (/ x y_n)) xyz) ⇒ (0.9687111145512467 1.0 1.1210875945303613) (define xyz (spectrum->XYZ (blackbody-spectrum 5000))) (map (lambda (x) (/ x y_n)) xyz) ⇒ (0.2933441826889158 0.2988931825387761 0.25783646831201573)

- Function:
**spectrum->chromaticity***proc* - Function:
**spectrum->chromaticity***spectrum x1 x2* Computes the chromaticity for the given spectrum.

- Function:
**wavelength->XYZ***w* `w`must be a number between 380e-9 to 780e-9.`wavelength->XYZ`

returns (unnormalized) XYZ values for a monochromatic light source with wavelength`w`.

- Function:
**wavelength->chromaticity***w* `w`must be a number between 380e-9 to 780e-9.`wavelength->chromaticity`

returns the chromaticity for a monochromatic light source with wavelength`w`.

- Function:
**blackbody-spectrum***temp* - Function:
**blackbody-spectrum***temp span* Returns a procedure of one argument (wavelength in meters), which returns the radiance of a black body at

`temp`.The optional argument

`span`is the wavelength analog of bandwidth. With the default`span`of 1.nm (1e-9.m), the values returned by the procedure correspond to the power of the photons with wavelengths`w`to`w`+1e-9.

- Function:
**temperature->XYZ***x* The positive number

`x`is a temperature in degrees kelvin.`temperature->XYZ`

computes the unnormalized CIEXYZ(1931) values for the spectrum of a black body at temperature`x`.Compute the chromaticities of 6500.K and 5000.K blackbody radiation:

(require 'color-space) (XYZ->chromaticity (temperature->XYZ 6500)) ⇒ (0.3135191660557008 0.3236456786200268) (XYZ->chromaticity (temperature->XYZ 5000)) ⇒ (0.34508082841161052 0.3516084965163377)

- Function:
**temperature->chromaticity***x* The positive number

`x`is a temperature in degrees kelvin.`temperature->cromaticity`

computes the chromaticity for the spectrum of a black body at temperature`x`.Compute the chromaticities of 6500.K and 5000.K blackbody radiation:

(require 'color-space) (temperature->chromaticity 6500) ⇒ (0.3135191660557008 0.3236456786200268) (temperature->chromaticity 5000) ⇒ (0.34508082841161052 0.3516084965163377)

- Function:
**XYZ->chromaticity***xyz* Returns a two element list: the x and y components of

`xyz`normalized to 1 (=`x`+`y`+`z`).

- Function:
**chromaticity->CIEXYZ***x y* Returns the list of

`x`, and`y`, 1 -`y`-`x`.

- Function:
**chromaticity->whitepoint***x y* Returns the CIEXYZ(1931) values having luminosity 1 and chromaticity

`x`and`y`.

Many color datasets are expressed in *xyY* format; chromaticity with
CIE luminance (Y). But xyY is not a CIE standard like CIEXYZ, CIELAB,
and CIELUV. Although chrominance is well defined, the luminance
component is sometimes scaled to 1, sometimes to 100, but usually has no
obvious range. With no given whitepoint, the only reasonable course is
to ascertain the luminance range of a dataset and normalize the values
to lie from 0 to 1.

- Function:
**XYZ->xyY***xyz* Returns a three element list: the

`x`and`y`components of`XYZ`normalized to 1, and CIE luminance`Y`.

- Function:
**xyY->XYZ***xyY*

- Function:
**xyY:normalize-colors***colors* `colors`is a list of xyY triples.`xyY:normalize-colors`

scales each chromaticity so it sums to 1 or less; and divides the`Y`values by the maximum`Y`in the dataset, so all lie between 0 and 1.

- Function:
**xyY:normalize-colors***colors n* If

`n`is positive real, then`xyY:normalize-colors`

divides the`Y`values by`n`times the maximum`Y`in the dataset.If

`n`is an exact non-positive integer, then`xyY:normalize-colors`

divides the`Y`values by the maximum of the`Y`s in the dataset excepting the -`n`largest`Y`values.In all cases, returned

`Y`values are limited to lie from 0 to 1.

Why would one want to normalize to other than 1? If the sun or its reflection is the brightest object in a scene, then normalizing to its luminance will tend to make the rest of the scene very dark. As with photographs, limiting the specular highlights looks better than darkening everything else.

The results of measurements being what they are,
`xyY:normalize-colors`

is extremely tolerant. Negative numbers are
replaced with zero, and chromaticities with sums greater than one are
scaled to sum to one.

Next: Color Difference Metrics, Previous: Color Spaces, Up: Color [Contents][Index]