Contents
% Robust Phase Unwrapping by Convex Optimization % % This script shows the behavior of the phase unwrapping algorithm % 'cvx_unwrapping.m' described in [1]. % % The test is performed on a synthetic phase image defined in a 256x256 % pixel grid. This image is simulated by a 2-D Gaussian function of height % 0.9*rho*pi (rho is a parameter to modify the height of the Gaussian), and % standard deviations of 40 px horizontally and 25 px vertically. It then % adds normal distributed noise and compute the observations using the % wrapping function. % % The unwrapping algorithm in 'cvx_unwrapping.m' (see [1]) allows solving % the following minimization problem: % % [x*,v*] = argmin_[x,v] || Psi^T x ||_1 % s.t. || v ||_2 < epsilon1 % || q - nabla(x + v)||_1 < epsilon2 % x(1) = 0 % with y the observation (wrapped phase) and q(y) = wrap(grad(y)) % % References: % % [1] A. Gonzalez and L. Jacques. ''Robust Phase Unwrapping by Convex % Optimization,'' in IEEE International Conference on Image Processing % (ICIP14), Paris, France. October 27-30, 2014. % % [2] SPARCO Toolbox. E. v. Berg, M. P. Friedlander, G. Hennenfent, F. % Herrmann, R. Saab, and O. Yilmaz, ''Sparco: A testing framework for % sparse reconstruction,'' Dept. Computer Science, University of British % Columbia, Vancouver, Tech. Rep. TR-2007-20, October 2007. % % [3] J. Bioucas-Dias and G. Valad˜ao, ''Phase unwrapping via graph-cuts,'' % IEEE Transactions on Image Processing, vol. 16, no. 3, pp. 698–709, 2007. % % [4] Rice Wavelet Toolbox. % http://dsp.rice.edu/software/rice-wavelet-toolbox % % BibTeX Citation when using this code: % @INPROCEEDINGS{7025343, % author={Gonzalez, A. and Jacques, L.}, % booktitle={Image Processing (ICIP), 2014 IEEE International Conference on}, % title={Robust phase unwrapping by convex optimization}, % year={2014}, % pages={1713-1717}, % doi={10.1109/ICIP.2014.7025343}, % month={Oct},} % % Copyright 2015 Adriana Gonzalez % PhD Student at Universite catholique de Louvain (UCL), Belgium
REQUIREMENTS
% The Rice Wavelet Toolbox (RWT) must be installed and must be located in % the following path addpath(genpath(strcat(pwd,'\rwt'))) % The PUMA algorithm must be located in the following path addpath(genpath(strcat(pwd,'\PUMA')))
INITIALIZATION
% Intitialization of the algorithm **************************************** init = 'puma_denoised'; % 'y': initialized using the observed data % 'zeros': initialized using a vector of zeros % 'puma': initialized using the output of PUMA % 'puma_denoised': initialized using the denoised PUMA % Computation of the noise bound ****************************************** type_epsilon1 = 'Oracle'; % 'GT': computing the noise bound using the GT of the noise % variance % 'Oracle': computing the noise bound using the variance % estimated by the robust median estimator % Computation of the error bound ****************************************** type_epsilon2 = 'Oracle'; % 'GT': computing the error bound from the GT image % 'Puma': computing the error bound from the PUMA output % Parameters to adjust **************************************************** % Parameter that allows analyzing the behavior of the algorithm with % respect to the amount of ''wraps''. rho = 1 provides no ''wraps'' rho = 10; % Boolean variable to decide whether to show the images or not show_im = 1; % Standard deviation of the Gaussian noise to add to the phase std_dev = 0.35; % Data size n = 256; N = n^2; % Gradient Operator opG = opGrad_AG(n); % Wavelet Operator w.name = 'daubechies'; % Mother wavelet family: 'daubechies' or 'haar' w.filter = 14; % Number of taps of the filter w.level = 7; % Number of decomposition levels w.type = 1; % 1:DWT, 2:UDWT opW = opTranspose(opWavelet_AG(n,n,w.name,w.filter,w.level,'min',w.type));
GROUND TRUTH (GT)
[xx,yy] = meshgrid(-n/2+1:n/2,-n/2+1:n/2); sx = 40; sy = 25; im_noiseless = 0.9*pi*(exp(-xx.^2/(2*sx^2)-yy.^2/(2*sy^2))); clear xx yy sx sy top im_noiseless = reshape(im_noiseless*rho,N,1); im_noiseless_aux = im_noiseless - mean(im_noiseless); if show_im figure; colormap(pink(256)); imagesc(reshape(im_noiseless,n,n)); colorbar; axis image; title('Continuous phase image (x)') xlabel('Pixels'); ylabel('Pixels') end

