Color rendering of spectra

author:Tobias Kölling <tobias.koelling@physik.uni-muenchen.de>

This module can convert spectra to RGB. It is inspired by John Walkers specrend.c and the respective python version of Andrew Hutchins, but is completely rewritten.

The wavelenth resampling code is from Florian Ewald <florian.ewald@campus.lmu.de>.

Usage:

>>> spectralimage = ... #some spectral image
>>> spectralbands = ... #the corresponding wavelengths
>>> converter = SpecRGBConverter(spectralbands)
>>> rgbimage = converter.spectrum_to_rgb(spectralimage)

The original specrend.py comment:

            Colour Rendering of Spectra

                by John Walker
            http://www.fourmilab.ch/

    Last updated: March 9, 2003

Converted to Python by Andrew Hutchins, sometime in early
2011.

    This program is in the public domain.
    The modifications are also public domain. (AH)

For complete information about the techniques employed in
this program, see the World-Wide Web document:

        http://www.fourmilab.ch/documents/specrend/

The xyz_to_rgb() function, which was wrong in the original
version of this program, was corrected by:

    Andrew J. S. Hamilton 21 May 1999
    Andrew.Hamilton@Colorado.EDU
    http://casa.colorado.edu/~ajsh/

who also added the gamma correction facilities and
modified constrain_rgb() to work by desaturating the
colour by adding white.

A program which uses these functions to plot CIE
"tongue" diagrams called "ppmcie" is included in
the Netpbm graphics toolkit:
    http://netpbm.sourceforge.net/
(The program was called cietoppm in earlier
versions of Netpbm.)
class runmacs.spec.util.specrend.CieColorTable(wvlns)[source]

Represents a color sensitivity function for given wavelenths. :param wvlns: list of wavelengths to interpolate the sensitivity on.

resample_wvlns(wvlns)[source]

Resamples the color table to a set of given wavelenths.

Author:Florian Ewald <florian.ewald@campus.lmu.de>
Parameters:wvlns – Wavelengths to resample to.
class runmacs.spec.util.specrend.ColorSystem[source]

Baseclass for a general color system.

add_gamma(rgb)[source]

Adds gamma correction to a given rgb image.

Note:The image must be given in float, normalized to 0…1
class runmacs.spec.util.specrend.MatrixColorSystem(name, xyz2rgb, gamma)[source]

ColorSystem defined by a linear transformation w.r.t. XYZ space.

class runmacs.spec.util.specrend.SpecRGBConverter(wvlns, colorsystem=<sRGB ColorSystem>)[source]

Converter for spectra to RGB images.

The default color system is sRGB because it is the most widely adopted color system on the web.

Note:

Check self.colortable.wvlns_idx for the taken spectral indices. The spectra will be contrained to these indices when the transformation is applied.

Parameters:
  • wvlns – List of wavelengths of the spectra to convert.
  • cs – RGB color system to convert to (default: SRGB)
crop_spectrum(spectrum)[source]

Crop a given spectrum to the used wavelengths, assuming the spectrum is either given with the same wavelenths as in __init__ or already cropped (-> this function is idempotent)

Parameters:spectrum – over-defined spectrum
Returns:spectrum only on needed wavelengths
spectrum_to_rgb(source, postprocess=True)[source]

Calculate the R, G, B coordinates corresponding to a light source with spectral distribution given by source. The spectral axis must be the last axis, the spectrum must be defined in equidistant steps, either on the wavelenths defined during the __init__ call, or already cropped to self.colortable.wvlns.

Note:

Use postprocess only on full images, not on slices!

Parameters:
  • source – a […,nwvlns] - shaped input spectral distribution
  • postprocess – If set to True, a ‘ready-to-store’ rgb image will be returned.
Returns:

RGB image

spectrum_to_xyz(spectrum)[source]

Calculate the CIE X, Y, and Z coordinates corresponding to a light source with spectral distribution given by spectrum. spectrum must be a numpy array and the last dimension must be the spectral dimension with equally spaced wavelengths equal to self.wvlns.

Parameters:spectrum – Input spectrum
Returns:Image in xyz coordinates (not normalized)
xyz_to_rgb(xyz)[source]

convert xyz to RGB according to the defined color system :param xyz: Input image in xyz coordinates :return: Image in rgb coordinates (not normalized)

class runmacs.spec.util.specrend.SpecrendColorSystem(csdef)[source]

ColorSystem corresponding to the original specrend implementation of John Walker.

classmethod cs2mat(cs)[source]

Given an additive tricolour system CS, defined by the CIE x and y chromaticities of its three primaries (z is derived trivially as 1-(x+y)), and a desired chromaticity (XC, YC, ZC) in CIE space, determine the contribution of each primary in a linear combination which sums to the desired chromaticity. If the requested chromaticity falls outside the Maxwell triangle (colour gamut) formed by the three primaries, one of the r, g, or b weights will be negative.

Caller can use constrain_rgb() to desaturate an outside-gamut colour to the closest representation within the available gamut and/or norm_rgb to normalise the RGB components so the largest nonzero component has value 1.

runmacs.spec.util.specrend.array_max_dynamic_range(arr)[source]

Returns an array scaled to a minimum value of 0 and a maximum value of 1.

runmacs.spec.util.specrend.constrain_rgb(rgb, inplace=False)[source]

If the requested RGB shade contains a negative weight for one of the primaries, it lies outside the colour gamut accessible from the given triple of primaries. Desaturate it by adding white, equal quantities of R, G, and B, enough to make RGB all positive.

runmacs.spec.util.specrend.display(filename)[source]

Display RGB image from netCDF file

runmacs.spec.util.specrend.float2byte(arr)[source]

Convert float [0 … 1]-valued array to uint byte array.

runmacs.spec.util.specrend.gamma_rec709(rgb)[source]

Compute REC709 Gamma (according to the original specrend.py)

runmacs.spec.util.specrend.gamma_srgb(rgb)[source]

Compute sRGB Gamma according to: http://www.w3.org/Graphics/Color/sRGB

Parameters:rgb – rgb-array WITHOUT gamma, values 0.0…1.0 (linear data)
Returns:rgb-array WITH gamma, values 0.0…1.0 (nonlinear data)
runmacs.spec.util.specrend.gamma_srgb_reverse(rgb)[source]

Compute sRGB Gamma according to: http://www.w3.org/Graphics/Color/sRGB

Parameters:rgb – rgb-array WITH gamma, values 0.0…1.0 (nonlinear data)
Returns:rgb-array WITHOUT gamma, values 0.0…1.0 (linear data)
runmacs.spec.util.specrend.load(filename)[source]

Load calibrated netCDF file and return RGB image

runmacs.spec.util.specrend.norm_array(arr)[source]

Returns an array scaled to a maximum value of 1.

runmacs.spec.util.specrend.postProcessRGB(rgb, colorsystem=<sRGB ColorSystem>)[source]

Post process an rgb image.

This is normalize to full dynamic range, apply gamma and convert to 8bit uint.

Note:

This function will give errorneous results, if applied only on image slices.

Note:

This function operates in-place, so the input rgb will be overwritten!

Parameters:
  • cs – Color system to use
  • rgb – Preprocessed rgb image
runmacs.spec.util.specrend.set_outliers_to_zero(arr)[source]

Set all pixels which are bigger than 100 times the median to 0

runmacs.spec.util.specrend.tojpg(filename)[source]

Convert a calibrated netCDF file to RGB JPEG.