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'); 180