sooyekim / Deep-SR-ITM

Official repository of Deep SR-ITM (oral at ICCV 2019)
101 stars 16 forks source link

Quantitative comparison problems #19

Open zhs1 opened 3 years ago

zhs1 commented 3 years ago

Hi,sooyekim: Thanks for your great works! I have a problem about HDR-VDP: How to get the linearized y channel from hdr images? I convert the hdr images from yuv format to RGB format, then use the EOTF to get linearized rgb images, and finally convert them to yuv format. Is this pipeline right?

Thanks in advance.

sooyekim commented 3 years ago

Hi @zhs1 ,

Thanks for the interest in our work! Yes, your pipeline seems right. What I did was:

  1. Convert YUV to RGB (in BT.2020 color space)
  2. Inverse PQ-OETF (EOTF) to obtain linear RGB
  3. Convert RGB to YUV (in BT.2020 color space)

One thing you should be careful about is using the conversion matrices for BT.2020 when converting YUV->RGB or RGB->YUV. You could refer to the Common Test Conditions for HDR/WCG Video Coding Experiments document officially released by MPEG.

Please refer to the below code for details of the pipeline. For steps 1-2:

function linRGB=inv_PQTF(YUV)

Bitdepth=10;

% 4:2:0 to 4:4:4
D_Y = YUV(:,:,1);
D_u = YUV(:,:,2);
D_v = YUV(:,:,3);

% Inverse quant 10b
Y=ClampImg((D_Y/bitshift(1, Bitdepth-8) - 16)/219, 0, 1);
D_Cb=ClampImg((D_u/bitshift(1, Bitdepth-8) - 128)/224, -0.5, 0.5);
D_Cr=ClampImg((D_v/bitshift(1, Bitdepth-8) - 128)/224, -0.5, 0.5);

% Y'CbCr to R'G'B'

% BT 2020
A = [1 0.00000000000000 1.47460000000000;
     1 -0.16455312684366 -0.57135312684366;
     1 1.88140000000000 0.00000000000000];

H_RGB(:,:,1) = ClampImg(Y(:,:,1) + A(1,3)*D_Cr, 0, 1);
H_RGB(:,:,2) = ClampImg(Y(:,:,1) + A(2,2)*D_Cb + A(2,3)*D_Cr, 0, 1);
H_RGB(:,:,3) = ClampImg(Y(:,:,1) + A(3,2)*D_Cb, 0, 1);

% Inverse PQ
m1=(2610/4096)*0.25;
m2=(2523/4096)*128;
c1=3424/4096;
c2=(2413/4096)*32;
c3=(2392/4096)*32;

linRGB = 10000 * ((max((H_RGB.^(1/m2))-c1,0))./(c2-c3*(H_RGB.^(1/m2)))).^(1/m1);
linRGB = ClampImg(linRGB,0,10000);

end

For step 3:

function [H_Y, H_u, H_v]=rgb2yuv_hdr(linRGB)

Bitdepth=10;

hdri=double(linRGB);
hdri = ClampImg(hdri,0,10000);
[r,c,~]=size(hdri);
if mod(r,2)==1
    hdri=hdri(1:r-1,:,:);
end
if mod(c,2)==1
    hdri=hdri(:,1:c-1,:);
end

% Coding TF
Clip_hdri=max(0,min(hdri/10000,1));
% comment to keep linear values
% m1=(2610/4096)*0.25;
% m2=(2523/4096)*128;
% c1=3424/4096;
% c2=(2413/4096)*32;
% c3=(2392/4096)*32;
% PQTF_hdri=((c1+c2*(Clip_hdri.^m1))./(1+c3*(Clip_hdri.^m1))).^m2;
PQTF_hdri=Clip_hdri;

% R'G'B to Y'CbCr
Y=0.2627*PQTF_hdri(:,:,1)+0.6780*PQTF_hdri(:,:,2)+0.0593*PQTF_hdri(:,:,3);
Cb=(PQTF_hdri(:,:,3)-Y)/1.8814;
Cr=(PQTF_hdri(:,:,1)-Y)/1.4746;

% Quant 10b
D_Y=ClampImg(round(bitshift(1, Bitdepth-8) * (219*Y + 16)), 0, bitshift(1, Bitdepth)-1);
D_Cb=ClampImg(round(bitshift(1, Bitdepth-8) * (224*Cb + 128)), 0, bitshift(1, Bitdepth)-1);
D_Cr=ClampImg(round(bitshift(1, Bitdepth-8) * (224*Cr + 128)), 0, bitshift(1, Bitdepth)-1);

% 4:4:4 to 4:2:0
D_Cb_padd=[D_Cb(:,1) D_Cb];
D_Cb_Hor=64*D_Cb_padd(:,1:2:size(D_Cb,2));
D_Cb_Hor=D_Cb_Hor + 384*D_Cb(:,1:2:size(D_Cb,2));
D_Cb_Hor=D_Cb_Hor + 64*D_Cb(:,2:2:size(D_Cb,2));

D_Cr_padd=[D_Cr(:,1) D_Cr];
D_Cr_Hor=64*D_Cr_padd(:,1:2:size(D_Cr,2));
D_Cr_Hor=D_Cr_Hor + 384*D_Cr(:,1:2:size(D_Cr,2));
D_Cr_Hor=D_Cr_Hor + 64*D_Cr(:,2:2:size(D_Cr,2));

D_Cb_Hor_padd=[D_Cb_Hor(1,:); D_Cb_Hor];
D_Cb_ver=0*D_Cb_Hor_padd(1:2:size(D_Cb_Hor,1),:);
D_Cb_ver=D_Cb_ver + 256*D_Cb_Hor(1:2:size(D_Cb_Hor,1),:);
D_Cb_ver=D_Cb_ver + 256*D_Cb_Hor(2:2:size(D_Cb_Hor,1),:);

D_Cr_Hor_padd=[D_Cr_Hor(1,:); D_Cr_Hor];
D_Cr_ver=0*D_Cr_Hor_padd(1:2:size(D_Cr_Hor,1),:);
D_Cr_ver=D_Cr_ver + 256*D_Cr_Hor(1:2:size(D_Cr_Hor,1),:);
D_Cr_ver=D_Cr_ver + 256*D_Cr_Hor(2:2:size(D_Cr_Hor,1),:);

D_Cb=bitshift(D_Cb_ver+131072, -18);
D_Cr=bitshift(D_Cr_ver+131072, -18);

H_Y=D_Y;
H_u=D_Cb;
H_v=D_Cr;

end

LMK if you have any other questions! Soo Ye