├── Barbara.jpg ├── D_ADMM_C.m ├── D_ADMM_H.m ├── anisoTVDenoise.m ├── demo.m ├── isoTVDenoise.m ├── kernels.mat └── readme.txt /Barbara.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csdwren/D-ADMM-code/801465e02316e3198c16ce6fe3c91c5c51cde068/Barbara.jpg -------------------------------------------------------------------------------- /D_ADMM_C.m: -------------------------------------------------------------------------------- 1 | function [x,iter]=D_ADMM_C( y,H,miu,method, eps) 2 | %D_ADMM A Derivative-Space alternating directional method of mutipliers for TV-based image restoration 3 | % The method is designed based on the ALM framework, i.e., introducing two constraints, 4 | % then adddressing several subproblems. 5 | % The constraint d=Dx requires d lies in the irrotatioanl subspace 6 | % V. According to the definition of curl of a vector, we hereby rewrite the constraint as 7 | % a linear form, i.e., Dh{dv}=Dv{dh}, and it is totally solved by ADMM. 8 | % 9 | % Input: 10 | % y: degraded image 11 | % H: linear oprater 12 | % miu: weighting parameter, controlling a trade-off between data 13 | % fidelity and TV item. 14 | % varargin: {1} options for selecting TV operators, i.e., 1, the default 15 | % setting, for anisotropic version and others for isotropic 16 | % version. 17 | % {2} eps, stopping criterion, default is 1e-3. 18 | % {3} option for if compute objective function error. 19 | % default:0, ~0 for yes. 20 | % Output: 21 | % x: reconstructed image 22 | % iter: iteration numbers of the restoration procedure 23 | % Optional output arguments, 24 | % Ferr: objective function values of each iteration. 25 | % 26 | 27 | %% 28 | %% preprocessing 29 | [m,n]=size(y); 30 | mean_y=sum(y(:))/(m*n); 31 | % y=y-mean_y; %unnecessary processing 32 | 33 | %% 34 | J=(0:(n-1));J=repmat(J,[m,1]); 35 | I=(0:(m-1))';I=repmat(I,[1,n]); 36 | % I=zeros(m,n);J=I; 37 | % for k=1:m 38 | % J(k,:)=(0:(n-1)); 39 | % end 40 | % for k=1:n 41 | % I(:,k)=(0:(m-1)); 42 | % end 43 | Wi=1./(2*cos(2*pi*I/m)+2*cos(2*pi*J/n)-4);Wi(1,1)=0; 44 | 45 | Dh_FFT=1-exp(-1i*2*pi*J/n);% backward gradient operator, with d(0)=x(0)-x(N-1) 46 | Dv_FFT=1-exp(-1i*2*pi*I/m); 47 | 48 | Dh2=Dh_FFT.*conj(Dh_FFT); 49 | Dv2=Dv_FFT.*conj(Dv_FFT); 50 | 51 | %% initilation 52 | [dx,dy]=BackwardD(y); 53 | 54 | p=zeros(m,n); 55 | qx=p;qy=p; 56 | 57 | %% 58 | H_FFT=psf2otf(H,[m,n]); 59 | HC_FFT = conj(H_FFT); 60 | 61 | AsDhy=HC_FFT.*fft2(dx);%A^T{D_h{y}} 62 | AsDvy=HC_FFT.*fft2(dy);%A^T{D_v{y}} 63 | 64 | ATA_FFT=H_FFT.*HC_FFT; 65 | 66 | %% parameters setting 67 | delta2=1e-4; 68 | delta1=delta2; 69 | delta_max=100*delta1; 70 | maxIter=200; 71 | 72 | % psnr_t=[]; 73 | % ssim_t=[]; 74 | % 75 | % psnr_t=[psnr_t;psnr(x_true,y)]; 76 | % ssim_t=[ssim_t;ssim(x_true*255,y*255)]; 77 | 78 | %% 79 | for i=1:maxIter 80 | 81 | %% f 82 | if method==1 83 | [fx,fy] = anisoTVDenoise(miu/delta2,dx+qx,dy+qy); 84 | else 85 | [fx,fy] = isoTVDenoise(miu/delta2,dx+qx,dy+qy); 86 | end 87 | 88 | %% d 89 | dxp=dx;dyp=dy;%store the results of previous iteration 90 | 91 | tmp=BackwardDy(BackwardDxT(dy)+p); 92 | dx=real(ifft2((AsDhy+fft2(delta1*tmp+delta2*(fx-qx)))./(ATA_FFT+delta1*Dv2+delta2))); 93 | tmp=BackwardDx(BackwardDyT(dx)-p); 94 | dy=real(ifft2((AsDvy+fft2(delta1*tmp+delta2*(fy-qy)))./(ATA_FFT+delta1*Dh2+delta2))); 95 | 96 | %% 97 | % x=real(ifft2(fft2(div(dx,dy)).*Wi));% x=U{dx,dy} 98 | % psnr_t=[psnr_t;psnr(x_true,x+mean_y)]; 99 | % ssim_t=[ssim_t;ssim(x_true*255,(x+mean_y)*255)]; 100 | 101 | 102 | % x=real(ifft2(fft2(div(dx,dy)).*Wi)); 103 | % imshow(x+mean_y);pause(); 104 | 105 | %% check the stopping criterion 106 | dxd=dxp-dx; 107 | dyd=dyp-dy; 108 | 109 | normdx=norm(dxd(:)); 110 | normdy=norm(dyd(:)); 111 | if normdx/norm(dxp(:))+ normdy/norm(dyp(:))<=4*eps 112 | iter=i; 113 | break; 114 | end 115 | 116 | %% update the parameters 117 | p=p+BackwardDxT(dy)-BackwardDyT(dx); 118 | 119 | qx=qx+dx-fx; 120 | qy=qy+dy-fy; 121 | 122 | a=BackwardDxT(dyd);b=BackwardDyT(dx); 123 | if norm(a(:))*delta1/(norm(b(:)))<1e-3 124 | rao1=1.5; 125 | else 126 | rao1=1; 127 | end 128 | 129 | if (normdx+normdy)*delta2/(norm(fx(:))+norm(fy(:)))<1e-3 130 | rao2=2.9; 131 | else 132 | rao2=1; 133 | end 134 | 135 | delta1=min(rao1*delta1,delta_max); 136 | delta2=min(rao2*delta2,delta_max); 137 | 138 | end 139 | %% 140 | if i==maxIter 141 | iter=maxIter; 142 | end 143 | 144 | %% obtain recovered image according to its gradient 145 | x=real(ifft2(fft2(div(dx,dy)).*Wi));% x=U{dx,dy} 146 | x=x+mean_y; 147 | 148 | %% nested functions 149 | function [Dux,Duy] = BackwardD(U) 150 | % Backward finite difference operator 151 | Dux = [ U(:,1) - U(:,end),diff(U,1,2)]; 152 | Duy = [ U(1,:) - U(end,:);diff(U,1,1)]; 153 | end 154 | 155 | function [Dux,Duy] = BackwardDT(U) 156 | % Backward finite difference operator 157 | Dux = [ -diff(U,1,2), U(:,end)-U(:,1)]; 158 | Duy = [ -diff(U,1,1); U(end,:)-U(1,:)]; 159 | end 160 | 161 | function Dux=BackwardDx(U) 162 | Dux = [ U(:,1) - U(:,end),diff(U,1,2)]; 163 | end 164 | function Duy=BackwardDy(U) 165 | Duy = [ U(1,:) - U(end,:);diff(U,1,1)]; 166 | end 167 | 168 | function Dux = BackwardDxT(U) 169 | % Backward finite difference operator 170 | Dux = [ -diff(U,1,2), U(:,end)-U(:,1)]; 171 | end 172 | function Duy = BackwardDyT(U) 173 | % Backward finite difference operator 174 | Duy = [ -diff(U,1,1); U(end,:)-U(1,:)]; 175 | end 176 | 177 | function DtXY = div(X,Y) 178 | % divergence of the backward finite difference operator 179 | DtXY = [ diff(X,1,2),X(:, 1)-X(:,end) ]; 180 | DtXY = DtXY + [ diff(Y,1,1);Y(1, :)-Y(end,:)]; 181 | end 182 | 183 | end 184 | 185 | -------------------------------------------------------------------------------- /D_ADMM_H.m: -------------------------------------------------------------------------------- 1 | function [x,iter]=D_ADMM_H( y,H,miu,method, eps) 2 | %D_ADMM A Derivative-Space alternating directional method of mutipliers for TV-based image restoration 3 | % The method is designed based on the ALM 4 | % The constraint d=Dx requires d lies in the irrotatioanl subspace V. 5 | % According to the definition of curl of a vector, we hereby rewrite the constraint as 6 | % a linear form, i.e., Dh{dv}=Dv{dh} 7 | % 8 | % Input: 9 | % y: degraded image 10 | % H: linear oprater 11 | % miu: weighting parameter, controlling a trade-off between data 12 | % fidelity and TV item. 13 | % method: options for selecting TV operators, i.e., 1, the default 14 | % setting, for anisotropic version and others for isotropic 15 | % version. 16 | % eps: stopping criterion, default is 1e-4. 17 | % 18 | % Output: 19 | % x: reconstructed image 20 | % iter: iteration numbers of the restoration procedure 21 | % 22 | 23 | %% 24 | if nargin<5 25 | eps=1e-4; 26 | end 27 | 28 | %% preprocessing 29 | [m,n]=size(y); 30 | mean_y=sum(y(:))/(m*n); 31 | 32 | %% 33 | J=(0:(n-1));J=repmat(J,[m,1]); 34 | I=(0:(m-1))';I=repmat(I,[1,n]); 35 | % I=zeros(m,n);J=I; 36 | % for k=1:m 37 | % J(k,:)=(0:(n-1)); 38 | % end 39 | % for k=1:n 40 | % I(:,k)=(0:(m-1)); 41 | % end 42 | Wi=1./(2*cos(2*pi*I/m)+2*cos(2*pi*J/n)-4);Wi(1)=0; 43 | 44 | Dh_FFT=1-exp(-1i*2*pi*J/n);% backward gradient operator, with d(0)=x(0)-x(N-1) 45 | Dv_FFT=1-exp(-1i*2*pi*I/m); 46 | cDh_FFT=conj(Dh_FFT); 47 | cDv_FFT=conj(Dv_FFT); 48 | 49 | denominator=cDh_FFT.*Dh_FFT+cDv_FFT.*Dv_FFT; 50 | denominator(1)=1;% in case of 0/0 51 | 52 | %% initilation 53 | [dx,dy]=BackwardD(y); 54 | px=zeros(m,n);py=px; 55 | 56 | %% 57 | H_FFT=psf2otf(H,[m,n]); 58 | HC_FFT = conj(H_FFT); 59 | 60 | AsDhy=HC_FFT.*fft2(dx);%A^T{D_h{y}} 61 | AsDvy=HC_FFT.*fft2(dy);%A^T{D_v{y}} 62 | 63 | ATA_FFT=H_FFT.*HC_FFT; 64 | 65 | %% parameters setting 66 | delta=1e-1; 67 | % delta_max=100; 68 | maxIter=200; 69 | 70 | % psnr_t=[]; 71 | % ssim_t=[]; 72 | % 73 | % psnr_t=[psnr_t;psnr(x_true,y)]; 74 | % ssim_t=[ssim_t;ssim(x_true*255,y*255)]; 75 | 76 | %% 77 | for i=1:maxIter 78 | 79 | %% f subproblem 80 | if method==1 81 | [fx,fy] = anisoTVDenoise(miu/delta,dx+px,dy+py); 82 | elseif method==2 83 | [fx,fy] = isoTVDenoise(miu/delta,dx+px,dy+py); 84 | else 85 | fx=solve_Lp(dx+px,miu/delta,.8); 86 | fy=solve_Lp(dy+py,miu/delta,.8); 87 | end 88 | 89 | %% d subproblem 90 | dxp=dx;dyp=dy;%store the results of previous iteration 91 | 92 | fpx=delta*fft2(fx-px); 93 | fpy=delta*fft2(fy-py); 94 | 95 | lamb=(cDv_FFT.*(AsDhy+fpx)-cDh_FFT.*(AsDvy+fpy))./denominator;% Lagrangian multiplier 96 | dx=real(ifft2((AsDhy+fpx-Dv_FFT.*lamb)./(ATA_FFT+delta))); 97 | dy=real(ifft2((AsDvy+fpy+Dh_FFT.*lamb)./(ATA_FFT+delta))); 98 | 99 | %% 100 | % x=real(ifft2(fft2(div(dx,dy)).*Wi));% x=U{dx,dy} 101 | % psnr_t=[psnr_t;psnr(x_true,x+mean_y)]; 102 | % ssim_t=[ssim_t;ssim(x_true*255,(x+mean_y)*255)]; 103 | 104 | %% check the stopping criterion 105 | normdx=norm((dxp(:)-dx(:))); 106 | normdy=norm((dyp(:)-dy(:))); 107 | if normdx/norm(dxp(:))+ normdy/norm(dyp(:))<=eps 108 | iter=i; 109 | break; 110 | end 111 | 112 | %% update the parameters 113 | px=px+dx-fx; 114 | py=py+dy-fy; 115 | 116 | if (normdx+normdy)*delta/(norm(fx(:))+norm(fy(:))) < 1e-3 117 | rao=1.9; 118 | else 119 | rao=1; 120 | end 121 | 122 | delta=rao*delta; 123 | % delta=min(delta_max,rao*delta); 124 | 125 | end 126 | %% 127 | if i==maxIter 128 | iter=maxIter; 129 | end 130 | 131 | 132 | %% obtain recovered image according to its gradient 133 | x=real(ifft2(fft2(div(dx,dy)).*Wi));% x=U{dx,dy} 134 | x=x+mean_y; 135 | 136 | %% nested functions 137 | function [Dux,Duy] = BackwardD(U) 138 | % Backward finite difference operator 139 | Dux = [ U(:,1) - U(:,end),diff(U,1,2)]; 140 | Duy = [ U(1,:) - U(end,:);diff(U,1,1)]; 141 | end 142 | 143 | function DtXY = div(X,Y) 144 | % divergence of the backward finite difference operator 145 | DtXY = [ diff(X,1,2),X(:, 1)-X(:,end) ]; 146 | DtXY = DtXY + [ diff(Y,1,1);Y(1, :)-Y(end,:)]; 147 | end 148 | 149 | end -------------------------------------------------------------------------------- /anisoTVDenoise.m: -------------------------------------------------------------------------------- 1 | function [ u,v ] = anisoTVDenoise( lambda,wh,wv ,varargin) 2 | % this function compute ||u,v||_l+lambda||u-wh||^2+||v-wv||^2 3 | if nargin==4 4 | if size(wh)==size(wv) 5 | V=abs(wh); 6 | V(V==0)=1; 7 | V=max(V-lambda,0)./V; 8 | u=(wh/varargin{1}).*V; 9 | 10 | V=abs(wv); 11 | V(V==0)=1; 12 | V=max(V-lambda,0)./V; 13 | v=(wv/varargin{1}).*V; 14 | 15 | else 16 | u=zeros(size(wh)); 17 | v=zeros(size(wv)); 18 | end 19 | elseif nargin==3 20 | if size(wh)==size(wv) 21 | V=abs(wh); 22 | V(V==0)=1; 23 | V=max(V-lambda,0)./V; 24 | u=(wh).*V; 25 | 26 | V=abs(wv); 27 | V(V==0)=1; 28 | V=max(V-lambda,0)./V; 29 | v=(wv).*V; 30 | 31 | else 32 | u=zeros(size(wh)); 33 | v=zeros(size(wv)); 34 | end 35 | else 36 | error('Invilid Inputs!'); 37 | end 38 | end 39 | 40 | -------------------------------------------------------------------------------- /demo.m: -------------------------------------------------------------------------------- 1 | 2 | %% 3 | 4 | x = imread('Barbara.jpg'); 5 | if(length(size(x))==3) 6 | x=im2double(rgb2gray(x)); 7 | else 8 | x=im2double(x); 9 | end 10 | 11 | 12 | sigma=5e-3; 13 | miu=4e-4; 14 | 15 | 16 | [m, n] = size(x); 17 | 18 | %% 19 | %%get the oberverd image 20 | load kernels.mat 21 | H=k{7}; 22 | 23 | H_FFT=psf2otf(H,[m,n]); 24 | HC_FFT = conj(H_FFT); 25 | 26 | 27 | y=imfilter(x,H,'circular','conv')+ sigma*randn(m,n); 28 | 29 | tic; 30 | % [x_admm,iter]=D_ADMM_C(y,H,miu,2,1e-4); 31 | [x_admm,iter]=D_ADMM_H(y,H,miu,2,1e-4); 32 | t=toc; 33 | 34 | figure,imshow(x_admm); 35 | 36 | -------------------------------------------------------------------------------- /isoTVDenoise.m: -------------------------------------------------------------------------------- 1 | function [ u,v ] = isoTVDenoise( lambda,wh,wv ,varargin) 2 | % this function compute ||u,v||_l2+lambda||u-wh||^2+||v-wv||^2 3 | 4 | if nargin==4 5 | if size(wh)==size(wv) 6 | V = wh.^2 + wv.^2; 7 | 8 | V = sqrt(V); 9 | V(V==0) = 1; 10 | V = max(V - lambda, 0)./V/varargin{1}; 11 | u = wh.*V; 12 | v = wv.*V; 13 | 14 | else 15 | u=zeros(size(wh)); 16 | v=zeros(size(wv)); 17 | end 18 | elseif nargin==3 19 | if size(wh)==size(wv) 20 | V = wh.^2 + wv.^2; 21 | 22 | V = sqrt(V); 23 | V(V==0) = 1; 24 | V = max(V - lambda, 0)./V; 25 | u = wh.*V; 26 | v = wv.*V; 27 | 28 | else 29 | u=zeros(size(wh)); 30 | v=zeros(size(wv)); 31 | end 32 | else 33 | error('Invilid Inputs!'); 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /kernels.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/csdwren/D-ADMM-code/801465e02316e3198c16ce6fe3c91c5c51cde068/kernels.mat -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Source code of the paper 2 | Dongwei Ren, Hongzhi Zhang, David Zhang, Wangmeng Zuo, "Fast Total-Variation Based Image Restoration Based on Derivative Alternated Direction Optimization Methods", Neurocomputing 2015. 3 | 4 | Please follow demo.m 5 | --------------------------------------------------------------------------------