%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Matlab Code for CRT Calibration
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PR650 Set-up
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Must clear the serial port for PR650 to properly
interact with Matlab
ieClearSerialPorts;
% Must set the serial port to the port the PR650
is connected to
SerialPort = 4;
meter = cmeter( SerialPort );
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Color maps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create color maps for each phosphor
% Columns are RGB values, row indicies correspond
to digital value
length = 256;
for i = 1:length
redmap( i,: ) = [ ( i-1 )/( length-1
) 0
0 ];
greenmap( i,: ) = [ 0
( i-1 )/( length-1 ) 0 ];
bluemap( i,: ) = [ 0
0
( i-1 )/( length-1 )];
end
clear i
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% PSD measurements
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Step through the digital values and measure
the PSD of each color
for DV = 1:1:length
% for i = start:increment:finish
% Display a square
figure( 1 )
image( DV )
title( DV )
% Color it red
colormap( redmap )
% Take measurement
[DataRed(:,DV),wavelength(:,DV)]=getdata(meter);
% Color it green
colormap( greenmap )
% Take measurement
[DataGreen(:,DV),wavelength(:,DV)]=getdata(meter);
% Color it blue
colormap( bluemap )
% Take measurement
[DataBlue(:,DV),wavelength(:,DV)]=getdata(meter);
end
clear DV
% Save variables beginning with 'Data' to GammaData.mat
save GammaData Data*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Phosphor PSDs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create the montior phosphor matrix (i.e. R,
G, B PSDs at max)
Monitor = [ DataRed( :,length ) DataGreen( :,length ) DataBlue( :,length
)];
figure( 2 )
plot( wavelength(:,256), Monitor(:,1), '-r', ...
wavelength(:,256), Monitor(:,2),
'-g', ...
wavelength(:,256), Monitor(:,3),
'-b' )
title( 'Monitor Phosphor PSDs' )
xlabel( 'Wavelength [ nm ]' ), ylabel( 'Radiance [ W / m^2 / sr / nm
]' )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Gamma
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To create gamma function, sum the PSDs across
wavelength and scale by the maximum value of the PSD
GammaTemp = [ sum( DataRed, 1 )
sum( DataGreen, 1 )
sum( DataBlue, 1 ) ];
ScaledGamma = [ GammaTemp( 1,: )/GammaTemp( 1,length )
GammaTemp( 2,: )/GammaTemp( 2,length )
GammaTemp( 3,: )/GammaTemp( 3,length ) ]';
% Plot the measured gamma functions
DV = [ 1:256 ];
figure( 3 )
plot( DV, ScaledGamma( :,1 ), '-r', ...
DV, ScaledGamma( :,2 ), '-g', ...
DV, ScaledGamma( :,3 ), '-b' )
% Estimate the gamma with zero intercept
error = [ 100 100 100 ]; %
[ rederror greenerror blueerror ]
Gamma = [ 2 2 2 ];
% [ redgamma greengamma bluegamma ]
for g = 2:0.01:3.0
e = [ 0 0 0 ];
% running sum of errors
for DV = 1:length
Est = ( DV/length )^g;
e( 1 ) = e( 1 ) + abs( Est
- ScaledGamma( DV,1 ));
e( 2 ) = e( 2 ) + abs( Est
- ScaledGamma( DV,2 ));
e( 3 ) = e( 3 ) + abs( Est
- ScaledGamma( DV,3 ));
end
for i = 1:3
if( e( i ) < error( i
))
error( i ) = e( i ); %
new minimum error
Gamma( i ) = g; %
and the gamma that achieved that
end
end
clear i
end
clear g, clear DV
% Create the estimated gamma functions
DV = [ 1:256 ];
GammaFctRed = (DV./length).^Gamma(1);
GammaFctGreen = (DV./length).^Gamma(2);
GammaFctBlue = (DV./length).^Gamma(3);
% plot the estimated gamma functions
figure( 4 )
hold on
plot( DV, GammaFctRed , '-r' , DV, GammaFctGreen, '-g', DV, GammaFctBlue,
'-b' )
plot( DV, ScaledGamma( :,1 ), '.r', DV, ScaledGamma( :,2 ), '-g', DV,
ScaledGamma( :,3 ), '-b' )
hold off
title( 'Estimated Gamma Functions' )
xlabel( 'Digital Value' ); ylabel( 'Intensity' )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Inverse Gamma
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I = [ 0:1/(length-1):1 ];
GammaInvRed = I.^(1/Gamma(1));
GammaInvGreen = I.^(1/Gamma(2));
GammaInvBlue = I.^(1/Gamma(3));
% plot the inverse gamma functions
figure( 5 )
plot( DV, GammaInvRed , '-r*', DV, GammaInvGreen, '-gx', DV, GammaInvBlue,
'-b' )
title( 'Inverse Gamma Functions' )
xlabel( 'Intensity' ); ylabel( 'Digital Value' )
% Save Gamma data
save GammaPlots Gamma*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Gamma Verification
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% To verify the calculated gamma values, convert
desired intensities to digital values using the inverse gamma
% function and measure the output intensity.
InvGammaRedMap = [];
InvGammaGreenMap = [];
InvGammaBlueMap = [];
% Convert intensities to digital values
for i = 0:0.1:1.0
InvGammaRedMap = [ InvGammaRedMap
i^(1/Gamma(1)) 0 0 ];
InvGammaGreenMap = [ InvGammaGreenMap
0 i^(1/Gamma(2)) 0 ];
InvGammaBlueMap = [ InvGammaBlueMap
0 0 i^(1/Gamma(3)) ];
end
for i = 1:size( InvGammaRedMap, 1 )
% Display a square
figure( 1 )
image( i )
Intensity( i )^(1/Gamma(1))
title( Intensity( i ))
% Color it red
colormap( InvGammaRedMap )
% Take measurement
[DataRedGamma(:,i),wavelength(:,i)]=getdata(meter);
figure( 1 )
image( i )
title( Intensity( i ))
% Color it green
colormap( InvGammaGreenMap )
% Take measurement
[DataGreenGamma(:,i),wavelength(:,i)]=getdata(meter);
figure( 1 )
image( i )
title( Intensity( i ))
% Color it blue
colormap( InvGammaBlueMap )
% Take measurement
[DataBlueGamma(:,i),wavelength(:,i)]=getdata(meter);
end
clear i
MeasuredIntensity = [ sum( DataRedGamma, 1 )
sum( DataGreenGamma, 1 )
sum( DataBlueGamma, 1 ) ];
IntensityOut = [ MeasuredIntensity( 1,: )/MeasuredIntensity( 1,11 )
MeasuredIntensity( 2,: )/MeasuredIntensity( 2,11 )
MeasuredIntensity( 3,: )/MeasuredIntensity( 3,11 ) ];
% Plot the desired intensity versuses the measured
intensity
IntensityIn = [ 0:0.1:1.0 ]
figure( 6 )
plot( IntensityIn, IntensityOut' )
title( 'Gamma Verification' )
xlabel( 'Intensity In' ), ylabel( 'Intensity Out' )
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Phosphor Independence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a color map that contains every combination
of RGB values corresponding to intensities 0.2, 0.6, and 1.0
DVMap = [];
IntensityMap = [];
% i, j, k represent the Intensity we'd like to
see at the output
for i = 0.2:0.4:1.0
for j = 0.2:0.4:1.0
for k = 0.2:0.4:1.0
% must convert to digital value so correct intensity is displayed on screen
DVMap = [ DVMap
(i^(1/Gamma(1))) (j^(1/Gamma(2))) (k^(1/Gamma(3))) ];
%
will use the non-scaled intensity values to calculate the ideal thingies.
IntensityMap = [ IntensityMap
i j k ];
end
end
end
clear i, clear j, clear k
% Measure PSD of multi-phosphor colors
for i = 1:27
% Display a square
figure( 1 )
image( i )
% Color it
colormap( DVMap )
% Take measurement
[DataIndep(:,i),wavelength(:,i)]=getdata(meter);
end
clear i
% figure( 7 )
% plot( DataIndep )
% Ideal = Monitor * IntensityMap';
% figure( 8 )
% plot( Ideal )
% Check for full rank so we can use least-squares
approximation
rank( Monitor ) % Rank = 3...good!
for i = 1:27
rgb(i,:) = Monitor\DataIndep(:,i);
end
clear i
% Calculate Relative Error
IndepError = (rgb - IntensityMap)/IntensityMap;
Error = sort(IndepError, 1 );
Index = [1:27];
figure( 9 )
plot( Index, Error( :,1 ), '-r', Index, Error( :,2 ), '-g', Index,
Error( :,3 ), '-b' )
title( 'Relative Error of Phosphor Independence Tests' )
% Plot relative error in RGB values versus intended
intensity
figure( 10 )
hold on
plot (IntensityMap(:,1), IndepError(:,1),'r*')
plot (IntensityMap(:,2), IndepError(:,2),'g*')
plot (IntensityMap(:,3), IndepError(:,3),'b*')
title( 'Relative Error of Phosphor Independence Tests' )
xlabel( 'Input Intensity' ), ylabel( 'Percent Error' )
hold off
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Phosphor Independence
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a 3x3 matrix that converts monitor RGB
values to fly cone sensitivities
load FlyData % a fat
matrix containing the spectral sensitivies of each of the relevant Drosophila
cones in the rows
CalibrationMatrix = FlyCones * Monitor;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Delete the meter - it gets angry if you
don't and you'll have to shut Matlab down and restart it
% before you can use the meter again
delete(meter);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Save all data collected and calculated values
% save Everything