1
function Color3DLUTTest
2
% A simple test/demo of use of 3D CLUT color correction.
4
% Shows some simple test color transformations, performs some CLUT
5
% conversion accuracy test at the end, measuring how smaller CLUT sizes /
6
% resolutions affect the precision of color conversion.
8
% Press any key to progress through different tests/demos.
12
% 21.09.2012 mk Written.
16
% Open window with 3D CLUT color correction enabled:
17
PsychImaging('PrepareConfiguration');
18
PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'LookupTable3D');
19
w=PsychImaging('OpenWindow', 0, 0, [0 0 400 400], [], [], [], [], [], kPsychGUIWindow);
21
% Build initial identity 3D-CLUT with 16 slots in each color dimension:
22
clut = ones(3,16,16,16);
24
% Put red-intensity gradient along red-axis of clut cube:
25
for i=0:15; clut(1,i+1,:,:) = ones(16,16) * (i/15); end
26
% Put green-intensity gradient along gree-axis of clut cube:
27
for i=0:15; clut(2,:,i+1,:) = ones(16,16) * (i/15); end
28
% Put blue-intensity gradient along blue-axis of clut cube:
29
for i=0:15; clut(3,:,:,i+1) = ones(16,16) * (i/15); end
31
% Store original identity lut as baseline:
34
DrawStim(w, clut, 'Identity mapping: gray gradient, increasing left to right.');
36
% Reduce level of verbosity of PsychColorCorrection() to warnings:
37
oldverbosity = PsychColorCorrection('Verbosity', 2);
39
% Invert red intensity gradient:
40
for i=0:15; clut(1,i+1,:,:) = ones(16,16) * (1 - (i/15)); end
41
DrawStim(w, clut, 'Identity mapping: Red channel gradient, decreasing left to right.');
43
% Invert green intensity gradient:
45
for i=0:15; clut(2,:,i+1,:) = ones(16,16) * (1 - (i/15)); end
46
DrawStim(w, clut, 'Identity mapping: Green channel gradient, decreasing left to right.');
48
% Invert blue intensity gradient:
50
for i=0:15; clut(3,:,:,i+1) = ones(16,16) * (1 - (i/15)); end
51
DrawStim(w, clut, 'Identity mapping: Blue channel gradient, decreasing left to right.');
53
% Only yellow gradient: Clear blue output subvolume:
56
DrawStim(w, clut, 'Identity mapping: Yellow gradient, blue channel all-zeros.');
58
% Some basic correctness test:
59
Screen('FillRect', w, 0);
61
% Iterate over various CLUT subsampling levels from full resolution
62
% identity mapping to a unit value cube and measure how precision of color
63
% mapping degrades with decreasing resolution of the 3D CLUT:
66
clut = ones(3,mi+1,mi+1,mi+1);
68
% Put red-intensity gradient along red-axis of clut cube:
69
for i=0:mi; clut(1,i+1,:,:) = ones(mi+1,mi+1) * (i/mi); end
70
% Put green-intensity gradient along gree-axis of clut cube:
71
for i=0:mi; clut(2,:,i+1,:) = ones(mi+1,mi+1) * (i/mi); end
72
% Put blue-intensity gradient along blue-axis of clut cube:
73
for i=0:mi; clut(3,:,:,i+1) = ones(mi+1,mi+1) * (i/mi); end
75
PsychColorCorrection('SetLookupTable3D', w, clut);
77
% Each RGB input triplet should map to identical output triplet (minus
78
% interpolation errors, of course:
79
refImage = uint8(rand(400, 400, 3) * 255);
80
tex = Screen('MakeTexture', w, refImage);
81
Screen('DrawTexture', w, tex);
84
% Run pipeline, readback result:
85
Screen('DrawingFinished', w);
86
testImage = Screen('GetImage', w, [], 'backBuffer');
92
% Compute differences:
93
diffImage = testImage - refImage;
94
maxdiff = max(max(max(diffImage)));
95
mindiff = min(min(min(diffImage)));
96
meandiff = mean(mean(mean(diffImage)));
98
fprintf('k=%i : CLUT Resolution %i : max = %f min = %f mean = %f error.\n', k, mi+1, maxdiff, mindiff, meandiff);
102
PsychColorCorrection('Verbosity', oldverbosity);
109
function DrawStim(w, clut, label)
110
% Draw some test stim:
111
Screen('FillOval', w, [255 0 0]);
113
% A little intensity gradient from rgb (0,0,0) to (255,255,255):
114
Screen('DrawLines', w, [[0 ; 200] , [400 ; 200]], 10, [[0 ; 0 ; 0] , [255 ; 255 ; 255]]);
116
% Show label for this test:
117
Screen('TextSize', w, 14);
118
DrawFormattedText(w, label, 'center', 50, 255);
121
PsychColorCorrection('SetLookupTable3D', w, clut);
123
% And show the color corrected stim:
126
% Wait until keypress: