# v_lambda2rgb

## PURPOSE

V_LAMBDA2XYZ Convert wavelength to XYZ or RGB colour space X=(L,M)

## SYNOPSIS

function x=v_lambda2rgb(l,m)

## DESCRIPTION

    V_LAMBDA2XYZ Convert wavelength to XYZ or RGB colour space X=(L,M)

    Inputs:   l(n,1)  column vector of wavelengths in nanometres
              m       mode:
                        r - output is [R G B] using the 1931 observer with negative values eliminated [default]
                        s - output is [R G B] using the 1931 observer with signed values
                        x - output ix [X Y Z] using the 1931 observer

                        Use uppercase 'X', 'R' etc for the 1964 observer instead

     Outputs: x(n,3)  tristimulus output values

     The formulae are taken from [1] and were obtained by numerical curve
     fitting to the CIE standard observer data available from [2].

     References:
      [1]    C. Wyman, P.-P. Sloan, and P. Shirley.
           Simple analytic approximations to the CIE XYZ color matching functions.
           Journal of Computer Graphics Techniques, 2 (2): 1-11, 2013.
      [2]    D. Wyble. Useful color data. Website, Rochester Institute of Technology, 2001.
           URL http://www.rit.edu/cos/colorscience/rc_useful_data.php

## CROSS-REFERENCE INFORMATION

This function calls:

- v_lambda2rgb V_LAMBDA2XYZ Convert wavelength to XYZ or RGB colour space X=(L,M)

This function is called by:

- v_lambda2rgb V_LAMBDA2XYZ Convert wavelength to XYZ or RGB colour space X=(L,M)

## SOURCE CODE

    0001 function x=v_lambda2rgb(l,m)
    0002 %V_LAMBDA2XYZ Convert wavelength to XYZ or RGB colour space X=(L,M)
    0003 %
    0004 %Inputs:   l(n,1)  column vector of wavelengths in nanometres
    0005 %          m       mode:
    0006 %                    r - output is [R G B] using the 1931 observer with negative values eliminated [default]
    0007 %                    s - output is [R G B] using the 1931 observer with signed values
    0008 %                    x - output ix [X Y Z] using the 1931 observer
    0009 %
    0010 %                    Use uppercase 'X', 'R' etc for the 1964 observer instead
    0011 %
    0012 % Outputs: x(n,3)  tristimulus output values
    0013 %
    0014 % The formulae are taken from [1] and were obtained by numerical curve
    0015 % fitting to the CIE standard observer data available from [2].
    0016 %
    0017 % References:
    0018 %  [1]    C. Wyman, P.-P. Sloan, and P. Shirley.
    0019 %       Simple analytic approximations to the CIE XYZ color matching functions.
    0020 %       Journal of Computer Graphics Techniques, 2 (2): 1-11, 2013.
    0021 %  [2]    D. Wyble. Useful color data. Website, Rochester Institute of Technology, 2001.
    0022 %       URL http://www.rit.edu/cos/colorscience/rc_useful_data.php
    0023
    0024 %      Copyright (C) Mike Brookes 2014
    0025 %      Version: $Id: v_lambda2rgb.m 10865 2018-09-21 17:22:45Z dmb $
    0026 %
    0027 %   VOICEBOX is a MATLAB toolbox for speech processing.
    0028 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
    0029 %
    0030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0031 %   This program is free software; you can redistribute it and/or modify
    0032 %   it under the terms of the GNU Lesser General Public License as published by
    0033 %   the Free Software Foundation; either version 3 of the License, or
    0034 %   (at your option) any later version.
    0035 %
    0036 %   This program is distributed in the hope that it will be useful,
    0037 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
    0038 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0039 %   GNU Lesser General Public License for more details.
    0040 %
    0041 %   You can obtain a copy of the GNU Lesser General Public License from
    0042 %   https://www.gnu.org/licenses/ .
    0043 %
    0044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0045 persistent c d xr rx
    0046 if isempty(c)
    0047     c=[1.065 -0.5/33.33^2 595.8 0.366 -0.5/19.44^2 446.8 1.014 -0.5/0.075^2 log(556.3) 1.839 -0.5/0.051^2 log(449.8)];
    0048     d=[0.398 -1250 -570.1 -log(1014) 1.132 -234 1338 1300 -log(743.5) 1.011 -0.5/46.14^2 556.1 2.06 -32 265.8 -log(180.4)];
    0049     xr=[0.49 0.31 0.2; 0.17697 0.8124 0.01063; 0 0.01 0.99];
    0050     xr=xr'/xr(2);
    0051     rx=inv(xr);
    0052 end
    0053 if nargin<1
    0054     l=[];
    0055 end
    0056 lv=l(:);
    0057 if nargin<2
    0058     m='r';
    0059 end
    0060 lm=lower(m);
    0061 if m==lm % use 1931 standard observer
    0062     ll=log(lv);
    0063     x=[c(1)*exp(c(2)*(lv-c(3)).^2)+c(4)*exp(c(5)*(lv-c(6)).^2) c(7)*exp(c(8)*(ll-c(9)).^2) c(10)*exp(c(11)*(ll-c(12)).^2)];
    0064 else % use 1964 standard observer
    0065     x=[d(1)*exp(d(2)*(log(lv-d(3))+d(4)).^2)+d(5)*exp(d(6)*(log(d(7)-min(lv,d(8)))+d(9)).^2) d(10)*exp(d(11)*(lv-d(12)).^2) d(13)*exp(d(14)*(log(lv-d(15))+d(16)).^2)];
    0066 end
    0067 if lm=='s'
    0068     x=x*rx;
    0069 elseif lm=='r'
    0070     x=max(x*rx,0);
    0071 end
    0072 if ~nargout
    0073     if numel(l)<10
    0074         la=linspace(360,740,200)';
    0075         xa=v_lambda2rgb(la,m);
    0076     else
    0077         la=l;
    0078         xa=x;
    0079     end
    0080     plot(la,xa(:,1),'r-',la,xa(:,2),'g-',la,xa(:,3),'b-');
    0081     if numel(l)<10 && numel(l)>0
    0082         hold on
    0083         plot(l,x(:,1),'ro',l,x(:,2),'go',l,x(:,3),'bo');
    0084         hold off
    0085     end
    0086     xlabel('Wavelength, \lambda (nm)');
    0087     switch lm
    0088         case 'x'
    0089             cstr='XYZ';
    0090         case 's'
    0091             cstr='RGB';
    0092         case 'r'
    0093             cstr='RGB+';
    0094     end
    0095     if lm==m
    0096         yr=1931;
    0097     else
    0098         yr=1964;
    0099     end
    0100     legend(cstr(1), cstr(2), cstr(3));
    0101     title(sprintf('%d Standard Observer (%s)',yr,cstr));
    0102 end
    0103
    0104