File: Color3DLUTTest.m

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (130 lines) | stat: -rw-r--r-- 4,417 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
function Color3DLUTTest
% A simple test/demo of use of 3D CLUT color correction.
%
% Shows some simple test color transformations, performs some CLUT
% conversion accuracy test at the end, measuring how smaller CLUT sizes /
% resolutions affect the precision of color conversion.
%
% Press any key to progress through different tests/demos.
%

% History:
% 21.09.2012  mk  Written.
%
global diffImage;

% Open window with 3D CLUT color correction enabled:
PsychImaging('PrepareConfiguration');
PsychImaging('AddTask', 'AllViews', 'DisplayColorCorrection', 'LookupTable3D');
w=PsychImaging('OpenWindow', 0, 0, [0 0 401 401], [], [], [], [], [], kPsychGUIWindow);

% Build initial identity 3D-CLUT with 16 slots in each color dimension:
clut = ones(3,16,16,16);

% Put red-intensity gradient along red-axis of clut cube:
for i=0:15; clut(1,i+1,:,:) = ones(16,16) * (i/15); end
% Put green-intensity gradient along gree-axis of clut cube:
for i=0:15; clut(2,:,i+1,:) = ones(16,16) * (i/15); end
% Put blue-intensity gradient along blue-axis of clut cube:
for i=0:15; clut(3,:,:,i+1) = ones(16,16) * (i/15); end

% Store original identity lut as baseline:
origclut = clut;

DrawStim(w, clut, 'Identity mapping: gray gradient, increasing left to right.');

% Reduce level of verbosity of PsychColorCorrection() to warnings:
oldverbosity = PsychColorCorrection('Verbosity', 2);

% Invert red intensity gradient:
for i=0:15; clut(1,i+1,:,:) = ones(16,16) * (1 - (i/15)); end
DrawStim(w, clut, 'Identity mapping: Red channel gradient, decreasing left to right.');

% Invert green intensity gradient:
clut = origclut;
for i=0:15; clut(2,:,i+1,:) = ones(16,16) * (1 - (i/15)); end
DrawStim(w, clut, 'Identity mapping: Green channel gradient, decreasing left to right.');

% Invert blue intensity gradient:
clut = origclut;
for i=0:15; clut(3,:,:,i+1) = ones(16,16) * (1 - (i/15)); end
DrawStim(w, clut, 'Identity mapping: Blue channel gradient, decreasing left to right.');

% Only yellow gradient: Clear blue output subvolume:
clut = origclut;
clut(3, :, :, :) = 0;
DrawStim(w, clut, 'Identity mapping: Yellow gradient, blue channel all-zeros.');

% Some basic correctness test:
Screen('FillRect', w, 0);

% Iterate over various CLUT subsampling levels from full resolution
% identity mapping to a unit value cube and measure how precision of color
% mapping degrades with decreasing resolution of the 3D CLUT:
for k = 8:-1:1
    mi = 2^k - 1;
    clut = ones(3,mi+1,mi+1,mi+1);
    
    % Put red-intensity gradient along red-axis of clut cube:
    for i=0:mi; clut(1,i+1,:,:) = ones(mi+1,mi+1) * (i/mi); end
    % Put green-intensity gradient along gree-axis of clut cube:
    for i=0:mi; clut(2,:,i+1,:) = ones(mi+1,mi+1) * (i/mi); end
    % Put blue-intensity gradient along blue-axis of clut cube:
    for i=0:mi; clut(3,:,:,i+1) = ones(mi+1,mi+1) * (i/mi); end
    
    PsychColorCorrection('SetLookupTable3D', w, clut);
    
    % Each RGB input triplet should map to identical output triplet (minus
    % interpolation errors, of course:
    refImage = uint8(rand(400, 400, 3) * 255);
    tex = Screen('MakeTexture', w, refImage);
    Screen('DrawTexture', w, tex);
    Screen('Close', tex);
    
    % Run pipeline, readback result:
    Screen('DrawingFinished', w);
    testImage = Screen('GetImage', w, [0 0 400 400], 'backBuffer');
    
    % Show it to user:
    Screen('Flip', w);
    WaitSecs(0.5);
    
    % Compute differences:
    diffImage = testImage - refImage;
    maxdiff = max(max(max(diffImage)));
    mindiff = min(min(min(diffImage)));
    meandiff = mean(mean(mean(diffImage)));

    fprintf('k=%i : CLUT Resolution %i : max = %f min = %f mean = %f error.\n', k, mi+1, maxdiff, mindiff, meandiff);
end

% We're done:
PsychColorCorrection('Verbosity', oldverbosity);
Screen('CloseAll');

return;

end

function DrawStim(w, clut, label)
    % Draw some test stim:
    Screen('FillOval', w, [255 0 0]);

    % A little intensity gradient from rgb (0,0,0) to (255,255,255):
    Screen('DrawLines', w, [[0 ; 200] , [400 ; 200]], 10, [[0 ; 0 ; 0] , [255 ; 255 ; 255]]);

    % Show label for this test:
    Screen('TextSize', w, 14);
    DrawFormattedText(w, label, 'center', 50, 255);
    
    % Upload it:
    PsychColorCorrection('SetLookupTable3D', w, clut);
    
    % And show the color corrected stim:
    Screen('Flip', w);
    
    % Wait until keypress:
    KbStrokeWait;
    
    return;
end