📄 vgg_poly3d_orthorectify.m
字号:
%vgg_poly3d_orthorectify Frontoparallel rectification of image of 3D polygon.
% [H,imsize] = vgg_poly3d_orthorectify(Q,u) finds homography H that
% removes perspective distortion of image Q*hom(u) of a 3D polygon. Parameters:
% u ... double(2,N), inhomog. coordinates of polygon vertices measured in an orthonormal
% coordinate frame in the 3D polygon plane.
% Q ... double(3,3), homography that maps u to image plane.
% Image of the polygon is thus x = Q*hom(u) (homog. coords.).
% H ... double(3,3), rectifying homography
% imsize ... double(2,1), size of the target image
% The rectification is done as follows:
% Irect = vgg_warp_H(I{k},inv(H),'linear',[1 imsize(2) 1 imsize(1)]).
%
% [H,imsize] = vgg_poly3d_orthorectify(Q,u,smax) allows to specify maximum ratio of
% area element in output and input image (if omitted, smax=5). This is to prevent
% the output image from becoming huge if the perspective distortion is large.
%
% If Q is K-cell of double(3,3), rectification is done simultaneously for K images
% of the 3D polygon, so that pixels with the same coordinates correspond in the
% rectified images. Then H is K-cell of double(3,3) and imsize is double(2,K).
%
% [H,imsize] = vgg_poly3d_orthorectify(Q,u,smax,in_imsize) specifies sizes of input
% images. This is needed if some vertices project outside some input images.
function [H,imsize] = vgg_poly3d_frontorectify(H,u,smax,imsize)
if ~iscell(H)
H = {H};
end
if nargin<3
smax = 5;
end
% find scales of H in all u
for k = 1:length(H)
if nargin>3 % consider only vertices inside input image
i = boxclipu( [[1;1] imsize(:,k)], vgg_get_nonhomg(H{k}*vgg_get_homg(u)) );
else
i = logical(ones(1,size(u,2)));
end
s(k,~i) = nan;
if nnz(i)==0, continue, end
s(k,i) = sqrt(abs( dethomog(H{k},u(:,i)) ));
end
% determine the scale;
% forbid scaling polygons more than smax-times
s = s(:);
s(isnan(s)) = [];
if isempty(s) % polygon is not in the image
imsize = [0;0];
return
end
if nargin < 5
smax = inf;
end
s = min(s) * min(smax,max(s)/min(s));
% scale H and u consistently by s
u = u*s;
Hs = diag([1/s 1/s 1]);
for k = 1:length(H)
H{k} = H{k}*Hs;
end
% translate the polygon to the origin
b = bboxu(u);
imsize = ceil( b(:,2) - b(:,1) );
Ht = eye(3);
Ht(1:2,3) = b(:,1) + 1;
for k = 1:length(H)
H{k} = H{k}*Ht;
end
if length(H)==1
H = H{1};
end
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
% D = dethomog(H,q) Determinant of Jacobian of homography transformation r = nhom(H*hom(q)), D = det(dr/dq). Works vector-wise for size(q)=[2 ?].
%
function D = dethomog(H,q)
% Derivative of homography r = h(q) = nhom(H*[q;1]) is:
% dh = [eye(2) -r]/y(3)*H(:,1:2), where y = H*[q;1].
q(3,:) = 1;
r = vgg_get_nonhomg(H*q);
D = ((H(1,1)-r(1,:)*H(3,1)).*(H(2,2)-r(2,:)*H(3,2)) - (H(1,2)-r(1,:)*H(3,2)).*(H(2,1)-r(2,:)*H(3,1))) ./ (H(3,:)*q).^2;
return
function i = boxclipu(b,u)
% i = boxclipu(b,u) Returns logical indices of points inside box b.
i = all( u >= b(:,row1(u)) & u <= b(:,2*row1(u)), 1 );
return
function ub = bboxu(u)
% ub = bboxu(u) Bounding box of point cloud u.
ub = [min(u')' max(u')'];
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -