blob: fe8777ee71a3d019d28cf7454a194cc5dc7366b4 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001% Create the color enhancement look-up table and write it to
2% file colorEnhancementTable.cpp. Copy contents of that file into
3% the source file for the color enhancement function.
4
5clear
6close all
7
8
9% First, define the color enhancement in a normalized domain
10
11% Compander function is defined in three radial zones.
12% 1. From 0 to radius r0, the compander function
13% is a second-order polynomial intersecting the points (0,0)
14% and (r0, r0), and with a slope B in (0,0).
15% 2. From r0 to r1, the compander is a third-order polynomial
16% intersecting the points (r0, r0) and (r1, r1), and with the
17% same slope as the first part in the point (r0, r0) and slope
18% equal to 1 in (r1, r1).
19% 3. For radii larger than r1, the compander function is the
20% unity scale function (no scaling at all).
21
22r0=0.07; % Dead zone radius (must be > 0)
23r1=0.6; % Enhancement zone radius (must be > r0 and < 1)
24B=0.2; % initial slope of compander function (between 0 and 1)
25
26x0=linspace(0,r0).'; % zone 1
27x1=linspace(r0,r1).'; % zone 2
28x2=linspace(r1,1).'; % zone 3
29
30A=(1-B)/r0;
31f0=A*x0.^2+B*x0; % compander function in zone 1
32
33% equation system for finding second zone parameters
Henrik Kjellander0f59a882015-11-18 22:31:24 +010034M=[r0^3 r0^2 r0 1;
niklase@google.com470e71d2011-07-07 08:21:25 +000035 3*r0^2 2*r0 1 0;
36 3*r1^2 2*r1 1 0;
37 r1^3 r1^2 r1 1];
38m=[A*r0^2+B*r0; 2*A*r0+B; 1; r1];
39% solve equations
40theta=M\m;
41
42% compander function in zone 1
43f1=[x1.^3 x1.^2 x1 ones(size(x1))]*theta;
44
45x=[x0; x1; x2];
46f=[f0; f1; x2];
47
48% plot it
49figure(1)
50plot(x,f,x,x,':')
51xlabel('Normalized radius')
52ylabel('Modified radius')
53
54
55% Now, create the look-up table in the integer color space
56[U,V]=meshgrid(0:255, 0:255); % U-V space
57U0=U;
58V0=V;
59
60% Conversion matrix from normalized YUV to RGB
61T=[1 0 1.13983; 1 -0.39465 -0.58060; 1 2.03211 0];
62Ylum=0.5;
63
64figure(2)
65Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3);
66Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3);
67Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3);
68Z=max(Z,0);
69Z=min(Z,1);
70subplot(121)
71image(Z);
72axis square
73axis off
74set(gcf,'color','k')
75
76R = sqrt((U-127).^2 + (V-127).^2);
77Rnorm = R/127;
78RnormMod = Rnorm;
79RnormMod(RnormMod==0)=1; % avoid division with zero
80
81% find indices to pixels in dead-zone (zone 1)
82ix=find(Rnorm<=r0);
83scaleMatrix = (A*Rnorm(ix).^2 + B*Rnorm(ix))./RnormMod(ix);
84U(ix)=(U(ix)-127).*scaleMatrix+127;
85V(ix)=(V(ix)-127).*scaleMatrix+127;
86
87% find indices to pixels in zone 2
88ix=find(Rnorm>r0 & Rnorm<=r1);
89scaleMatrix = (theta(1)*Rnorm(ix).^3 + theta(2)*Rnorm(ix).^2 + ...
90 theta(3)*Rnorm(ix) + theta(4)) ./ RnormMod(ix);
91U(ix)=(U(ix)-127).*scaleMatrix + 127;
92V(ix)=(V(ix)-127).*scaleMatrix + 127;
93
94% round to integer values and saturate
95U=round(U);
96V=round(V);
97U=max(min(U,255),0);
98V=max(min(V,255),0);
99
100Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3);
101Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3);
102Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3);
103Z=max(Z,0);
104Z=min(Z,1);
105subplot(122)
106image(Z);
107axis square
108axis off
109
110figure(3)
111subplot(121)
112mesh(U-U0)
113subplot(122)
114mesh(V-V0)
115
116
117
118% Last, write to file
119% Write only one matrix, since U=V'
120
121fid = fopen('../out/Debug/colorEnhancementTable.h','wt');
122if fid==-1
123 error('Cannot open file colorEnhancementTable.cpp');
124end
125
126fprintf(fid,'//colorEnhancementTable.h\n\n');
127fprintf(fid,'//Copy the constant table to the appropriate header file.\n\n');
128
129fprintf(fid,'//Table created with Matlab script createTable.m\n\n');
130fprintf(fid,'//Usage:\n');
131fprintf(fid,'// Umod=colorTable[U][V]\n');
132fprintf(fid,'// Vmod=colorTable[V][U]\n');
133
134fprintf(fid,'static unsigned char colorTable[%i][%i] = {\n', size(U,1), size(U,2));
135
136for u=1:size(U,2)
137 fprintf(fid,' {%i', U(1,u));
138 for v=2:size(U,1)
139 fprintf(fid,', %i', U(v,u));
140 end
141 fprintf(fid,'}');
142 if u<size(U,2)
143 fprintf(fid,',');
144 end
145 fprintf(fid,'\n');
146end
147fprintf(fid,'};\n\n');
148fclose(fid);
149fprintf('done');
150
151
152answ=input('Create test vector (takes some time...)? y/n : ','s');
153if answ ~= 'y'
154 return
155end
156
157% Also, create test vectors
158
159% Read test file foreman.yuv
160fprintf('Reading test file...')
161[y,u,v]=readYUV420file('../out/Debug/testFiles/foreman_cif.yuv',352,288);
162fprintf(' done\n');
163unew=uint8(zeros(size(u)));
164vnew=uint8(zeros(size(v)));
165
166% traverse all frames
167for k=1:size(y,3)
168 fprintf('Frame %i\n', k);
169 for r=1:size(u,1)
170 for c=1:size(u,2)
171 unew(r,c,k) = uint8(U(double(v(r,c,k))+1, double(u(r,c,k))+1));
172 vnew(r,c,k) = uint8(V(double(v(r,c,k))+1, double(u(r,c,k))+1));
173 end
174 end
175end
Henrik Kjellander0f59a882015-11-18 22:31:24 +0100176
niklase@google.com470e71d2011-07-07 08:21:25 +0000177fprintf('\nWriting modified test file...')
178writeYUV420file('../out/Debug/foremanColorEnhanced.yuv',y,unew,vnew);
179fprintf(' done\n');