📄 vgg_signspx_from_x.m
字号:
% [P,X] = vgg_signsPX_from_x(P,X,x) Finds signs of P and X in a projective reconstruction.
%
% Given a projective reconstruction, i.e. P, X, and x such that
% s_n^k x_n^k = P^k X_n,
% where
% - P^k is k-th camera matrix
% - X_n is n-th scene point
% - x_n^k is image projection of X_n in camera P^k
% - s_n^k is scale,
% it will change signs of P^k and X_n such that all s_n^k are positive. Positivity of s_n^k
% determines the signs of P and X uniquely up to a single overall sign.
%
% Parameters:
% P ... cell(K) of 3-by-4 matrices, camera matrices.
% P also can be (3*K)-by-4 joint camera matrix.
% P also can be 3-by-4-by-K array.
% X ... double(4,N), scene points in homog. coordinates
% x ... cell(K) of double(3,N), image points in homog. coordinates.
% If an image point is missing, set x{k}(:,n) = [NaN;NaN;NaN].
% x also can be joint (3*K)-by-N joint image point matrix, again with NaNs if a point is missing.
% x also can be 3-by-N-by-K array.
%
% If it is not possible to change signs of P^k and X_n such that s_n^k are positive, it is P=X=[].
% This means that the projective reconstruction [P,X,x] does not correspond to any real scene.
%
% The function works for any dimension, ie, D-by-(D+1) camera matrices.
%
% See also vgg_selfcalib_qaffine.
function [P0,X] = vgg_signsPX_from_x(P0,X,u0)
% Re-arrange input data to joint camera matrix and joint image points.
if iscell(P0)
P = vertcat(P0{:});
u = vertcat(u0{:});
else
if ndims(P0)==2 % joint camera matrix
P = P0;
u = u0;
else % P(:,:,k) is k-th camera matrix
P = [];
u = [];
for k = 1:size(P0,3)
P = [P; P0(:,:,k)];
u = [u; u0(:,:,k)];
end
end
end
[D N] = size(X);
K = size(P,1)/(D-1);
% Do sign swapping in joint image / joint camera matrix format
if any(isnan(u(:)))
[P,X] = signsPX_from_x_occl(P,X,u); % slower code but can handle undefined points
else
[P,X] = signsPX_from_x(P,X,u); % faster code if all image points are defined
end
if isempty(P)
P0 = [];
return
end
% Re-arrange back to original format
if iscell(P0)
for k = 1:length(P0)
P0{k} = P([1:D-1]+(D-1)*(k-1),:);
end
else
if ndims(P0)==2
P0 = P;
else
for k = 1:size(P0,3)
P0(:,:,k) = P([1:D-1]+(D-1)*(k-1),:);
end
end
end
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Does the sign swapping if all image points are defined (ie, no nans are in u).
function [P,X] = signsPX_from_x(P,X,x)
[D N] = size(X);
K = size(P,1)/(D-1);
s = sign( reshape( sum(reshape(x,D-1,K*N).*reshape(P*X,D-1,K*N)), K,N) );
sP = s(:,1);
s = sP(:,ones(1,N)) .* s;
sX = s(1,:);
s = sX(ones(1,K),:) .* s;
if any(s(:)<0)
P = [];
X = [];
return
end
aux = sP(:,ones(1,D-1))'; aux = aux(:); P = P .* aux(:,ones(1,D));
X = X .* sX(ones(1,D),:);
return
% Does sign swapping if there are undefined points (nans) in x.
function [P,X] = signsPX_from_x_occl(P,X,u)
[D N] = size(X);
K = size(P,1)/(D-1);
PX = reshape( dot(reshape(u,D-1,K*N),reshape(P*X,D-1,K*N)), K,N);
for initp = 1:K
p = NaN*ones(K,1);
x = NaN*ones(1,N);
p(initp) = 1;
n = 1;
oldn = 0;
while n-oldn > 0
oldn = n;
x = updatej(p,x,PX);
p = updatej(x',p',PX')';
n = nnz(~isnan([p' x]));
end
if all(all(isnan(PX) | ~isnan((p*x).*PX)))
break
end
end
P = (reshape(ones(D-1,1)*p',(D-1)*K,1)*ones(1,D)) .* P;
X = (ones(D,1)*x) .* X;
% check if the sign changing process was succesful
uPX = reshape( dot(reshape(u,D-1,K*N),reshape(P*X,D-1,K*N)), K,N);
if ~all(all( (uPX>0) | isnan(uPX) ))
P = [];
X = [];
end
return
% Auxiliary function used for swaping the signs of P^k, X_n.
function j = updatej(i,j,IJ)
mj = any(~isnan(i*ones(1,length(j))) & isnan(ones(length(i),1)*j) & ~isnan(IJ));
nj = IJ(:,mj) .* (i*ones(1,nnz(mj)));
nj_ = nj(:); nj_(isnan(nj_)) = 0; nj(:) = nj_;
j(mj) = sign(sum(nj));
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -