s_sensorMacbethEstimateIlluminant

It is possible to use sensor measurements of an MCC to estimate a daylight illuminants. This script illustrates the logic of the calculation. We also wrote a function that implements this calculation starting from a sensor image with an MCC image in it.

There are 3 daylight basis functions and we aim to estimate three weights for those functions. We can express the predicted camera data,C, for the MCC this way:

   C = sum w_i SQE * diag(dayBasis_i) * MCC

where C are the RGB values of the sensor (3 x 24) SQE is the spectral quantum efficiency of the camera, dayBasis_i is the ith basis function of the cie daylights, MCC columns are the reflectance functions of the Macbeth Color Checker.

See also sensorMacbethDaylightEstimate(sensor,varargin);

Contents

Read the reflectance functions of the MCC

wave = 400:10:700;
reflectance = macbethReadReflectance(wave);
% plotReflectance(wave,reflectance);

Pick the default sensor

sensor = sensorCreate;
sensorFilters = sensorGet(sensor,'spectral qe');
% ieNewGraphWin; plot(wave,sensorFilters);

These are the CIE basis functions for daylights

% Read the daylight basis, which is specified in energy.  Convert the basis
% terms to photons because we normally compute with photons in ISETCam.
dayBasis = ieReadSpectra('cieDaylightBasis.mat',wave);
dayBasis = Energy2Quanta(wave,dayBasis);
% plotRadiance(wave,dayBasis);

Make up a set of weights for the illuminant

illuminant = illuminantCreate;

w = [1 0 0];
illuminant = illuminantSet(illuminant,'photons',dayBasis*w');
illPhotons = illuminantGet(illuminant,'photons');
% plotRadiance(wave,illPhotons);

Calculate the sensor data

C = sensorFilters'*diag(illPhotons)*reflectance;

Estimation process

% There are three basis functions so the camera data, in the 3x24 matrix C,
% should be the weighted sum of these three matrices.
X1 = sensorFilters'*diag(dayBasis(:,1))*reflectance;
X2 = sensorFilters'*diag(dayBasis(:,2))*reflectance;
X3 = sensorFilters'*diag(dayBasis(:,3))*reflectance;

Stack the three matrices

% Each matrix is a big column
X = [X1(:), X2(:), X3(:)];

% Stack the camera data into a big column
Cstacked = C(:);

The weights are supposed to solve this:

   Cstacked = X w
% We solve for w this way.
%    w =  inv(X'*X) * X' * Cstacked

% Or in Matlab's preferred formulation
A = X'*X;
b = X'*Cstacked;
estimatedW = A\b;
estimatedW = estimatedW/estimatedW(1);
disp(estimatedW)
Warning: Matrix is singular, close to singular or badly scaled. Results may be
inaccurate. RCOND = NaN. 
   NaN
   NaN
   NaN

END