ADDING GAUSSIAN NOISE
noise = std_dev*randn(N,1); im = im_noiseless + noise; im_aux = im - mean(im); MSNR = 20*log10(norm(im_noiseless)/norm(noise)); fprintf('MSNR = %3.5fdB\n', MSNR); if show_im figure; colormap(pink(256)); imagesc(reshape(im,n,n)); colorbar; axis image; title(sprintf('Noisy continuous phase image (x+n) - MSNR = %2.2fdB',MSNR)) xlabel('Pixels'); ylabel('Pixels') end
MSNR = 24.93145dB

WRAPPED DATA
% Observations y = mod(im+pi,2*pi)-pi; % Indirect observations q = mod(opG(y(:),1)+pi,2*pi) - pi; if show_im figure;colormap(pink(256));imagesc(reshape(y,n,n)); colorbar; axis image; title('Measurement - Wrapped phase - y = (x+n) mod 2\pi') xlabel('Pixels'); ylabel('Pixels') end

COMPUTING THE NOISE BOUND
switch type_epsilon1 case 'GT' gx = opG(im_noiseless,1); epsilon1 = std_dev*sqrt(N + 2*sqrt(N)); case 'Oracle' % Computation of the variance of the observation noise Wn = 0.4; % Normalized cut-off frequency to filter the noise from % the noisy signal inside the robust median estimator QX = reshape(q(1:N),n,n); QY = reshape(q(N+1:2*N),n,n); aux_X = 0; aux_Y = 0; for ii=1:n aux_X = aux_X + sqrt(median_estimator((n-1),QX(ii,:),Wn)); aux_Y = aux_Y + sqrt(median_estimator((n-1),QY(ii,:),Wn)); end sigma_X = aux_X/n; sigma_Y = aux_Y/n; epsilon1 = (sigma_X + sigma_Y)*sqrt(N + 2*sqrt(N)); end fprintf('|| n ||_2 = %e\n', epsilon1);
|| n ||_2 = 9.027190e+01
CVX UNWRAPPING
% Algorithm parameters **************************************************** param.iter = []; param.ThMode = 3; % 1 => Stability, 2 => Residuals, 3 => Both param.Th = [1.5e-4 5e-1 5e-1]; % [Stability Residuals] param.max_iter = 1e4; param.res_norm = 2; param.t = 1e3; param.print = 0; % Compute the output of PUMA if it is needed for initialization or for % computing the error bound *********************************************** if strcmp(type_epsilon2,'Oracle')&&(strcmp(init,'puma_denoised')||strcmp(init,'puma_denoised')) % PUMA output [unwph,~,~] = puma_ho(reshape(y,n,n),2,'verbose','no'); xp = unwph(:); % Denoising fun = @(lambda) abs(norm(xp-opW(SoftTh(opW(xp,1),lambda),2))-epsilon1); lambda_min = fminsearch(fun,epsilon1); xp_denoised = opW(SoftTh(opW(xp,1),lambda_min),2); end % Computing the error bound *********************************************** switch type_epsilon2 case 'GT' epsilon2 = norm(q - opG(im,1),1); case 'Oracle' epsilon2 = norm(q - opG(xp,1),1); end fprintf('|| q - nabla(x+n) ||_1 = %e\n', epsilon2); % Ground Truth ************************************************************ gt = [im_noiseless; noise]; % Initialization ********************************************************** switch init case 'zeros' x0 = zeros(2*N,1); case 'y' x0 = [y; zeros(N,1)]; case 'puma_denoised' x0 = [xp_denoised; zeros(N,1)]; case 'puma' x0 = [xp; zeros(N,1)]; end % Algorithm *************************************************************** [est,iter,T,SNR,p,d,condition,time,l1norm_x,l1norm_gt] = ... cvx_unwrapping(q,epsilon1,epsilon2,w,gt,x0,param); x = est(1:N); % Quality ***************************************************************** x_aux = x - mean(x); SNRx = 20*log10(norm(im_noiseless_aux)/norm(im_noiseless_aux - x_aux)); RMSEx = std(im_noiseless_aux-x_aux); fprintf('\ncvx unwrapping: RSNR = %2.4f dB\n',SNRx) % Results ***************************************************************** if show_im figure; colormap(pink(256)); imagesc(reshape(x,n,n)); colorbar; axis image; title('Unwrapped Phase') xlabel('Pixels'); ylabel('Pixels') end
|| q - nabla(x+n) ||_1 = 1.125100e-12 || W^T x ||_1 = 2.476665e+03 || W^T x* ||_1 = 2.837763e+03 epsilon = 9.027190e+01 || v* ||_2 = 8.814280e+01 || q - grad(x*+v*) ||_1 = 2.919999e+02 cvx unwrapping: RSNR = 40.8506 dB
