function [y,w] = idctn(y,DIM,w) %IDCTN N-D inverse discrete cosine transform. % X = IDCTN(Y) inverts the N-D DCT transform, returning the original % array if Y was obtained using Y = DCTN(X). % % IDCTN(X,DIM) applies the IDCTN operation across the dimension DIM. % % Class Support % ------------- % Input array can be numeric or logical. The returned array is of class % double. % % Reference % --------- % Narasimha M. et al, On the computation of the discrete cosine % transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. % % Example % ------- % RGB = imread('autumn.tif'); % I = rgb2gray(RGB); % J = dctn(I); % imshow(log(abs(J)),[]), colormap(jet), colorbar % % The commands below set values less than magnitude 10 in the DCT matrix % to zero, then reconstruct the image using the inverse DCT. % % J(abs(J)<10) = 0; % K = idctn(J); % figure, imshow(I) % figure, imshow(K,[0 255]) % % See also DCTN, IDSTN, IDCT, IDCT2. % % -- Damien Garcia -- 2009/04, revised 2009/11 % website: www.BiomeCardio.com % ---------- % [Y,W] = IDCTN(X,DIM,W) uses and returns the weights which are used by % the program. If IDCTN is required for several large arrays of same % size, the weights can be reused to make the algorithm faster. A typical % syntax is the following: % w = []; % for k = 1:10 % [y{k},w] = idctn(x{k},[],w); % end % The weights (w) are calculated during the first call of IDCTN then % reused in the next calls. % ---------- error(nargchk(1,3,nargin)) y = double(y); sizy = size(y); % Test DIM argument if ~exist('DIM','var'), DIM = []; end assert(~isempty(DIM) || ~isscalar(DIM),... 'DIM must be a scalar or an empty array') assert(isempty(DIM) || DIM==round(DIM) && DIM>0,... 'Dimension argument must be a positive integer scalar within indexing range.') % If DIM is empty, a DCT is performed across each dimension if isempty(DIM), y = squeeze(y); end % Working across singleton dimensions is useless dimy = ndims(y); % Some modifications are required if Y is a vector if isvector(y) dimy = 1; if size(y,1)==1 if DIM==1, w = []; return elseif DIM==2, DIM=1; end y = y.'; elseif DIM==2, w = []; return end end % Weighing vectors if ~exist('w','var') || isempty(w) w = cell(1,dimy); for dim = 1:dimy if ~isempty(DIM) && dim~=DIM, continue, end n = (dimy==1)*numel(y) + (dimy>1)*sizy(dim); w{dim} = exp(1i*(0:n-1)'*pi/2/n); end end % --- IDCT algorithm --- if ~isreal(y) y = complex(idctn(real(y),DIM,w),idctn(imag(y),DIM,w)); else for dim = 1:dimy if ~isempty(DIM) && dim~=DIM y = shiftdim(y,1); continue end siz = size(y); n = siz(1); y = reshape(y,n,[]); y = bsxfun(@times,y,w{dim}); y(1,:) = y(1,:)/sqrt(2); y = ifft(y,[],1); y = real(y*sqrt(2*n)); I = (1:n)*0.5+0.5; I(2:2:end) = n-I(1:2:end-1)+1; y = y(I,:); y = reshape(y,siz); y = shiftdim(y,1); end end y = reshape(y,sizy);