pinvUpdate.m 2.15 KiB
function [dX,dY] = pinvUpdate(Value,Mask,Value_,varargin)
%PINVUPDATE Summary of this function goes here
% Detailed explanation goes here
p = inputParser; p.KeepUnmatched = true; p.StructExpand = true;
p.addParameter('constrained', false, @islogical);
p.parse(varargin{:});
constrained = p.Results.constrained;
%% Constants
projSize = size(Value);
uref = floor(projSize(1)/2)+1;
vref = floor(projSize(2)/2)+1;
seAng = strel('arbitrary',[0,1,0]|[0,1,0]');
seSpa = strel('arbitrary',reshape([0,1,0]|[0,1,0]',1,1,3,3));
[u,v] = ndgrid(1:projSize(1),1:projSize(2));
u = u-uref;
v = v-vref;
%% Compute difference
Delta = Value_-Value;
DeltaMat = LF.LFToMat(Delta);
%% Extend signal (to avoid cropping the gradient at the boundaries)
ValDil = extend(Value,seSpa,2);
ValDil = extend(ValDil,seAng,2);
%% Compute gradient
[LFx,LFy] = LF.gradient(ValDil);
LFx(~Mask) = nan;
LFy(~Mask) = nan;
%% Compute disparity update
if constrained
%% Compute jacobian and delta
Fx = u.*LFx;
Fy = v.*LFy;
Fx = Fx(Mask);
Fy = Fy(Mask);
J = [Fx(:),Fy(:)];
Delta = Delta(Mask);
Delta = Delta(:);
%% Compute disparity update
dXdY = pinv(J)*Delta;
dX = dXdY(1);
dY = dXdY(2);
else
%% Compute jacobian
LFxMat = LF.LFToMat(LFx);
LFyMat = LF.LFToMat(LFy);
LFxMat = LF.split(LFxMat,[0,1]);
LFyMat = LF.split(LFyMat,[0,1]);
LFxMat = cellfun(@(x) x(~isnan(x)),LFxMat,'UniformOutput',false);
LFyMat = cellfun(@(x) x(~isnan(x)),LFyMat,'UniformOutput',false);
JMat = cellfun(@(x,y) [x,y],LFxMat,LFyMat,'UniformOutput',false);
DeltaMat = LF.split(DeltaMat,[0,1]);
DeltaMat = cellfun(@(x) x(~isnan(x)),DeltaMat,'UniformOutput',false);
%% Compute disparity update
dXdY = cellfun(@(j,d) pinv(j)*d,JMat,DeltaMat,'UniformOutput',false);
dXdY = reshape(dXdY,projSize(1:2));
[dX,dY] = cellfun(@(dxdy) deal(dxdy(1),dxdy(2)),dXdY);
end
end
function Value = extend(Value,se,numIter)
for i=1:numIter
Mask = ~isnan(Value);
Temp = Value;
Temp(~Mask)=-Inf;
Temp = imdilate(Temp,se);
Temp(isinf(Temp))=NaN;
Value(~Mask) = Temp(~Mask);
end
end