JPEG Compression with 8x8 DCT Block

Hi, i did this code to apply the jpeg compression to an image.
clc
clear all
close all
a=imread('coins.png');
figure(1)
imagesc(a)
xlabel('x')
ylabel('y')
title('a(x,y)')
colormap('gray')
colorbar
Atdc=dct2(a);
T=10;
Atdc(abs(Atdc)<T)=0;
Ac=idct2(Atdc);
figure (2)
imagesc(log10(abs(Atdc)+1))
xlabel('u')
ylabel('v')
colorbar
title('TDC')
K=rescale(Ac);
figure(3)
montage({a,K})
title('Original (left) and compressed (right')
But now I need to modify this code to apply an 8x8 DCT block, I suppose I have to change T for a matrix of ones, but I have no idea how to do this. I hope someone can help me, thanks.

 Accepted Answer

blockproc permits you to apply a function to blocks, either in a distinct block or sliding block manner. It also has options for how to handle edge cases.

5 Comments

Dang, i don't get how to use the blockproc :/
blockproc(YourImageArray, [8 8], @YourDctFunction)
where YourDctFunction is the name of your function that accepts a struct and does the dct you need on the "data" field of the struct. Watch out for the edge cases if the array is not a multiple of 8 in some direction. And be careful about whether you are working on rgb.
I see! The thing is that I'm working on this code for my university and my professor asked me to use for loops (for a rolling window of 8x8). I managed to do this, but I'm not getting the image compression...
clc
clear all
close all
a=imread('saturn.png');
I=rgb2gray(a);
e=I;
[filas, columnas]=size(I);
mask = [1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
for i=1:8:filas-7
for j=1:8:columnas-7
bloque=I(i:i+7,j:j+7);
bloque_dct=dct2(bloque);
multi=double(bloque_dct).*mask;
bloque_compress=idct2(multi);
I(i:i+7,j:j+7)=bloque_compress;
end
end
figure(1)
subplot(1,2,1)
imagesc(e)
title('original image')
subplot(1,2,2)
imagesc(I)
title('compressed image')
colormap gray
Could you help me see what the error is? u.u
Let me explain what i'm trying to do in the for section:
for i=1:8:filas-7
for j=1:8:columnas-7 %The '-7' is to avoid exceeding the limits of the image (I don't know if it's possible to express it in another way)
bloque=I(i:i+7,j:j+7); %Taking blocks of 8x8"
bloque_dct=dct2(bloque); %Applying DCT to each block
multi=double(bloque_dct).*mask; %Multiplying each DCT block with the mask
bloque_compress=idct2(multi); %Applying inverse DCT to the multiplication
I(i:i+7,j:j+7)=bloque_compress; %Substituting those blocks in the original image
end
end
Thanks.
your image is uint8 but dct2 returns data that needs double range
Thank you sir.

Sign in to comment.

More Answers (0)

Products

Release

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!