# 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.
0029 %
0030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0031 %   This program is free software; you can redistribute it and/or modify
0033 %   the Free Software Foundation; either version 2 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 General Public License for more details.
0040 %
0041 %   You can obtain a copy of the GNU General Public License from
0042 %   http://www.gnu.org/copyleft/gpl.html or by writing to
0043 %   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
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