Learn R Programming

colorSpec (version 1.5-0)

canonicalOptimalColors: compute the Canonical Optimal Colors

Description

Consider a colorSpec object x with type equal to 'responsivity.material'. The set of all possible material reflectance functions (or transmittance functions) is convex, closed, and bounded (in any reasonable function space), and this implies that the set of all possible output responses from x is also convex, closed, and bounded. The latter set is called the object-color solid or Rösch Farbkörper for x. A color on the boundary of the object-color solid is called an optimal color for x. The corresponding transmittance spectrum is called an optimal spectrum for x. The special points W (the response to the perfect reflecting diffuser) and 0 (the response to the perfect absorbing diffuser) are optimal.

Currently the function only works if the number of spectra in x is 3 (e.g. RGB or XYZ). In this case the object-color solid is a zonohedron whose boundary is the union of parallelograms, which may be coplanar. These parallelograms are indexed by distinct pairs of the wavelengths of x; if x has N wavelengths, then there are N*(N-1) parallelograms. The center of each parallelogram is called a canonical optimal color. Interestingly, the special points W and 0 are not canonical.

Usage

# S3 method for colorSpec
canonicalOptimalColors( x, lambda, spectral=FALSE )

Value

If argument spectral=FALSE, canonicalOptimalColors() returns a data.frame with a row for each row in lambda. The columns in the output are:

lambda

the given matrix argument lambda

optimal

the computed optimal colors - an Mx3 matrix

transitions

the number of transitions in the optimal spectrum, this is a positive even number

If rownames(lambda) is not NULL, they are copied to the row names of the output.

If argument spectral=TRUE, it returns a colorSpec object with quantity 'transmittance'. This object contains the optimal spectra, and the above-mentioned data.frame can then be obtained by applying extradata() to the returned object.

In case of global error, the function returns NULL.

Arguments

x

a colorSpec object with type equal to 'responsivity.material' and 3 spectra

lambda

a numeric Mx2 matrix whose rows contain distinct pairs of wavelengths of x, or a numeric vector that can be converted to such a matrix, by row. If any entry in lambda is not a wavelength of x, it is an error.

spectral

if TRUE, the function returns a colorSpec object with the optimal spectra, see Value.

Details

The 3 responsivities are regarded not as continuous functions, but as step functions. This implies that the color solid is a zonohedron. In the preprocessing phase the zonohedral representation is calculated. The faces of the zonohedron are either parallelograms, or compound faces that can be partitioned into parallelograms. The centers of all these parallelograms are the canonical optimal colors.
The optimal spectra take value 1/2 at the 2 given wavelengths, and 0 or 1 elsewhere. If the 2 wavelengths are \(\lambda_1\) and \(\lambda_2\), and \(\lambda_1 < \lambda_2\) then the spectrum is approximately a bandpass filter. If the 2 wavelengths are swapped, then the spectrum is "flipped" and is approximately a bandstop filter.

References

Centore, Paul. A zonohedral approach to optimal colours. Color Research & Application. Vol. 38. No. 2. pp. 110-119. April 2013.

Logvinenko, A. D. An object-color space. Journal of Vision. 9(11):5, 1-23, (2009).
https://jov.arvojournals.org/article.aspx?articleid=2203976 doi:10.1167/9.11.5.

Schrödinger, E. (1920). Theorie der Pigmente von grösster Leuchtkraft. Annalen der Physik. 62, 603-622.

West, G. and M. H. Brill. Conditions under which Schrödinger object colors are optimal. Journal of the Optical Society of America. 73. pp. 1223-1225. 1983.

See Also

probeOptimalColors(), bandRepresentation(), scanner.ACES, extradata(), type, vignette Convexity and Transitions

Examples

Run this code
wave    = seq(400,700,by=5)
D50.eye = product( D50.5nm, 'material', xyz1931.1nm, wavelength=wave )
canonicalOptimalColors( D50.eye, c(500,600, 550,560, 580,585) )
##    lambda.1 lambda.2   optimal.x   optimal.y   optimal.z transitions
##  1      500      600 47.02281830 80.07281030  4.33181530           2
##  2      550      560  5.18490614 10.09045773  0.06121505           2
##  3      580      585 26.91247649 21.49031008  0.03457904           6

Run the code above in your browser using DataLab