简体   繁体   中英

DCT implementation for H.264

I am implementing DCT on video for H.264. I have read through a few books, and have followed the coefficients that they specify. Even with all that, i don't seem to be getting the right image when i do the IDCT. Please help me with any kind of information. Thanks: My code is:

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

It's simple just convert this:

transformedblock=transformedblock*scaling_mat;

and

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

to this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM