Problems implementing my own 2d DCT function. Smearing effect

조회 수: 15 (최근 30일)
speck
speck 2019년 6월 6일
편집: Matt J 2019년 6월 7일
Hi, I'm trying to implement my own Discrete Cosine transform and inverse transform functions. I have all the code written however the output images from the fuction seem to have a blurring effect.
EX:
Here is my code :
function dct = my_dct_2d(image)
%% Calculate the cosine coefficients
image = double(image);
N = length(image);
dct = zeros(N);
for u=0: N-1
for v=0: N-1
if u==0
cu = 1/sqrt(N);
else
cu = sqrt(2/N);
end
if v==0
cv = 1/sqrt(N);
else
cv = sqrt(2/N);
end
mysum = 0;
for x=0:N-1
for y=0:N-1
temp = image(x+1,y+1)*cos(pi*u*(2*x+1)/(2*N))*cos(pi*v*(2*y+1)/(2*N));
%temp = image(k,l)*cos(((2*(k-1)+1)*i*pi)/(2*n))*cos(((2*(l-1)+1)*j*pi)/(2*n));
mysum = mysum+ temp;
end
end
dct(u+1,v+1) = cu*cv*mysum;
end
end
end
function idct = my_idct_2d(image)
%% Calculate the cosine coefficients
N = length(image);
idct = zeros(N);
for u=0: N-1
for v=0: N-1
if u==0
cu = 1/sqrt(N);
else
cu = sqrt(2/N);
end
if v==0
cv = 1/sqrt(N);
else
cv = sqrt(2/N);
end
mysum = 0;
for x=0:N-1
for y=0:N-1
temp = cu*cv*image(x+1,y+1)*cos(pi*u*(2*x+1)/(2*N))*cos(pi*v*(2*y+1)/(2*N));
%temp = image(k,l)*cos(((2*(k-1)+1)*i*pi)/(2*n))*cos(((2*(l-1)+1)*j*pi)/(2*n));
mysum = mysum+ temp;
end
end
idct(u+1,v+1) = mysum;
end
end
idct = uint8(idct);
end
Please let me know if you see an error or I am implementing the functions incorectly.
Thanks
-Matt
Edit: Here is the code that generated the images posted as an example:
I = imread('cameraman.tif');
temp = my_dct_2d(I);
newImage = my_idct_2d(temp);
imshow([I newImage]);
  댓글 수: 2
Matt J
Matt J 2019년 6월 6일
You need to show the code that generated the smeared images as well
speck
speck 2019년 6월 6일
This is now included

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2019년 6월 7일
편집: Matt J 2019년 6월 7일
Your forward and inverse DCT code look identical. In other words, you appear to be performing the forward DCT where you intended to do the inverse.
  댓글 수: 2
Matt J
Matt J 2019년 6월 7일
편집: Matt J 2019년 6월 7일
Your code is also quite slow, making testing difficult. There are opportunities here to exploit vectorization and separability. Below is how I would implement it. You could probably do even better by writing it in terms of FFTs.
I = imread('cameraman.tif');
temp = my_dct_2d(I);
newImage = uint8( my_idct_2d(temp));
imshow([I newImage]);
function A=dctmatrix_1d(N)
c(1:N,1)=sqrt(2/N); c(1)=c(1)/sqrt(2);
e=(0:N-1);
A=c.*cos( e(:) * (pi*(2*e+1)/(2*N)) );
end
function dct = my_dct_2d(image)
image = double(image);
N = length(image);
A=dctmatrix_1d(N);
dct=A*image*A.';
end
function idct = my_idct_2d(image)
image = double(image);
N = length(image);
A=dctmatrix_1d(N);
idct=A\image/A.';
end
Matt J
Matt J 2019년 6월 7일
편집: Matt J 2019년 6월 7일
Another, more compact way of implementing the above is by using my KronProd class.
I = double(imread('cameraman.tif'));
K=dct_kronprod(length(I)); %This can be re-used later on images of the same size
tic
temp = K*I;
newImage = uint8( K\temp );
toc %Elapsed time is 0.005276 seconds.
imshow([I newImage]);
function K=dct_kronprod(N)
c(1:N,1)=sqrt(2/N); c(1)=c(1)/sqrt(2);
e=(0:N-1);
A=c.*cos( e(:) * (pi*(2*e+1)/(2*N)) );
K=KronProd({A},[1,1]);
end

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

Community Treasure Hunt

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

Start Hunting!

Translated by