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
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 General Public License as published by 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