Reputation: 133
I work on a function in Matlab that calculates the DCT (discrete cosine transform) of an image. I don't know what is not working in my code,which is used in image compression.please help me. Any ideas please.
clc;close all;clear all;
image=('cameraman.tif');
[h w] = size(image);
image = double(image) - 128;
b=8;
block = zeros(b,b);
image_t=zeros(size(image));
for k=1:b:h
for l=1:b:w
image_t(k:k+b-1,l:l+b-1)= image(k:k+b-1,l:l+b-1);
for u=1:b
for v=1:b
if u == 0
Cu = 1/sqrt(2);
else
Cu = 1;
end
if v == 0
Cv = 1/sqrt(2);
else
Cv = 1;
end
Res_sum=0;
for x=1:b;
for y=1:b
Res_sum = Res_sum + ((image_t(x,y))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
end
end
dct= (1/4)*Cu*Cv*Res_sum;
block(u,v) = dct;
end
end
image_comp(k:k+b-1,l:l+b-1)=block(u,v);
end
end
end
Upvotes: 0
Views: 1595
Reputation: 14326
I assume you implement the following formula for the DCT:
with
And I guess you need to divide the image into blocks of 8x8
and do the DCT on each of these blocks.
if u == 0
or if v == 0
, as you go through u
and v
in for loops which run through 1:b
. The underlying problem is that MATLAB starts indexing at 1, while the frequencies in the DCT start at 0. My hint: Use u
and v
as frequency as in the formula, not like index, i.e. for u=0:b-1
and use u+1
when indexing.x
and y
.image_t
should only contain the current block (i thus renamed it to current_block
) and not the whole image. That's current_block = image(k:k+b-1,l:l+b-1);
dct= (1/4)*Cu*Cv*Res_sum;
, it should not be 1/4
but rather 1/sqrt(2*N)
where N
is your block size (you call it b
), thus 1/sqrt(2*b)
. For a block size of 8
, as in your example, this is of course 1/4
.image
is the name of a MATLAB function. It is advisable not to use it as a function name. Consider changing it e.g. to input_image
.128
from the input image, please overthink why you are doing that. That leads to the code below. I don't know if that solves all your problem, but you should be much closer to that now ;-)
PS: Consider vectorization of the code for improved performance.
function image_comp = dctII(input_image, b)
[h, w] = size(input_image);
input_image = double(input_image);
block_dct = zeros(b);
% Loop through all blocks
for k=1:b:h
for l=1:b:w
% Save true image of block
current_block = input_image(k:k+b-1,l:l+b-1);
% Loop through all cos frequencies (u,v)
for u=0:b-1
for v=0:b-1
if u == 0
Cu = 1/sqrt(2);
else
Cu = 1;
end
if v == 0
Cv = 1/sqrt(2);
else
Cv = 1;
end
Res_sum = 0;
% Loop through all pixel values
for x=0:b-1
for y=0:b-1
Res_sum = Res_sum + ((current_block(x+1,y+1))*cos(((2*x)+1)*u*pi/(2*b))*cos(((2*y)+1)*v*pi/(2*b)));
end
end
% Calculate DCT value at frequency (u,v)
dct = 1/sqrt(2*b) * Cu * Cv * Res_sum;
block_dct(u+1,v+1) = dct;
end
end
image_comp(k:k+b-1,l:l+b-1) = block_dct(u+1,v+1);
end
end
end % of function
Upvotes: 1