# What is gamma correction?

The relation between a frame buffer value, typically assigned by 0-255 in your program, and the actual intensity on the monitor is quite non-linear. The relation is expressed by
<Luminance> = constant * <frame buffer value>^GAMMA
where GAMMA ranges 1.8-2.5 depending on the monitor. You cannot tell the gamma value of your monitor until you measure it.

Gamma correction is a procedure to linearize this relation by filtering desired color values with the inverse function. This is not a minor calibration. The luminance generated by a frame buffer value [200 200 200] is not twice as high as [100 100 100]. It can be over four times! This is a MUST for quantitative psychophysicists, especially for those who use sine gratings or graded luminance levels. You are not qualified to refer to luminance in your papers unless you know the gamma of your monitor!

# Step 1

Measure luminance of the monitor at different frame buffer values, e.g., [0 0 0], [50 50 50], [100 100 100], [150 150 150], [200 200 200], [255 255 255]. Make sure that the program to show the stimulus does not involve any color/luminance calibration.

# Step 2

Fit a function to the data. You may use the following MATLAB script. This requires Psychophysics Toolbox (PsychGamma folder) and Optimization Toolbox, which we don't have for mac in Shimojo Lab. In this script, a power function is used by default, but you can select polynominal, weibull, sigmoid functions, etc.

% script to compute a gamma table
% by Yuki Kamitani   12-7-99
% ---- data,  [col1 lum1; col2 lim2;...] ------------
measTest = [ 50  6.25 ; 100  12.5; 150  18; 200  32; 250  50];
% --------------------------------------

%%%%  put your data into 'meas'
meas = meaTest;

maxIndex = 255;  %  +1 = total num of indices
indexNormal = [0:0.001:1]';
maxLum = meas(size(meas,1),2)

% You can select a fitting method with the last argument
% see help for FitGamma in Psychophysics Toolbox
[out1 params1  message1] = FitGamma(meas(:,1)/maxIndex,  meas(:,2)/maxLum, indexNormal, 1);

figure(1);
plot(maxIndex*[0:0.001:1]', maxLum*out1);
hold on;
scatter(meas(:,1), meas(:,2));

% create a gamma-corrected table
% Inverse function is calculated numerically
% independent of fitting curves
orgTable = [maxIndex*indexNormal  maxLum*out1 ];
correctedTable = [];
for i = 0: 255
eqLum = i * maxLum/maxIndex;
numTable = max(find(orgTable(:,2) <= eqLum));
correctedTable = [correctedTable ;  i round(orgTable(numTable,1))];
end

% confirm linearity
figure(2);
linearTable = [];
for i=0:255
numTable = max(find(orgTable(:,1) <= correctedTable(i+1, 2)));
linearTable = [linearTable;  i  orgTable(numTable, 2) ];
end
plot(linearTable(:,1), linearTable(:,2)');

correctedTable
gammaValue = params1(1)

# Step 3

Correct color values based on the gamma calculated above.
Desired linear color values (0-255) should be transformed by
255*(<desired color value>/255)^(1/<gamma>)
before color is assigned.

Alternatively, you can also use 'correctedTable' calculated above , which does not depend on fitting methods.

written by Yukiyasu Kamitani, kamitani@percipi.caltech.edu