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
|