function yout=CWT_upcoef(array_in,Sizes)
%
% yout=CWT_upcoef(array_in,Sizes)
%
% This function applies the inverse Complex Wavelet Transform on the
% previously transformed signal
%
% Its inputs are the outputs of the transformation CWT_downcoef and its
% output is the reconstructed signal
%
% (c) 2008 Reshad Hosseini
% Further details about the algorithm can be found in
% Hosseini : "Almost Perfect Reconstruction Filter Bank for Non-redundant
% ,Approximately Shift-Invariant, Complex Wavelet Transforms"
%
num1=['filter1x';'filter2x';'filter3x'];
num2=['filter1y';'filter2y';'filter3y'];
num3=['filter1z';'filter2z';'filter3z'];
siz=Sizes.sum_subbands;
size_array=Sizes.subbands;
siz_original=Sizes.original;
dim=Sizes.dim;
levels=Sizes.level;
for k=1:levels
if k==1
start_lev(k)=1;
else
if dim==1
start_lev(k)=start_lev(k-1)+siz(k-1)*2;
elseif dim==2
start_lev(k)=start_lev(k-1)+siz(k-1)*8;
elseif dim==3
start_lev(k)=start_lev(k-1)+siz(k-1)*26;
end
end
end
yout=0;
for k=levels:-1:1
flag=1;
if k==1
load filter2
filter1x=real(filters(:,1));
filter3x=real(filters(:,2));
filter2x=imag(filters(:,3));
if dim>1
filter1y=filter1x';
filter2y=filter2x';
filter3y=filter3x';
end
if dim>2
clear filter1z filter2z filter3z
filter1z(1,1,:)=filter1x;
filter2z(1,1,:)=filter2x;
filter3z(1,1,:)=filter3x;
end
filt_len=size(filters,1);
else
clear y filter1z filter2z filter3z
if k==levels
load filter1
end
filter1x=real(filters(:,1));
filter3x=real(filters(:,2));
filter2x=imag(filters(:,3));
filt_len=size(filters,1);
if dim>1
filter1y=filter1x';
filter2y=filter2x';
filter3y=filter3x';
end
if dim>2
filter1z(1,1,:)=filter1x;
filter2z(1,1,:)=filter2x;
filter3z(1,1,:)=filter3x;
end
end
if dim==1
end_num=3;
elseif dim==2
end_num=9;
else
end_num=27;
end
for num=1:end_num
refer=size_array(k,:);
if dim==1
refer=[1 refer];
end
if dim==3
if num==14
in=2*(reshape(array_in(get_pos(k,1,siz,start_lev))+array_in(get_pos(k,3,siz,start_lev))+...
array_in(get_pos(k,5,siz,start_lev))+array_in(get_pos(k,7,siz,start_lev)),refer));
elseif num==18
in=2*(reshape(-array_in(get_pos(k,1,siz,start_lev))+array_in(get_pos(k,3,siz,start_lev))+...
array_in(get_pos(k,5,siz,start_lev))-array_in(get_pos(k,7,siz,start_lev)),refer));
elseif num==24
in=2*(reshape(-array_in(get_pos(k,1,siz,start_lev))+array_in(get_pos(k,3,siz,start_lev))-...
array_in(get_pos(k,5,siz,start_lev))+array_in(get_pos(k,7,siz,start_lev)),refer));
elseif num==26
in=2*(reshape(-array_in(get_pos(k,1,siz,start_lev))-array_in(get_pos(k,3,siz,start_lev))+...
array_in(get_pos(k,5,siz,start_lev))+array_in(get_pos(k,7,siz,start_lev)),refer));
elseif num==23
in=2*(reshape(array_in(get_pos(k,2,siz,start_lev))+array_in(get_pos(k,4,siz,start_lev))+...
array_in(get_pos(k,6,siz,start_lev))+array_in(get_pos(k,8,siz,start_lev)),refer));
elseif num==15
in=2*(reshape(array_in(get_pos(k,2,siz,start_lev))-array_in(get_pos(k,4,siz,start_lev))+...
array_in(get_pos(k,6,siz,start_lev))-array_in(get_pos(k,8,siz,start_lev)),refer));
elseif num==17
in=2*(reshape(array_in(get_pos(k,2,siz,start_lev))+array_in(get_pos(k,4,siz,start_lev))-...
array_in(get_pos(k,6,siz,start_lev))-array_in(get_pos(k,8,siz,start_lev)),refer));
elseif num==27
in=2*(reshape(-array_in(get_pos(k,2,siz,start_lev))+array_in(get_pos(k,4,siz,start_lev))+...
array_in(get_pos(k,6,siz,start_lev))-array_in(get_pos(k,8,siz,start_lev)),refer));
elseif num==13
in=2*(reshape(array_in(get_pos(k,9,siz,start_lev))+array_in(get_pos(k,11,siz,start_lev)),refer));
elseif num==25
in=2*(reshape(-array_in(get_pos(k,9,siz,start_lev))+array_in(get_pos(k,11,siz,start_lev)),refer));
elseif num==16
in=2*(reshape(array_in(get_pos(k,10,siz,start_lev))-array_in(get_pos(k,12,siz,start_lev)),refer));
elseif num==22
in=2*(reshape(array_in(get_pos(k,10,siz,start_lev))+array_in(get_pos(k,12,siz,start_lev)),refer));
elseif num==11
in=2*(reshape(array_in(get_pos(k,13,siz,start_lev))+array_in(get_pos(k,15,siz,start_lev)),refer));
elseif num==21
in=2*(reshape(-array_in(get_pos(k,13,siz,start_lev))+array_in(get_pos(k,15,siz,start_lev)),refer));
elseif num==12
in=2*(reshape(array_in(get_pos(k,14,siz,start_lev))-array_in(get_pos(k,16,siz,start_lev)),refer));
elseif num==20
in=2*(reshape(array_in(get_pos(k,14,siz,start_lev))+array_in(get_pos(k,16,siz,start_lev)),refer));
elseif num==5
in=2*(reshape(array_in(get_pos(k,17,siz,start_lev))+array_in(get_pos(k,19,siz,start_lev)),refer));
elseif num==9
in=2*(reshape(-array_in(get_pos(k,17,siz,start_lev))+array_in(get_pos(k,19,siz,start_lev)),refer));
elseif num==6
in=2*(reshape(array_in(get_pos(k,18,siz,start_lev))-array_in(get_pos(k,20,siz,start_lev)),refer));
elseif num==8
in=2*(reshape(array_in(get_pos(k,18,siz,start_lev))+array_in(get_pos(k,20,siz,start_lev)),refer));
elseif num==10
in=2*reshape(array_in(get_pos(k,21,siz,start_lev)),refer);
elseif num==19
in=2*reshape(array_in(get_pos(k,22,siz,start_lev)),refer);
elseif num==7
in=2*reshape(array_in(get_pos(k,23,siz,start_lev)),refer);
elseif num==4
in=2*reshape(array_in(get_pos(k,24,siz,start_lev)),refer);
elseif num==3
in=2*reshape(array_in(get_pos(k,25,siz,start_lev)),refer);
elseif num==2
in=2*reshape(array_in(get_pos(k,26,siz,start_lev)),refer);
elseif num==1
if k==levels
in=reshape(array_in(get_pos(k,27,siz,start_lev)),refer);
else
in=yout;
yout=0;
end
end
elseif dim==2
if num==5
in=2*(reshape(array_in(get_pos(k,1,siz,start_lev))+array_in(get_pos(k,3,siz,start_lev)),refer));
elseif num==9
in=2*(reshape(-array_in(get_pos(k,1,siz,start_lev))+array_in(get_pos(k,3,siz,start_lev)),refer));
elseif num==6
in=2*(reshape(array_in(get_pos(k,2,siz,start_lev))-array_in(get_pos(k,4,siz,start_lev)),refer));
elseif num==8
in=2*(reshape(array_in(get_pos(k,2,siz,start_lev))+array_in(get_pos(k,4,siz,start_lev)),refer));
elseif num==7
in=2*reshape(array_in(get_pos(k,5,siz,start_lev)),refer);
elseif num==4
in=2*reshape(array_in(get_pos(k,6,siz,start_lev)),refer);
elseif num==3
in=2*reshape(array_in(get_pos(k,7,siz,start_lev)),refer);
elseif num==2
in=2*reshape(array_in(get_pos(k,8,siz,start_lev)),refer);
elseif num==1
if k==levels
in=reshape(array_in(get_pos(k,9,siz,start_lev)),refer);
else
in=yout;
yout=0;
end
end
elseif dim==1
if num==3
in=2*reshape(array_in(get_pos(k,1,siz,start_lev)),refer);
elseif num==2
in=2*reshape(array_in(get_pos(k,2,siz,start_lev)),refer);
elseif num==1
if k==levels
in=reshape(array_in(get_pos(k,3,siz,start_lev)),refer);
else
in=yout;
yout=0;
end
end
end
if k==1
refer=siz_original;
else
refer=size_array(k-1,:);
end
if dim==1
k1=mod(num-1,3);
elseif dim==2
k2=mod(num-1,3);
k1=mod(floor((num-1)/3),3);
elseif dim==3
k3=mod(num-1,3);
k2=mod(floor((num-1)/3),3);
k1=mod(floor((num-1)/9),3);
end
middle=eval(sprintf('conv3(upsample3(in,1,dim),%s)',num1(k1+1,:) ));
if dim>1
middle2=eval(sprintf('conv3( upsample3(middle,2,dim),%s)',num2(k2+1,:)));
if dim>2
middle3=eval(sprintf('conv3( upsample3(middle2,3,dim),%s)',num3(k3+1,:)));
yout=yout+pickup(middle3,filt_len,refer,dim);
else
yout=yout+pickup(middle2,filt_len,refer,dim);
end
else
yout=yout+pickup(middle,filt_len,refer,dim);
end
% if dim==1
% figure(1),plot(yout)
% pause
% elseif dim==2
% figure(1),imshow(yout/max(max(yout)))
% end
end
clear middle middle2 middle3;
end
return;
function yout=get_pos(k,subband,siz,start_lev)
subband=subband-1;
yout=[start_lev(k)+subband*siz(k):start_lev(k)+subband*siz(k)+siz(k)-1];
return; % end function
function yout=pickup(in,filter_len,size_array,dimension)
if dimension~=1
ROI(:,2)=size(in);
else
ROI(:,2)=length(in);
end
ROI(:,1)=floor((filter_len-1)/2)+1;
ROI(:,2)=ROI(:,1)+size_array'-1;
if dimension==1
yout=in(ROI(1,1):ROI(1,2));
elseif dimension==2
yout=in(ROI(1,1):ROI(1,2),ROI(2,1):ROI(2,2));
elseif dimension==3
yout=in(ROI(1,1):ROI(1,2),ROI(2,1):ROI(2,2),ROI(3,1):ROI(3,2));
end
return; % end function
function y=upsample3(x,dim,dimension)
if dimension==1 & size(x,2)~=1
x=x';
end
[m,n,p]=size(x);
if dimension==1
y=zeros(3*(m-1)+1,1)
y(1:3:3*(m-1)+1,1)=x;
else
if dim==1
y=zeros(3*(m-1)+1,n,p);
y(1:3:3*(m-1)+1,:,:)=x;
elseif dim==2
y=zeros(m,3*(n-1)+1,p);
y(:,1:3:3*(n-1)+1,:)=x;
elseif dim==3
y=zeros(m,n,3*(p-1)+1);
y(:,:,1:3:3*(p-1)+1)=x;
end
end
return;%end function