DCT implementation for H.264



我正在为H.264实现视频DCT。我已经通读了几本书,并遵循了它们指定的系数。即便如此,当我做IDCT时,我似乎并没有得到正确的图像。请帮我提供任何信息。谢谢我的代码是:

clear all;
clc;
%% DCT, IDCT
image=imread('foreman_166.gif');
figure(1);
imshow(image);title('Original image');

%taking the luminance value of the image
image_ycbcr=rgb2ycbcr(image);
%luminance=image_ycbcr(:,:,1);
luminance=double(image_ycbcr(:,:,1));
[M N]=size(luminance);
dctmat=[1 1 1 1;2 1 -1 -2;1 -1 -1 1;1 -2 2 -1];
dct_mat=dctmat(:);    %16*1 matrix
%idctmat=inv(dctmat);
%idctmat=[1 1 1 0.5;1 0.5 -1 -1;1 -0.5 -1 1;1 -1 1 -0.5];
idctmat=[1 1 1 1;1 0.5 -0.5 -1;1 -1 -1 1;0.5 -1 1 -0.5];
%idctmat=uint8(idctmat);
idct_mat=idctmat(:);  %16*1 matrix
dctimage=zeros(M,N);  % dct of the image
idctimage=zeros(M,N);
c=ones(1,16);
transformedblock=ones(4,4);
a=1/2;b=(2/5)^0.5;d=1/2;
scaling_mat=[a^2 a*b/2 a^2 a*b/2;a*b/2 b^2/4 a*b/2 b^2/4; a^2 a*b/2 a^2 a*b/2;a*b/2 b^2/4 a*b/2 b^2/4];
inv_scalingmat=[a^2 a*b a^2 a*b; a*b b^2 a*b b^2; a^2 a*b a^2 a*b; a*b b^2 a*b b^2];

%dft for 4*4 blocks
for i=1:4:M
    for j=1:4:N
        block=luminance(i:i+3,j:j+3);
        b=block(:);  %16*1 matrix
        %b=b-mean(b);  %shifting mean to 0
%         for l=1:16
%             c(l)=dct_mat(l)*b(l); % c=1*16, X=Hx X=c
%         end
%         transformedblock(:,1)=c(1:4);
%         transformedblock(:,2)=c(5:8);
%         transformedblock(:,3)=c(9:12);
%         transformedblock(:,4)=c(13:16);
%              
       %transformedblock=dctmat*block;         %X=Hx
       transformedblock=dctmat*block*dctmat';  %tranformed block
       transformedblock=transformedblock*scaling_mat;
       %transformedblock=transformedblock*diag([1/4,1/5,1/4,1/5]);
       dctimage(i:i+3,j:j+3)=transformedblock;      
    end
end
figure(2);
imshow((abs(dctimage)));title('dct of the image');

dctimage(abs(dctimage)<10) = 0;
%inverse dct
for i=1:4:M
    for j=1:4:N
        block=dctimage(i:i+3,j:j+3);
%         b=block(:); %16*1 matrix
%         %b=b-mean(b);  %shifting mean to 0
%         for l=1:16
%             c(l)=idct_mat(l)*b(l); % c=1*16, X=Hx X=c
%         end
%         invtransformedblock(:,1)=c(1:4);
%         invtransformedblock(:,2)=c(5:8);
%         invtransformedblock(:,3)=c(9:12);
%         invtransformedblock(:,4)=c(13:16);
%         
        %invtransformedblock=idctmat*block;
        invtransformedblock=idctmat'*(block*inv_scalingmat)*idctmat;  %tranformed block
        idctimage(i:i+3,j:j+3)=invtransformedblock;      
    end
end
figure(3);
imshow(idctimage,[0 255]);title('inverse DCT image');

转换这个很简单:

transformedblock=transformedblock*scaling_mat;

invtransformedblock=idctmat'*(block*inv_scalingmat)*idctmat; 

到此:

transformedblock=transformedblock.*scaling_mat;
invtransformedblock=idctmat'*(block.*inv_scalingmat)*idctmat;

最新更新