mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-18 00:09:10 +09:00
initial commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Unwrapping phase based on Ghiglia and Romero (1994) based on weighted and unweighted least-square method
|
||||
% URL: https://doi.org/10.1364/JOSAA.11.000107
|
||||
% Inputs:
|
||||
% * psi: wrapped phase from -pi to pi
|
||||
% * weight: weight of the phase (optional, default: all ones)
|
||||
% Output:
|
||||
% * phi: unwrapped phase from the weighted (or unweighted) least-square phase unwrapping
|
||||
% Author: Muhammad F. Kasim (University of Oxford, 2016)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
function phi = phase_unwrap(psi, weight)
|
||||
if (nargin < 2) % unweighted phase unwrap
|
||||
% get the wrapped differences of the wrapped values
|
||||
dx = [zeros([size(psi,1),1]), wrapToPi(diff(psi, 1, 2)), zeros([size(psi,1),1])];
|
||||
dy = [zeros([1,size(psi,2)]); wrapToPi(diff(psi, 1, 1)); zeros([1,size(psi,2)])];
|
||||
rho = diff(dx, 1, 2) + diff(dy, 1, 1);
|
||||
|
||||
% get the result by solving the poisson equation
|
||||
phi = solvePoisson(rho);
|
||||
|
||||
else % weighted phase unwrap
|
||||
% check if the weight has the same size as psi
|
||||
if (~all(size(weight) == size(psi)))
|
||||
error('Argument error: Size of the weight must be the same as size of the wrapped phase');
|
||||
end
|
||||
|
||||
% vector b in the paper (eq 15) is dx and dy
|
||||
dx = [wrapToPi(diff(psi, 1, 2)), zeros([size(psi,1),1])];
|
||||
dy = [wrapToPi(diff(psi, 1, 1)); zeros([1,size(psi,2)])];
|
||||
|
||||
% multiply the vector b by weight square (W^T * W)
|
||||
WW = weight .* weight;
|
||||
WWdx = WW .* dx;
|
||||
WWdy = WW .* dy;
|
||||
|
||||
% applying A^T to WWdx and WWdy is like obtaining rho in the unweighted case
|
||||
WWdx2 = [zeros([size(psi,1),1]), WWdx];
|
||||
WWdy2 = [zeros([1,size(psi,2)]); WWdy];
|
||||
rk = diff(WWdx2, 1, 2) + diff(WWdy2, 1, 1);
|
||||
normR0 = norm(rk(:));
|
||||
|
||||
% start the iteration
|
||||
eps = 1e-6;
|
||||
k = 0;
|
||||
phi = zeros(size(psi));
|
||||
while (~all(rk == 0))
|
||||
zk = solvePoisson(rk);
|
||||
k = k + 1;
|
||||
if (k == 1) pk = zk;
|
||||
else
|
||||
betak = sum(sum(rk .* zk)) / sum(sum(rkprev .* zkprev));
|
||||
pk = zk + betak * pk;
|
||||
end
|
||||
|
||||
% save the current value as the previous values
|
||||
rkprev = rk;
|
||||
zkprev = zk;
|
||||
|
||||
% perform one scalar and two vectors update
|
||||
Qpk = applyQ(pk, WW);
|
||||
alphak = sum(sum(rk .* zk)) / sum(sum(pk .* Qpk));
|
||||
phi = phi + alphak * pk;
|
||||
rk = rk - alphak * Qpk;
|
||||
|
||||
% check the stopping conditions
|
||||
if ((k >= numel(psi)) || (norm(rk(:)) < eps * normR0)) break; end;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function phi = solvePoisson(rho)
|
||||
% solve the poisson equation using dct
|
||||
dctRho = dct2(rho);
|
||||
[N, M] = size(rho);
|
||||
[I, J] = meshgrid([0:M-1], [0:N-1]);
|
||||
dctPhi = dctRho ./ 2 ./ (cos(pi*I/M) + cos(pi*J/N) - 2);
|
||||
dctPhi(1,1) = 0; % handling the inf/nan value
|
||||
|
||||
% now invert to get the result
|
||||
phi = idct2(dctPhi);
|
||||
|
||||
end
|
||||
|
||||
% apply the transformation (A^T)(W^T)(W)(A) to 2D matrix
|
||||
function Qp = applyQ(p, WW)
|
||||
% apply (A)
|
||||
dx = [diff(p, 1, 2), zeros([size(p,1),1])];
|
||||
dy = [diff(p, 1, 1); zeros([1,size(p,2)])];
|
||||
|
||||
% apply (W^T)(W)
|
||||
WWdx = WW .* dx;
|
||||
WWdy = WW .* dy;
|
||||
|
||||
% apply (A^T)
|
||||
WWdx2 = [zeros([size(p,1),1]), WWdx];
|
||||
WWdy2 = [zeros([1,size(p,2)]); WWdy];
|
||||
Qp = diff(WWdx2,1,2) + diff(WWdy2,1,1);
|
||||
end
|
||||
Reference in New Issue
Block a user