├── README.md ├── TGVdenoise.m ├── TNVdenoise.m ├── TVdenoise.m ├── deconvolution.m ├── demosaic.m └── parrotgray.png /README.md: -------------------------------------------------------------------------------- 1 | # TotalVariationAlgorithms 2 | 3 | 本仓库收集了目前所知的基于TV(total variationa)正则化的图像恢复算法,包括基于原始的TV, TNV, TGV的去噪,以及去模糊和去马赛克。其解法都是比较新颖的求解方法,值得好好琢磨。 4 | 5 | 本仓库的代码来源于: 6 | http://www.gipsa-lab.grenoble-inp.fr/~laurent.condat/software.html 7 | 8 | 其他的对TV的优化算法: 9 | TVAL3: TV minimization by Augmented Lagrangian and ALternating direction ALgorithms 10 | https://www.caam.rice.edu/~optimization/L1/TVAL3/ 11 | Paper:An Efficient Algorithm For Total Variation Regularization with Applications to the Single Pixel Camera and Compressive Sensing 12 | -------------------------------------------------------------------------------- /TGVdenoise.m: -------------------------------------------------------------------------------- 1 | % Denoising/smoothing a given image y with the second order 2 | % total generalized variation (TGV), defined in 3 | % K. Bredies, K. Kunisch, and T. Pock, "Total generalized variation," 4 | % SIAM J. Imaging Sci., 3(3), 492-526, 2010. 5 | % 6 | % The iterative algorithm converges to the unique image x 7 | % (and the auxiliary vector field r) minimizing 8 | % 9 | % ||x-y||_2^2/2 + lambda1.||r||_1,2 + lambda2.||J(Dx-r)||_1,Frobenius 10 | % 11 | % where D maps an image to its gradient field and J maps a vector 12 | % field to its Jacobian. For a large value of lambda2, the TGV 13 | % behaves like the TV. For a small value, it behaves like the 14 | % l1-Frobenius norm of the Hessian. 15 | % 16 | % The over-relaxed Chambolle-Pock algorithm is described in 17 | % L. Condat, "A primal-dual splitting method for convex optimization 18 | % involving Lipschitzian, proximable and linear composite terms", 19 | % J. Optimization Theory and Applications, vol. 158, no. 2, 20 | % pp. 460-479, 2013. 21 | % 22 | % Code written by Laurent Condat, CNRS research fellow in the 23 | % Dept. of Images and Signals of GIPSA-lab, Univ. Grenoble Alpes, 24 | % Grenoble, France. 25 | % 26 | % Version 1.0, Oct. 12, 2016 27 | 28 | 29 | function main 30 | 31 | Nbiter= 600; % number of iterations 32 | lambda1 = 0.1; % regularization parameter 33 | lambda2 = 0.15; % regularization parameter 34 | tau = 0.01; % proximal parameter >0; influences the 35 | % convergence speed 36 | 37 | y = double(imread('parrotgray.png'))/255; % Initial image 38 | figure(1); 39 | imshow(y); 40 | rng(0); 41 | y = y+randn(size(y))*0.1; % white Gaussian noise added to the image 42 | figure(2); 43 | imshow(y); 44 | x = TGVdenoising(y,lambda1,lambda2,tau,Nbiter); 45 | figure(3); 46 | imshow(x); 47 | imwrite(y,'noisy.png'); 48 | imwrite(x,'TGVdenoised.png'); 49 | end 50 | 51 | 52 | function x = TGVdenoising(y,lambda1,lambda2,tau,Nbiter) 53 | 54 | rho = 1.99; % relaxation parameter, in [1,2) 55 | sigma = 1/tau/72; % proximal parameter 56 | [H,W]=size(y); 57 | 58 | opD = @(x) cat(3,[diff(x,1,1);zeros(1,W)],[diff(x,1,2) zeros(H,1)]); 59 | opDadj = @(u) [-u(1,:,1);-diff(u(1:end-1,:,1),1,1);u(end-1,:,1)]+... 60 | [-u(:,1,2) -diff(u(:,1:end-1,2),1,2) u(:,end-1,2)]; 61 | opJ = @(r) cat(3,... 62 | [r(1,:,1);diff(r(:,:,1),1,1)],[diff(r(:,:,1),1,2) zeros(H,1)],... 63 | [r(:,1,2) diff(r(:,:,2),1,2)],[diff(r(:,:,2),1,1);zeros(1,W)]); 64 | opJadj = @(u) cat(3,... 65 | [-diff(u(:,:,1),1,1);u(end,:,1)]-[u(:,1,2) diff(u(:,:,2),1,2)],... 66 | [-diff(u(:,:,3),1,2) u(:,end,3)]-[u(1,:,4);diff(u(:,:,4),1,1)]); 67 | prox_tau_fx = @(x) (x+tau*y)/(1+tau); 68 | prox_tau_fr = @(r) r-bsxfun(@rdivide,r,max(sqrt(sum(r.^2,3))/... 69 | (tau*lambda1),1)); 70 | prox_sigma_g_conj = @(u) bsxfun(@rdivide,u,max(sqrt(sum(u.^2,3))/... 71 | lambda2,1)); 72 | 73 | x2 = y; % Initialization of the solution 74 | r2 = zeros([H,W,2]); % Initialization of the vector field r 75 | u2 = zeros([H,W,4]); % Initialization of the dual solution 76 | cy = sum(sum(y.^2))/2; 77 | primalcostlowerbound = 0; 78 | 79 | for iter = 1:Nbiter 80 | tmp = tau*opJadj(u2); 81 | x = prox_tau_fx(x2-opDadj(tmp)); 82 | r = prox_tau_fr(r2+tmp); 83 | u = prox_sigma_g_conj(u2+sigma*opJ(opD(2*x-x2)-(2*r-r2))); 84 | x2 = x2+rho*(x-x2); 85 | r2 = r2+rho*(r-r2); 86 | u2 = u2+rho*(u-u2); 87 | if mod(iter,25)==0 88 | primalcost = norm(x-y,'fro')^2/2+... 89 | lambda1*sum(sum(sqrt(sum(r.^2,3))))+... 90 | lambda2*sum(sum(sqrt(sum(opJ(opD(x)-r).^2,3)))); 91 | dualcost = cy-sum(sum((y-opDadj(opJadj(u))).^2))/2; 92 | tmp = max(max(sqrt(sum(opJadj(u).^2,3)))); 93 | % the value tmp is to check feasibility: the value will be 94 | % <= lambda1 only at convergence. Since u is not feasible, 95 | % the dual cost is not reliable: the gap=primalcost-dualcost 96 | % can be <0 and cannot be used as stopping criterion. 97 | u3=u/max(tmp/lambda1,1); 98 | % u3 is a scaled version of u, which is feasible. 99 | % so, its dual cost is a valid, but very rough lower bound 100 | % of the primal cost. 101 | dualcost2 = cy-sum(sum((y-opDadj(opJadj(u3))).^2))/2; 102 | % we display the best value of dualcost2 computed so far. 103 | primalcostlowerbound = max(primalcostlowerbound,dualcost2); 104 | % The gap between primalcost and primalcostlowerbound tends 105 | % to zero but does not tell much about convergence, since x 106 | % converges much faster than u3. 107 | fprintf('nb iter:%4d %f %f %f %f\n',iter,primalcost,... 108 | dualcost,primalcostlowerbound,tmp); 109 | figure(3); 110 | imshow(x); 111 | end 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /TNVdenoise.m: -------------------------------------------------------------------------------- 1 | % Denoising/smoothing a given color image y with the 2 | % isotropic total nuclear variation. 3 | % 4 | % The iterative algorithm converges to the unique image x minimizing 5 | % 6 | % ||x-y||_2^2/2 + lambda.TNV(x) 7 | % 8 | % TV(x)=||Dx||_1,*, where D maps a color image to its Jacobian field 9 | % and * is the nuclear norm (of the 3x2 Jacobian matrix at each pixel) 10 | % 11 | % This penaly was called the total nuclear variation in 12 | % * K.M. Holt, Total nuclear variation and Jacobian extensions 13 | % of total variation for vector fields, IEEE Trans. Image Proc., 14 | % vol. 23, pp. 3975–3989, 2014 15 | % It has also been studied with other names in 16 | % * S. Lefkimmiatis, A. Roussos, M. Unser, and P. Maragos, Convex 17 | % generalizations of total variation based on the structure tensor 18 | % with applications to inverse problems, in Scale Space and 19 | % Variational Methods in Computer Vision, Lecture Notes in Comput. 20 | % Sci. 7893, Springer, Berlin, 2013, pp. 48–60. 21 | % * G Chierchia, N Pustelnik, B Pesquet-Popescu, JC Pesquet, 22 | % "A nonlocal structure tensor-based approach for multicomponent 23 | % image recovery problems", IEEE Trans. Image Proc., 23 (12), 24 | % pp. 5531-5544, 2014. 25 | % * J. Duran, M. Moeller, C. Sbert, and D. Cremers, "Collaborative 26 | % Total Variation: A General Framework for Vectorial TV Models", 27 | % SIAM J. Imaging Sciences, Vol. 9, No. 1, pp. 116–151, 2016. % 28 | % 29 | % The over-relaxed Chambolle-Pock algorithm used here is described 30 | % in L. Condat, "A primal-dual splitting method for convex 31 | % optimization involving Lipschitzian, proximable and linear 32 | % composite terms", J. Optimization Theory and Applications, 33 | % vol. 158, no. 2, pp. 460-479, 2013. 34 | % 35 | % Code written by Laurent Condat, CNRS research fellow in the 36 | % Dept. of Images and Signals of GIPSA-lab, Univ. Grenoble Alpes, 37 | % Grenoble, France. 38 | % 39 | % Version 1.0, Jul. 12, 2018 40 | 41 | 42 | function main 43 | 44 | Nbiter= 1000; % number of iterations 45 | lambda = 0.12; % regularization parameter 46 | tau = 0.005; % proximal parameter >0; influences the 47 | % convergence speed 48 | 49 | y = double(imread('parrot2.tif'))/255; % Initial image 50 | figure(1); 51 | imshow(y); 52 | rng(0); 53 | y = y+randn(size(y))*0.1; % white Gaussian noise added to the image 54 | figure(2); 55 | imshow(y); 56 | x = TNVdenoising(y,lambda,tau,Nbiter); 57 | figure(3); 58 | imshow(x); 59 | imwrite(y,'noisy.png'); 60 | imwrite(x,'TNVdenoised.png'); 61 | end 62 | 63 | 64 | function x = TNVdenoising(y,lambda,tau,Nbiter) 65 | 66 | rho = 1.99; % relaxation parameter, in [1,2) 67 | sigma = 1/tau/8; % proximal parameter 68 | [H,W,C]=size(y); 69 | 70 | opD = @(x) cat(4,[diff(x,1,1);zeros(1,W,3)],[diff(x,1,2) zeros(H,1,3)]); 71 | opDadj = @(u) -[u(1,:,:,1);diff(u(:,:,:,1),1,1)]-[u(:,1,:,2) diff(u(:,:,:,2),1,2)]; 72 | prox_tau_f = @(x) (x+tau*y)/(1+tau); 73 | prox_sigma_g_conj = @(u) u - prox_g(u,lambda); 74 | 75 | x2 = y; % Initialization of the solution 76 | u2 = zeros([size(y) 2]); % Initialization of the dual solution 77 | cy = sum(sum(sum(y.^2)))/2; 78 | primalcostlowerbound = 0; 79 | 80 | for iter = 1:Nbiter 81 | x = prox_tau_f(x2-tau*opDadj(u2)); 82 | u = prox_sigma_g_conj(u2+sigma*opD(2*x-x2)); 83 | x2 = x2+rho*(x-x2); 84 | u2 = u2+rho*(u-u2); 85 | if mod(iter,25)==0 86 | primalcost = sum(sum(sum((x-y).^2)))/2+lambda*nucnorm(opD(x)); 87 | dualcost = cy-sum(sum(sum((y-opDadj(u)).^2)))/2; 88 | % best value of dualcost computed so far: 89 | primalcostlowerbound = max(primalcostlowerbound,dualcost); 90 | % The gap between primalcost and primalcostlowerbound is even better 91 | % than between primalcost and dualcost to monitor convergence. 92 | fprintf('nb iter:%4d %f %f %e\n',iter,primalcost,... 93 | primalcostlowerbound,primalcost-primalcostlowerbound); 94 | figure(3); 95 | imshow(x); 96 | end 97 | end 98 | end 99 | 100 | function val = nucnorm(y, lambda) 101 | s = diff(sum(y.^2,3),1,4); 102 | theta = atan2(2*dot(y(:,:,:,1),y(:,:,:,2),3),-s)/2; 103 | c = cos(theta); 104 | s = sin(theta); 105 | val = sum(sum(sqrt(sum((bsxfun(@times,y(:,:,:,1),c)+... 106 | bsxfun(@times,y(:,:,:,2),s)).^2,3)),2),1)+... 107 | sum(sum(sqrt(sum((bsxfun(@times,y(:,:,:,2),c)-... 108 | bsxfun(@times,y(:,:,:,1),s)).^2,3)),2),1); 109 | end 110 | 111 | function x = prox_g(y, lambda) 112 | s = diff(sum(y.^2,3),1,4); 113 | theta = atan2(2*dot(y(:,:,:,1),y(:,:,:,2),3),-s)/2; 114 | c = cos(theta); 115 | s = sin(theta); 116 | x = cat(4,bsxfun(@times,y(:,:,:,1),c)+bsxfun(@times,y(:,:,:,2),s),... 117 | bsxfun(@times,y(:,:,:,2),c)-bsxfun(@times,y(:,:,:,1),s)); 118 | tmp = max(sqrt(sum(x.^2,3)), lambda); 119 | tmp = bsxfun(@times, x, (tmp-lambda)./tmp); 120 | x = cat(4,bsxfun(@times,tmp(:,:,:,1),c)-bsxfun(@times,tmp(:,:,:,2),s),... 121 | bsxfun(@times,tmp(:,:,:,2),c)+bsxfun(@times,tmp(:,:,:,1),s)); 122 | end 123 | 124 | -------------------------------------------------------------------------------- /TVdenoise.m: -------------------------------------------------------------------------------- 1 | % Denoising/smoothing a given image y with the isotropic total variation. 2 | % 3 | % The iterative algorithm converges to the unique image x minimizing 4 | % 5 | % ||x-y||_2^2/2 + lambda.TV(x) 6 | % 7 | % TV(x)=||Dx||_1,2, where D maps an image to its gradient field. 8 | % 9 | % The over-relaxed Chambolle-Pock algorithm is described in 10 | % L. Condat, "A primal-dual splitting method for convex optimization 11 | % involving Lipschitzian, proximable and linear composite terms", 12 | % J. Optimization Theory and Applications, vol. 158, no. 2, 13 | % pp. 460-479, 2013. 14 | % 15 | % Code written by Laurent Condat, CNRS research fellow in the 16 | % Dept. of Images and Signals of GIPSA-lab, Univ. Grenoble Alpes, 17 | % Grenoble, France. 18 | % 19 | % Version 1.1, Oct. 12, 2016 20 | 21 | 22 | function main 23 | 24 | Nbiter= 400; % number of iterations 25 | lambda = 0.1; % regularization parameter 26 | tau = 0.01; % proximal parameter >0; influences the 27 | % convergence speed 28 | 29 | y = double(imread('parrotgray.png'))/255; % Initial image 30 | figure(1); 31 | imshow(y); 32 | rng(0); 33 | y = y+randn(size(y))*0.1; % white Gaussian noise added to the image 34 | figure(2); 35 | imshow(y); 36 | x = TVdenoising(y,lambda,tau,Nbiter); 37 | figure(3); 38 | imshow(x); 39 | imwrite(y,'noisy.png'); 40 | imwrite(x,'TVdenoised.png'); 41 | end 42 | 43 | 44 | function x = TVdenoising(y,lambda,tau,Nbiter) 45 | 46 | rho = 1.99; % relaxation parameter, in [1,2) 47 | sigma = 1/tau/8; % proximal parameter 48 | [H,W]=size(y); 49 | 50 | opD = @(x) cat(3,[diff(x,1,1);zeros(1,W)],[diff(x,1,2) zeros(H,1)]); 51 | opDadj = @(u) -[u(1,:,1);diff(u(:,:,1),1,1)]-[u(:,1,2) diff(u(:,:,2),1,2)]; 52 | prox_tau_f = @(x) (x+tau*y)/(1+tau); 53 | prox_sigma_g_conj = @(u) bsxfun(@rdivide,u,max(sqrt(sum(u.^2,3))/lambda,1)); 54 | 55 | x2 = y; % Initialization of the solution 56 | u2 = prox_sigma_g_conj(opD(x2)); % Initialization of the dual solution 57 | cy = sum(sum(y.^2))/2; 58 | primalcostlowerbound = 0; 59 | 60 | for iter = 1:Nbiter 61 | x = prox_tau_f(x2-tau*opDadj(u2)); 62 | u = prox_sigma_g_conj(u2+sigma*opD(2*x-x2)); 63 | x2 = x2+rho*(x-x2); 64 | u2 = u2+rho*(u-u2); 65 | if mod(iter,25)==0 66 | primalcost = norm(x-y,'fro')^2/2+lambda*sum(sum(sqrt(sum(opD(x).^2,3)))); 67 | dualcost = cy-sum(sum((y-opDadj(u)).^2))/2; 68 | % best value of dualcost computed so far: 69 | primalcostlowerbound = max(primalcostlowerbound,dualcost); 70 | % The gap between primalcost and primalcostlowerbound is even better 71 | % than between primalcost and dualcost to monitor convergence. 72 | fprintf('nb iter:%4d %f %f %e\n',iter,primalcost,... 73 | primalcostlowerbound,primalcost-primalcostlowerbound); 74 | figure(3); 75 | imshow(x); 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /deconvolution.m: -------------------------------------------------------------------------------- 1 | % This Matlab file implements deconvolution regularized by total 2 | % variation, as an example of application of the optimization 3 | % algorithm described in the article: 4 | % 5 | % L. Condat, "A Generic Proximal Algorithm for Convex Optimization — 6 | % Application to Total Variation Minimization", IEEE Signal Proc. 7 | % Letters, vol. 21, no. 8, pp. 1054-1057, Aug. 2014. 8 | % 9 | % This code has been written by Laurent Condat, CNRS research fellow 10 | % in the Dept. of Images and Signals of GIPSA-lab, a research center 11 | % of the University of Grenoble-Alpes. 12 | % 13 | % For any comment or question, contact me: 14 | % http://www.gipsa-lab.grenoble-inp.fr/~laurent.condat/ 15 | % 16 | % Version 1.0, Feb. 3, 2014. 17 | % 18 | % Tested on a Apple laptop with Mac OS 10.9 and Matlab R2011b. 19 | % 20 | % 21 | % Forward model: y=Ax+e where A is the blurring operator 22 | % and e is additive white Gaussian noise (e=0 is possible). 23 | % The problem solved is the following: 24 | % min ||Ax-y||^2/2 + lambda.TV(x) 25 | % where TV is the total variation. 26 | 27 | 28 | function main() 29 | blurlevel=5; 30 | noiselevel=3; 31 | nbiter=300; 32 | lambda=0.02; 33 | Iref=double(imread('monarch.tif')); 34 | if blurlevel>0 35 | Filter = fspecial('gaussian',blurlevel*6+1,blurlevel); 36 | I=imfilter(Iref,Filter,'symmetric'); 37 | else 38 | I=Iref; 39 | Filter=1; 40 | end 41 | [m,n,c]=size(I); 42 | if noiselevel>0 43 | rng(0); 44 | noi=randn(m,n); 45 | I=I+noi*(noiselevel/norm(noi,'fro')*sqrt(n*m)); 46 | end 47 | imwrite(I/255,'degraded.tif'); 48 | tic 49 | J=restore(I,Filter,lambda,nbiter); 50 | toc 51 | imwrite(J/255,'restored.tif'); 52 | end 53 | 54 | 55 | function Iout = restore(Iin,Filter,lambda,nbiter) 56 | sigma=lambda; 57 | tau=0.99/(0.5+8*sigma); 58 | [sizex,sizey]=size(Iin); 59 | Iout=Iin; %initialization with the degraded image 60 | Idual1=zeros(sizex,sizey); %initialization with zeros 61 | Idual2=Idual1; %initialization with zeros 62 | thewaitbar = waitbar(0,'Nb iterations'); 63 | figure 64 | imshow(Iout); 65 | colormap gray 66 | axis image 67 | for iter=1:nbiter 68 | Iaux=Iout; 69 | if Filter~=1 70 | Iout=Iout-tau*(imfilter((imfilter(Iout,Filter,'symmetric')-Iin),Filter,'symmetric')); 71 | else 72 | Iout=Iout-tau*(Iout-Iin); 73 | end 74 | Iout=Iout-tau*([-Idual1(:,1),Idual1(:,1:end-1)-Idual1(:,2:end)]+... 75 | [-Idual2(1,:);Idual2(1:end-1,:)-Idual2(2:end,:)]); 76 | Iout=min(255,max(Iout,0)); 77 | imshow(Iout/255); 78 | Iaux=2*Iout-Iaux; 79 | Idual1=Idual1+sigma*[Iaux(:,2:end)-Iaux(:,1:end-1), zeros(sizex,1)]; 80 | Idual2=Idual2+sigma*[Iaux(2:end,:)-Iaux(1:end-1,:); zeros(1,sizey)]; 81 | Iaux=max(1,sqrt(Idual1.^2+Idual2.^2)/lambda); 82 | Idual1=Idual1./Iaux; 83 | Idual2=Idual2./Iaux; 84 | waitbar(iter/nbiter); 85 | end 86 | close(thewaitbar) 87 | end 88 | 89 | -------------------------------------------------------------------------------- /demosaic.m: -------------------------------------------------------------------------------- 1 | % This Matlab file implements joint deblurring-demosaicing-denoising 2 | % regularized by total variation, as an example of application of 3 | % the optimization algorithm described in the article: 4 | % 5 | % L. Condat, "A Generic Proximal Algorithm for Convex Optimization — 6 | % Application to Total Variation Minimization", IEEE Signal Proc. 7 | % Letters, vol. 21, no. 8, pp. 1054-1057, Aug. 2014. 8 | % 9 | % This code has been written by Laurent Condat, CNRS research fellow 10 | % in the Dept. of Images and Signals of GIPSA-lab, a research center 11 | % of the University of Grenoble-Alpes. 12 | % 13 | % For any comment or question, contact me: 14 | % http://www.gipsa-lab.grenoble-inp.fr/~laurent.condat/ 15 | % 16 | % Version 1.0, Feb. 3, 2014. 17 | % 18 | % Tested on a Apple laptop with Mac OS 10.9 and Matlab R2011b. 19 | % 20 | % 21 | % Forward model: y=Ax+e where A is the blurring+mosaicing operator 22 | % and e is additive white Gaussian noise (e=0 is possible). 23 | % The problem solved is the following: 24 | % min ||Ax-y||^2/2 + lambda.TV(x) 25 | % The regularizer is the vectorial TV with a weight mu in front of 26 | % the finite differences in the luminance channel. 27 | 28 | 29 | function main() 30 | blurlevel=2; 31 | noiselevel=5; 32 | nbiter=300; 33 | lambda=1.5; 34 | mu=0.2; 35 | Iref=double(imread('parot.tif')); 36 | if blurlevel>0 37 | Filter = fspecial('gaussian',blurlevel*6+1,blurlevel); 38 | I=imfilter(Iref,Filter,'symmetric'); 39 | else 40 | I=Iref; 41 | Filter=1; 42 | end 43 | [m,n,c]=size(I); 44 | C=zeros(m,n,3); 45 | C(1:2:m,2:2:n,1)=1; 46 | C(2:2:m,1:2:n,3)=1; 47 | C(1:2:m,1:2:n,2)=1; 48 | C(2:2:m,2:2:n,2)=1; 49 | %imwrite(C,'cfa.tif'); 50 | I=dot(I,C,3); % mosaicing 51 | if noiselevel>0 52 | rng(0); 53 | noi=randn(m,n); 54 | I=I+noi*(noiselevel/norm(noi,'fro')*sqrt(n*m)); 55 | end 56 | imwrite(I/255,'degraded.tif'); 57 | tic 58 | J=restore(I,C,lambda,mu,Filter,nbiter); 59 | toc 60 | imwrite(J/255,'restored.tif'); 61 | end 62 | 63 | 64 | function Iout = restore(Iin,C,lambda,mu,Filter,nbiter) 65 | sigma=0.03; 66 | tau=0.99/(0.5+max(mu^2,1)*8*sigma); 67 | [sizex,sizey]=size(Iin); 68 | Iout=repmat(Iin./sum(C,3),[1 1 3]); %initialization with a gray image 69 | Idual1=zeros(sizex,sizey,3); %initialization with zeros 70 | Idual2=Idual1; %initialization with zeros 71 | 72 | thewaitbar = waitbar(0,'Nb iterations'); 73 | figure 74 | imshow(Iout); 75 | axis image 76 | Iout=RGBtoLCC(Iout); 77 | C=RGBtoLCC(C); 78 | for iter=1:nbiter 79 | Iaux=Iout; 80 | if Filter~=1 81 | Iout=Iout-tau*imfilter(C.*repmat(dot(imfilter(Iout,Filter,'symmetric'),C,3)-Iin,... 82 | [1 1 3]),Filter,'symmetric'); 83 | else, Iout=Iout-tau*C.*repmat(dot(Iout,C,3)-Iin,[1 1 3]); end 84 | Iout(:,:,1)=Iout(:,:,1)-tau*mu*(... 85 | [-Idual1(:,1,1),Idual1(:,1:end-1,1)-Idual1(:,2:end,1)]+... 86 | [-Idual2(1,:,1);Idual2(1:end-1,:,1)-Idual2(2:end,:,1)]); 87 | Iout(:,:,2:3)=Iout(:,:,2:3)-tau*(... 88 | [-Idual1(:,1,2:3),Idual1(:,1:end-1,2:3)-Idual1(:,2:end,2:3)]+... 89 | [-Idual2(1,:,2:3);Idual2(1:end-1,:,2:3)-Idual2(2:end,:,2:3)]); 90 | Iout=LCCtoRGB(Iout); 91 | Iout=min(255,max(Iout,0)); 92 | imshow(Iout/255); 93 | Iout=RGBtoLCC(Iout); 94 | Iaux=2*Iout-Iaux; 95 | Idual1(:,:,1)=Idual1(:,:,1)+sigma*mu*[Iaux(:,2:end,1)-Iaux(:,1:end-1,1), zeros(sizex,1)]; 96 | Idual1(:,:,2:3)=Idual1(:,:,2:3)+sigma*[Iaux(:,2:end,2:3)-Iaux(:,1:end-1,2:3), zeros(sizex,1,2)]; 97 | Idual2(:,:,1)=Idual2(:,:,1)+sigma*mu*[Iaux(2:end,:,1)-Iaux(1:end-1,:,1); zeros(1,sizey)]; 98 | Idual2(:,:,2:3)=Idual2(:,:,2:3)+sigma*[Iaux(2:end,:,2:3)-Iaux(1:end-1,:,2:3); zeros(1,sizey,2)]; 99 | Iaux=repmat(max(1,sqrt(sum(Idual1.^2+Idual2.^2,3))/lambda),[1 1 3]); 100 | Idual1=Idual1./Iaux; 101 | Idual2=Idual2./Iaux; 102 | waitbar(iter/nbiter); 103 | end 104 | Iout=LCCtoRGB(Iout); 105 | close(thewaitbar) 106 | end 107 | 108 | 109 | function Iout = RGBtoLCC(Iin) 110 | Iout=Iin; 111 | Iout(:,:,1)=sum(Iin,3)/sqrt(3); 112 | Iout(:,:,2)=(Iin(:,:,1)-Iin(:,:,2))/sqrt(2); 113 | Iout(:,:,3)=(Iin(:,:,1)+Iin(:,:,2)-2*Iin(:,:,3))/sqrt(6); 114 | end 115 | 116 | 117 | function Iout = LCCtoRGB(Iin) 118 | Iout=Iin; 119 | Iout(:,:,1)=Iin(:,:,1)/sqrt(3)+Iin(:,:,2)/sqrt(2)+Iin(:,:,3)/sqrt(6); 120 | Iout(:,:,2)=Iin(:,:,1)/sqrt(3)-Iin(:,:,2)/sqrt(2)+Iin(:,:,3)/sqrt(6); 121 | Iout(:,:,3)=Iin(:,:,1)/sqrt(3)-2*Iin(:,:,3)/sqrt(6); 122 | end 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /parrotgray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WanglifuCV/TotalVariationAlgorithms/8744a24b1c3b2bcac9193a7156a6351c1cdba459/parrotgray.png --------------------------------------------------------------------------------