# Computing XYZ from SPD and reflectances

**URL:** <https://psychtoolbox.discourse.group/t/computing-xyz-from-spd-and-reflectances/1047>\
**Category:** Uncategorized\
**Created:** [September 22, 2000, 12:32am UTC](https://psychtoolbox.discourse.group/t/computing-xyz-from-spd-and-reflectances/1047 "2000-09-22T00:32:10Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Allen\_Ingling](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@Allen\_Ingling](https://psychtoolbox.discourse.group/u/Allen_Ingling)\
**Post date:** [September 22, 2000, 12:32am UTC](https://psychtoolbox.discourse.group/t/computing-xyz-from-spd-and-reflectances/1047/1 "2000-09-22T00:32:10Z")

</div>

Hi,  
  
I'm interesting in computing XYZ values for a surface under a given   
illuminant. I can't find anything in the Toolbox that does exactly   
that. But there are some Access databases for the 1931 and 1964   
observer already in the Toolbox. I already have tools to resample my   
measurements to different samplings.   
  
1) Have I missed this code and it's already available?  
2) Is there anything similiar that someone would recommend as a good   
model for what I want to do?  
3) What do the samples in the database look like? Are they the 1 nm   
data from CIE Disk 1? Or are they at some other sampling and range?  
  
  
I'm a complete novice at MATLAB programming, and know even less about   
using ACCESS, but it's either MATLAB or C, and I know it'd be a pain   
to code this in C.  
  
I'm doing all this on a PC running Windows 2000. Most of the toolbox   
doesn't work for me, I keep getting segmentation violation errors.   
It's still a great thing and I appreciate that someone's done all   
this work. (Someday we may buy a Mac for our lab and then I'll be   
really in luck.)   
  
  
Todd Newman

---

<div class="post-metadata">

**Author:** ![Allen\_Ingling](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@Allen\_Ingling](https://psychtoolbox.discourse.group/u/Allen_Ingling)\
**Post date:** [September 22, 2000, 5:24am UTC](https://psychtoolbox.discourse.group/t/computing-xyz-from-spd-and-reflectances/1047/2 "2000-09-22T05:24:46Z")

</div>

> \>  
> \>Hi,  
> \>  
> \>I'm interesting in computing XYZ values for a surface under a given  
> \>illuminant. I can't find anything in the Toolbox that does exactly  
> \>that. But there are some Access databases for the 1931 and 1964  
> \>observer already in the Toolbox. I already have tools to resample my  
> \>measurements to different samplings.  
> \>  
> \>1) Have I missed this code and it's already available?

There isn't a routine for this, but it is very quick in MATLAB  
given the toolbox data structures. Here's an example:  
  
% Load CIE XYZ color matching functions (they are in the rows)  
load T\_xyz1931  
  
% Load CIE D65 daylight (it is in a column)  
load spd\_D65  
  
% Load surface reflectance functions of Macbeth color checker (they   
are in columns)  
»load sur\_macbeth  
  
% This line then computes the XYZ values of the color checker under D65.  
% The XYZ values end up in the columns of xyz\_macbeth.  
% It works so easily because of the conventions chosen for color matching  
% functions in rows and surface reflectance functions in columns. The  
% MATLAB function diag makes a diagonal matrix out of its argument.  
xyz\_macbeth = T\_xyz1931\*diag(spd\_D65)\*sur\_macbeth;  
  
% You can easily convert to chromaticity. See "help PsychColorimetric"  
% of other conversions easily available.  
xyY\_macbeth = XYZToxyY(xyz\_macbeth).  
  
% The CIE standard daylight is normalized in some fashion, so it doesn't  
% represent real units. If you want to go to the CIE convention for  
% surfaces, you'd compute the XYZ values of this illuminant and  
% divide the surface values by it, then multiply by 100. The  
% first line computes the XYZ values of the illuminant as reflected  
% off a perfect diffuser. The second just normalizes, using some MATLAB  
% indexing tricks to make the dimensions match.  
xyz\_illuminant = T\_xyz1931\*spd\_D65;  
xyz\_macbeth\_normalized = 100\*xyz\_macbeth ./   
(xyz\_illuminant(:,ones(1,size(xyz\_macbeth,2))));  
  
% If the illuminant was in specified in units of   
watts/(sr-m2-wavelength band) then you  
% and you wanted luminance in cd/m2, then you could compute the following.  
% In the expression, 683 is a standard constant. Here spd\_D65 is just  
% normalized in some way that I don't remember so I don't think you're  
% working in real units. But if you were, then the middle row of the  
% following would be in units of cd/m2.  
xyz\_macbeth\_cdm2 = 683\*T\_xyz1931\*diag(spd\_D65)\*sur\_macbeth;  
  
My chapter on colorimetry develops a lot of standard calculations in a form  
that is easly translated into MATLAB: Brainard, D.H. (1995). Colorimetry.  
In OSA Handbook of Optics: Volume 1. Fundamentals, Techniques, and Design,  
M. Bass (ed), McGraw-Hill, Inc., New York  
  

> \>2) Is there anything similiar that someone would recommend as a good  
> \>model for what I want to do?  
> \>3) What do the samples in the database look like? Are they the 1 nm  
> \>data from CIE Disk 1? Or are they at some other sampling and range?

type "help PsychColorimetricData at the MATLAB prompt and you'll  
get a fairly complete description of the data format.  
  
The sampling is 5 nm samples between 380 and 780. Some datasets  
were not available over the full range and were extended with zeros.  
See SplineSpd, SplineSrf, and SplineCmf for standard interface to  
routines that change wavelength sampling. Note the convention that power is  
specified as power per wavelength band, so that the values in  
spectral power distributions are changed in proportion to the  
wavelength sampling interval when you resample. This convention  
means that you don't have to multiply by delta lambda when you compute.  
  

> \>I'm doing all this on a PC running Windows 2000. Most of the toolbox  
> \>doesn't work for me, I keep getting segmentation violation errors.  
> \>It's still a great thing and I appreciate that someone's done all  
> \>this work. (Someday we may buy a Mac for our lab and then I'll be  
> \>really in luck.)

I think you're the first to try the Windows version under Windows  
2000. One more thing for us to try to get fixed when we manage  
to hire a windows programmer.  
  
DB
