IDCT of an image which has been blocked into 8x8 and then DCT'd not showing

3 views (last 30 days)
I am trying to block an image into 8x8 blocks, compute the DCT of each block and then IDCT the combined image and display it, however, I am unable to do this. I have looked at this post (https://uk.mathworks.com/matlabcentral/answers/211261-why-is-my-image-not-recombining-properly-after-a-dct) on the website already and tried what they did but it still didn't work. This is my code:
I = im2double(I);
T = dctmtx(8);
dct = @(block_struct) T * block_struct.data * T';
idct = @(block_struct) T' * block_struct.data * T;
B = blockproc(I,[8 8], dct);
B_idct = uint8(blockproc(B,[8 8], idct));
figure;
imshow(B_idct);
Thanks!

Answers (1)

V Sairam Reddy
V Sairam Reddy on 6 Dec 2022
Hi,
I understand that you are trying to divide image into 8 by 8 (8x8) blocks, compute DCT and then IDCT on each block and display the resulting image.
As per my investigation of the shared code snippet, these are some following issues identified in the code:
  1. 'I' is a 3 dimensional image, so it's of size m by n by 3 (mxnx3). While using 'blockproc', the size of each block will be 8 by 8 by 3 (8x8x3) and size of T is 8 by 8 (8x8), hence leading to dimensional error when performing matrix multiplication in 'dct' function.
  2. While performing 'Idct', before converting into uint8, multiply the output with 255 as the 'Idct' output is in the range [0,1].
Please follow the below code to make it work:
% Reading Image
I = imread ('lena_std.tif');
I = im2double(I);
% Splitting image
Ired = I(:,:,1);
Igrn = I(:,:,2);
Iblu = I(:,:,3);
% DCT Matrix
T = dctmtx(8);
% DCT and IDCT Functions
my_dct = @(block_struct) T * block_struct.data * T';
my_idct = @(block_struct) T' * block_struct.data * T;
% Applying DCT on corresponding Channels
Bred = blockproc(Ired,[8 8], my_dct);
Bgrn = blockproc(Igrn,[8 8], my_dct);
Bblu = blockproc(Iblu,[8 8], my_dct);
% Applying IDCT on corresponding Channels
B_idct_red = uint8(255*(blockproc(Bred,[8 8], my_idct)));
B_idct_grn = uint8(255*(blockproc(Bgrn,[8 8], my_idct)));
B_idct_blu = uint8(255*(blockproc(Bblu,[8 8], my_idct)));
% Concatenate the channels
B_idct = cat(3,B_idct_red,B_idct_grn,B_idct_blu);
figure;
imshow(B_idct);
Please refer to 'blockproc' Documentation to know more about its working.

Community Treasure Hunt

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

Start Hunting!