niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 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 |
Henrik Kjellander | 0f59a88 | 2015-11-18 22:31:24 +0100 | [diff] [blame] | 34 | M=[r0^3 r0^2 r0 1; |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 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 |
Henrik Kjellander | 0f59a88 | 2015-11-18 22:31:24 +0100 | [diff] [blame] | 176 | |
niklase@google.com | 470e71d | 2011-07-07 08:21:25 +0000 | [diff] [blame] | 177 | fprintf('\nWriting modified test file...') |
| 178 | writeYUV420file('../out/Debug/foremanColorEnhanced.yuv',y,unew,vnew); |
| 179 | fprintf(' done\n'); |