OLD | NEW |
| (Empty) |
1 % 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 | |
5 clear | |
6 close 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 | |
22 r0=0.07; % Dead zone radius (must be > 0) | |
23 r1=0.6; % Enhancement zone radius (must be > r0 and < 1) | |
24 B=0.2; % initial slope of compander function (between 0 and 1) | |
25 | |
26 x0=linspace(0,r0).'; % zone 1 | |
27 x1=linspace(r0,r1).'; % zone 2 | |
28 x2=linspace(r1,1).'; % zone 3 | |
29 | |
30 A=(1-B)/r0; | |
31 f0=A*x0.^2+B*x0; % compander function in zone 1 | |
32 | |
33 % equation system for finding second zone parameters | |
34 M=[r0^3 r0^2 r0 1; | |
35 3*r0^2 2*r0 1 0; | |
36 3*r1^2 2*r1 1 0; | |
37 r1^3 r1^2 r1 1]; | |
38 m=[A*r0^2+B*r0; 2*A*r0+B; 1; r1]; | |
39 % solve equations | |
40 theta=M\m; | |
41 | |
42 % compander function in zone 1 | |
43 f1=[x1.^3 x1.^2 x1 ones(size(x1))]*theta; | |
44 | |
45 x=[x0; x1; x2]; | |
46 f=[f0; f1; x2]; | |
47 | |
48 % plot it | |
49 figure(1) | |
50 plot(x,f,x,x,':') | |
51 xlabel('Normalized radius') | |
52 ylabel('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 | |
57 U0=U; | |
58 V0=V; | |
59 | |
60 % Conversion matrix from normalized YUV to RGB | |
61 T=[1 0 1.13983; 1 -0.39465 -0.58060; 1 2.03211 0]; | |
62 Ylum=0.5; | |
63 | |
64 figure(2) | |
65 Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3); | |
66 Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3); | |
67 Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3); | |
68 Z=max(Z,0); | |
69 Z=min(Z,1); | |
70 subplot(121) | |
71 image(Z); | |
72 axis square | |
73 axis off | |
74 set(gcf,'color','k') | |
75 | |
76 R = sqrt((U-127).^2 + (V-127).^2); | |
77 Rnorm = R/127; | |
78 RnormMod = Rnorm; | |
79 RnormMod(RnormMod==0)=1; % avoid division with zero | |
80 | |
81 % find indices to pixels in dead-zone (zone 1) | |
82 ix=find(Rnorm<=r0); | |
83 scaleMatrix = (A*Rnorm(ix).^2 + B*Rnorm(ix))./RnormMod(ix); | |
84 U(ix)=(U(ix)-127).*scaleMatrix+127; | |
85 V(ix)=(V(ix)-127).*scaleMatrix+127; | |
86 | |
87 % find indices to pixels in zone 2 | |
88 ix=find(Rnorm>r0 & Rnorm<=r1); | |
89 scaleMatrix = (theta(1)*Rnorm(ix).^3 + theta(2)*Rnorm(ix).^2 + ... | |
90 theta(3)*Rnorm(ix) + theta(4)) ./ RnormMod(ix); | |
91 U(ix)=(U(ix)-127).*scaleMatrix + 127; | |
92 V(ix)=(V(ix)-127).*scaleMatrix + 127; | |
93 | |
94 % round to integer values and saturate | |
95 U=round(U); | |
96 V=round(V); | |
97 U=max(min(U,255),0); | |
98 V=max(min(V,255),0); | |
99 | |
100 Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3); | |
101 Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3); | |
102 Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3); | |
103 Z=max(Z,0); | |
104 Z=min(Z,1); | |
105 subplot(122) | |
106 image(Z); | |
107 axis square | |
108 axis off | |
109 | |
110 figure(3) | |
111 subplot(121) | |
112 mesh(U-U0) | |
113 subplot(122) | |
114 mesh(V-V0) | |
115 | |
116 | |
117 | |
118 % Last, write to file | |
119 % Write only one matrix, since U=V' | |
120 | |
121 fid = fopen('../out/Debug/colorEnhancementTable.h','wt'); | |
122 if fid==-1 | |
123 error('Cannot open file colorEnhancementTable.cpp'); | |
124 end | |
125 | |
126 fprintf(fid,'//colorEnhancementTable.h\n\n'); | |
127 fprintf(fid,'//Copy the constant table to the appropriate header file.\n\n'); | |
128 | |
129 fprintf(fid,'//Table created with Matlab script createTable.m\n\n'); | |
130 fprintf(fid,'//Usage:\n'); | |
131 fprintf(fid,'// Umod=colorTable[U][V]\n'); | |
132 fprintf(fid,'// Vmod=colorTable[V][U]\n'); | |
133 | |
134 fprintf(fid,'static unsigned char colorTable[%i][%i] = {\n', size(U,1), size(U,2
)); | |
135 | |
136 for 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'); | |
146 end | |
147 fprintf(fid,'};\n\n'); | |
148 fclose(fid); | |
149 fprintf('done'); | |
150 | |
151 | |
152 answ=input('Create test vector (takes some time...)? y/n : ','s'); | |
153 if answ ~= 'y' | |
154 return | |
155 end | |
156 | |
157 % Also, create test vectors | |
158 | |
159 % Read test file foreman.yuv | |
160 fprintf('Reading test file...') | |
161 [y,u,v]=readYUV420file('../out/Debug/testFiles/foreman_cif.yuv',352,288); | |
162 fprintf(' done\n'); | |
163 unew=uint8(zeros(size(u))); | |
164 vnew=uint8(zeros(size(v))); | |
165 | |
166 % traverse all frames | |
167 for 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 | |
175 end | |
176 | |
177 fprintf('\nWriting modified test file...') | |
178 writeYUV420file('../out/Debug/foremanColorEnhanced.yuv',y,unew,vnew); | |
179 fprintf(' done\n'); | |
OLD | NEW |