diff options
Diffstat (limited to 'webrtc/modules/video_processing/test/createTable.m')
-rw-r--r-- | webrtc/modules/video_processing/test/createTable.m | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/webrtc/modules/video_processing/test/createTable.m b/webrtc/modules/video_processing/test/createTable.m new file mode 100644 index 0000000000..fe8777ee71 --- /dev/null +++ b/webrtc/modules/video_processing/test/createTable.m @@ -0,0 +1,179 @@ +% Create the color enhancement look-up table and write it to +% file colorEnhancementTable.cpp. Copy contents of that file into +% the source file for the color enhancement function. + +clear +close all + + +% First, define the color enhancement in a normalized domain + +% Compander function is defined in three radial zones. +% 1. From 0 to radius r0, the compander function +% is a second-order polynomial intersecting the points (0,0) +% and (r0, r0), and with a slope B in (0,0). +% 2. From r0 to r1, the compander is a third-order polynomial +% intersecting the points (r0, r0) and (r1, r1), and with the +% same slope as the first part in the point (r0, r0) and slope +% equal to 1 in (r1, r1). +% 3. For radii larger than r1, the compander function is the +% unity scale function (no scaling at all). + +r0=0.07; % Dead zone radius (must be > 0) +r1=0.6; % Enhancement zone radius (must be > r0 and < 1) +B=0.2; % initial slope of compander function (between 0 and 1) + +x0=linspace(0,r0).'; % zone 1 +x1=linspace(r0,r1).'; % zone 2 +x2=linspace(r1,1).'; % zone 3 + +A=(1-B)/r0; +f0=A*x0.^2+B*x0; % compander function in zone 1 + +% equation system for finding second zone parameters +M=[r0^3 r0^2 r0 1; + 3*r0^2 2*r0 1 0; + 3*r1^2 2*r1 1 0; + r1^3 r1^2 r1 1]; +m=[A*r0^2+B*r0; 2*A*r0+B; 1; r1]; +% solve equations +theta=M\m; + +% compander function in zone 1 +f1=[x1.^3 x1.^2 x1 ones(size(x1))]*theta; + +x=[x0; x1; x2]; +f=[f0; f1; x2]; + +% plot it +figure(1) +plot(x,f,x,x,':') +xlabel('Normalized radius') +ylabel('Modified radius') + + +% Now, create the look-up table in the integer color space +[U,V]=meshgrid(0:255, 0:255); % U-V space +U0=U; +V0=V; + +% Conversion matrix from normalized YUV to RGB +T=[1 0 1.13983; 1 -0.39465 -0.58060; 1 2.03211 0]; +Ylum=0.5; + +figure(2) +Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3); +Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3); +Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3); +Z=max(Z,0); +Z=min(Z,1); +subplot(121) +image(Z); +axis square +axis off +set(gcf,'color','k') + +R = sqrt((U-127).^2 + (V-127).^2); +Rnorm = R/127; +RnormMod = Rnorm; +RnormMod(RnormMod==0)=1; % avoid division with zero + +% find indices to pixels in dead-zone (zone 1) +ix=find(Rnorm<=r0); +scaleMatrix = (A*Rnorm(ix).^2 + B*Rnorm(ix))./RnormMod(ix); +U(ix)=(U(ix)-127).*scaleMatrix+127; +V(ix)=(V(ix)-127).*scaleMatrix+127; + +% find indices to pixels in zone 2 +ix=find(Rnorm>r0 & Rnorm<=r1); +scaleMatrix = (theta(1)*Rnorm(ix).^3 + theta(2)*Rnorm(ix).^2 + ... + theta(3)*Rnorm(ix) + theta(4)) ./ RnormMod(ix); +U(ix)=(U(ix)-127).*scaleMatrix + 127; +V(ix)=(V(ix)-127).*scaleMatrix + 127; + +% round to integer values and saturate +U=round(U); +V=round(V); +U=max(min(U,255),0); +V=max(min(V,255),0); + +Z(:,:,1)=Ylum + (U-127)/256*T(1,2) + (V-127)/256*T(1,3); +Z(:,:,2)=Ylum + (U-127)/256*T(2,2) + (V-127)/256*T(2,3); +Z(:,:,3)=Ylum + (U-127)/256*T(3,2) + (V-127)/256*T(3,3); +Z=max(Z,0); +Z=min(Z,1); +subplot(122) +image(Z); +axis square +axis off + +figure(3) +subplot(121) +mesh(U-U0) +subplot(122) +mesh(V-V0) + + + +% Last, write to file +% Write only one matrix, since U=V' + +fid = fopen('../out/Debug/colorEnhancementTable.h','wt'); +if fid==-1 + error('Cannot open file colorEnhancementTable.cpp'); +end + +fprintf(fid,'//colorEnhancementTable.h\n\n'); +fprintf(fid,'//Copy the constant table to the appropriate header file.\n\n'); + +fprintf(fid,'//Table created with Matlab script createTable.m\n\n'); +fprintf(fid,'//Usage:\n'); +fprintf(fid,'// Umod=colorTable[U][V]\n'); +fprintf(fid,'// Vmod=colorTable[V][U]\n'); + +fprintf(fid,'static unsigned char colorTable[%i][%i] = {\n', size(U,1), size(U,2)); + +for u=1:size(U,2) + fprintf(fid,' {%i', U(1,u)); + for v=2:size(U,1) + fprintf(fid,', %i', U(v,u)); + end + fprintf(fid,'}'); + if u<size(U,2) + fprintf(fid,','); + end + fprintf(fid,'\n'); +end +fprintf(fid,'};\n\n'); +fclose(fid); +fprintf('done'); + + +answ=input('Create test vector (takes some time...)? y/n : ','s'); +if answ ~= 'y' + return +end + +% Also, create test vectors + +% Read test file foreman.yuv +fprintf('Reading test file...') +[y,u,v]=readYUV420file('../out/Debug/testFiles/foreman_cif.yuv',352,288); +fprintf(' done\n'); +unew=uint8(zeros(size(u))); +vnew=uint8(zeros(size(v))); + +% traverse all frames +for k=1:size(y,3) + fprintf('Frame %i\n', k); + for r=1:size(u,1) + for c=1:size(u,2) + unew(r,c,k) = uint8(U(double(v(r,c,k))+1, double(u(r,c,k))+1)); + vnew(r,c,k) = uint8(V(double(v(r,c,k))+1, double(u(r,c,k))+1)); + end + end +end + +fprintf('\nWriting modified test file...') +writeYUV420file('../out/Debug/foremanColorEnhanced.yuv',y,unew,vnew); +fprintf(' done\n'); |