viewmtx example
Explore code from
Define vector that draws a cube
close all clear % 1 2 3 4 5 6 7 8 vcube = [ 0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1]'; idx = [1 2 3 4 1 5 6 7 8 5 6 2 3 7 8 4]; vert(1,:) = vcube(1,:); vert(2,:) = vcube(2,:); vert(3,:) = vcube(3,:); % These vectors trace the edges of a unit cube: x = vert(1,idx); y = vert(2,idx); z = vert(3,idx);
Transform the cube vectors to the screen and plot the object:
A = viewmtx(-37.5,30,25); [m,n] = size(x); x4d = [x(:),y(:),z(:),ones(m*n,1)]'; x2d = A*x4d; x2 = zeros(m,n); y2 = zeros(m,n); x2(:) = x2d(1,:)./x2d(4,:); y2(:) = x2d(2,:)./x2d(4,:); plot(x2,y2)
Use plot3 to display cube (same nominal parameters as above) save the plot as cube.eps
plot3(x,y,z); view(-37.5,30); camproj('perspective'); camva(25); set(gcf,'Position',[300 200 800 600]); set(gca,'Position',[0 0 1 1]); v1 = get(gca,'CameraPosition'); fprintf('camera position: %g %g %g\n',v1); v2 = get(gca,'CameraTarget'); fprintf('camera target: %g %g %g\n',v2);
camera position: -4.06571 -5.45015 4.83013 camera target: 0.5 0.5 0.5
view vs. viewmtx
T = viewmtx(-37.5,30) view(-37.5,30); M = view % look at rotation matrices R1 = T(1:3,1:3) R2 = M(1:3,1:3) fprintf('det(R1) %g det(R2) %g\n',det(R1),det(R2)); t1 = R1'*T(1:3,4) t2 = R2'*M(1:3,4) fprintf('camera position: %g %g %g\n',v1);
T =
0.7934 -0.6088 0 0
0.3044 0.3967 0.8660 0
-0.5272 -0.6871 0.5000 0
0 0 0 1.0000
M =
0.7934 -0.6088 0 -0.0923
0.3044 0.3967 0.8660 -0.7835
0.5272 0.6871 -0.5000 8.3031
0 0 0 1.0000
R1 =
0.7934 -0.6088 0
0.3044 0.3967 0.8660
-0.5272 -0.6871 0.5000
R2 =
0.7934 -0.6088 0
0.3044 0.3967 0.8660
0.5272 0.6871 -0.5000
det(R1) 1 det(R2) -1
t1 =
0
0
0
t2 =
4.0657
5.4502
-4.8301
camera position: -4.06571 -5.45015 4.83013
now perspective
az = -37.5; el = 30; phi = 25; T = viewmtx(-37.5,30,25) f = sqrt(2)/2/+tan(phi*pi/360); P = [ 1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 -1/f 1]; test = inv(P)*T
T =
0.7934 -0.6088 0 -0.0923
0.3044 0.3967 0.8660 -0.7835
-0.5272 -0.6871 0.5000 -0.5089
0.1653 0.2154 -0.1568 1.1595
test =
0.7934 -0.6088 0 -0.0923
0.3044 0.3967 0.8660 -0.7835
-0.5272 -0.6871 0.5000 -0.5089
0 0 0 1.0000
work through matrix
R = T(1:3,1:3); % Transformation to move origin of object coordinate system to TARGET pos = campos O1 = [eye(4,3),[-pos';1]]; R = [R [0 0 0]'; [0 0 0 1]] T = P*R*O1 el = el*pi/180; az = az*pi/180; % default target calculation (in viewmtx) default_target = 0.5 + sqrt(3)/2*[cos(el)*sin(az);-cos(el)*cos(az);sin(el)]
pos =
-4.0657 -5.4502 4.8301
R =
0.7934 -0.6088 0 0
0.3044 0.3967 0.8660 0
-0.5272 -0.6871 0.5000 0
0 0 0 1.0000
T =
0.7934 -0.6088 0 -0.0923
0.3044 0.3967 0.8660 -0.7835
-0.5272 -0.6871 0.5000 -8.3031
0.1653 0.2154 -0.1568 3.6032
default_target =
0.0434
-0.0950
0.9330
pts = [v2 1]; pt = T*pts' x0 = pt(1)/pt(4); y0 = pt(2)/pt(4); z0 = pt(3)/pt(4); fprintf('transformed target %f %f %f\n',x0,y0,z0); fprintf('focal length %g\n',f);
pt =
-0.0000
0.0000
-8.6603
3.7152
transformed target -0.000000 0.000000 -2.331037
focal length 3.18955
A = [x' y' z' ones(length(x),1)]; htpts = T*A'; x3 = htpts(1,:)./htpts(4,:); y3 = htpts(2,:)./htpts(4,:); z3 = htpts(3,:)./htpts(4,:); close all plot(x3,y3,'k'); axis equal % get points on edge of cube verts = unique(A,'rows'); %verts = [verts ones(length(verts),1)]; [B ix] = sort(verts(:,3)); B = verts(ix,:); htpts = T*B'; xpts = htpts(1,:)./htpts(4,:); ypts = htpts(2,:)./htpts(4,:); zpts = htpts(3,:)./htpts(4,:); disp([xpts' ypts' zpts']) hold on plot(xpts,ypts,'ko'); axis equal xo = 0.005; yo = 0.005; for n=1:8 str = sprintf('%d',n); text(xpts(n)+xo,ypts(n)+yo,str); end hold off
-0.0256 -0.2175 -2.3044
-0.1836 -0.1013 -2.3543
0.1860 -0.1271 -2.3432
0.0232 -0.0207 -2.3889
-0.0268 0.0239 -2.2641
-0.1914 0.1309 -2.3185
0.1941 0.1071 -2.3064
0.0241 0.2047 -2.3562
rgb = imread('cube.jpg'); [ny nx nz] = size(rgb); fprintf('image size %g %g\n',nx,ny); imshow(rgb)
image size 800 600
cube data obtained from *.eps file
% there are only 12 unique rows load cube plot([data(1,1) data(1,3)],[data(1,2) data(1,4)],'r') hold on for n=2:15 plot([data(n,1) data(n,3)],[data(n,2) data(n,4)]) end hold off axis ij % get unique points of cube pt = [data(:,1) data(:,2)]; pts = flipud(unique(pt,'rows')); % arrange in same order as starting points (xpts, ypts) ix = [5 7 2 4 6 8 1 3]; spts = pts(ix,:) for n=1:length(spts) str = sprintf('%d',n); text(spts(n,1),spts(n,2),str); end
spts =
3464 3849
2649 3224
4566 3360
3717 2805
3455 2571
2593 2012
4624 2134
3724 1641
look at pixel scale between plot3 pixel values and our calculated values
scl = 1000; cx = polyfit(xpts',spts(:,1)/scl,1) cy = polyfit(ypts',spts(:,2)/scl,1) close all xr = [-0.2 0.2]; plot(xpts,spts(:,1)/1000,'ko',xr,polyval(cx,xr)); grid xlabel('calculated x-values'); ylabel('x-values from cube.eps file'); figure xr = [-0.25 0.25]; plot(ypts,spts(:,2)/1000,'ko',xr,polyval(cy,xr)); grid xlabel('calculated y-values'); ylabel('y-values from cube.eps file');
cx =
5.2291 3.5990
cy =
-5.2303 2.6995
xfit = polyval(cx,xpts'); yfit = polyval(cy,ypts'); xd = spts(:,1)-xfit*scl; yd = spts(:,2)-yfit*scl; plot(xd,yd,'ko') grid; axis equal xlabel('x error (pixels)'); ylabel('y error (pixels)'); dm = 0.2; for n=1:8 str = sprintf('%d',n); text(xd(n)+dm*rand,yd(n)+dm*rand,str); end maxerr = squeeze(max([xd; yd])); fprintf('maxerror %e\n',maxerr);
maxerror 1.229105e+01