% est_bilinear Steve Mann, 1992-1993 % (not called est_bilinear2 because the 2 is obvious from ``bi'' in bilinear) % % estimate the 8 bilinear parameters from a pair of images % % The model is: u = p1xy + p2x + p3y + p4 % v = p5xy + p6x + p7y + p8 % % Use: p = est_bilinear(A,B); % or: [p1,p2,p3,p4,p5,p6,p7,p8] = bilinear_est(A,B); % or : est_bilinear(A,B); % nicely formatted screen output % % Example application: pb=est_bilinear(A,B); % pp=bilinear2p(pb); % B2=pchirp2(pp,B); % now B2 will look alot like A % pb=est_bilinear(A,B2); % residual difference % pp=bilinear2p(pb); % B3=pchirp2(pp,B); % almost exactly like A by now % % relation to pchirp2: p1=-(ah+bg); p2=(a-cg); p3=(b-ch); p4=c; % p5=-(dh+eg); p6=(d-fg); p7=(e-fh); p8=f; % sign convention: m (or X) down, n (or Y) to right % properly handles situation when one or both images contain some NaN points % % See also: bilinear2p, pchirp2 function [p1,p2,p3,p4,p5,p6,p7,p8]=f(E1,E2); % two images in, 0,1,or 8 outs %%%%mask = isnan(E1).*isnan(E2); % NaN mask: regions where either is undefined % doesnt work because nanmask makes it still nan [El,Em,En] = derivatives(E1,E2); [M,N]= size(El); % size of any of the 3 derivative matrices [n m]=meshdom(1:N,M:-1:1); % variables ``x'' and ``y'' %disp('est_bilinear: converting from pixels to units on [0,1)') doesnt work %m=m/M; doesnt work %n=n/N; doesnt work DERIVATIVES = ... [... [sum2nan(m.*n.*Em .*m.*n.*Em) sum2nan(m.*Em .*m.*n.*Em) sum2nan(n.*Em .*m.*n.*Em) sum2nan(Em .*m.*n.*Em)... sum2nan(m.*n.*En .*m.*n.*Em) sum2nan(m.*En .*m.*n.*Em) sum2nan(n.*En .*m.*n.*Em) sum2nan(En .*m.*n.*Em)];... [sum2nan(m.*n.*Em .*m.*Em) sum2nan(m.*Em .*m.*Em) sum2nan(n.*Em .*m.*Em) sum2nan(Em .*m.*Em)... sum2nan(m.*n.*En .*m.*Em) sum2nan(m.*En .*m.*Em) sum2nan(n.*En .*m.*Em) sum2nan(En .*m.*Em)];... [sum2nan(m.*n.*Em .*n.*Em) sum2nan(m.*Em .*n.*Em) sum2nan(n.*Em .*n.*Em) sum2nan(Em .*n.*Em)... sum2nan(m.*n.*En .*n.*Em) sum2nan(m.*En .*n.*Em) sum2nan(n.*En .*n.*Em) sum2nan(En .*n.*Em)];... [sum2nan(m.*n.*Em .*Em) sum2nan(m.*Em .*Em) sum2nan(n.*Em .*Em) sum2nan(Em .*Em)... sum2nan(m.*n.*En .*Em) sum2nan(m.*En .*Em) sum2nan(n.*En .*Em) sum2nan(En .*Em)];... [sum2nan(m.*n.*Em .*m.*n.*En) sum2nan(m.*Em .*m.*n.*En) sum2nan(n.*Em .*m.*n.*En) sum2nan(Em .*m.*n.*En)... sum2nan(m.*n.*En .*m.*n.*En) sum2nan(m.*En .*m.*n.*En) sum2nan(n.*En .*m.*n.*En) sum2nan(En .*m.*n.*En)];... [sum2nan(m.*n.*Em .*m.*En) sum2nan(m.*Em .*m.*En) sum2nan(n.*Em .*m.*En) sum2nan(Em .*m.*En)... sum2nan(m.*n.*En .*m.*En) sum2nan(m.*En .*m.*En) sum2nan(n.*En .*m.*En) sum2nan(En .*m.*En)];... [sum2nan(m.*n.*Em .*n.*En) sum2nan(m.*Em .*n.*En) sum2nan(n.*Em .*n.*En) sum2nan(Em .*n.*En)... sum2nan(m.*n.*En .*n.*En) sum2nan(m.*En .*n.*En) sum2nan(n.*En .*n.*En) sum2nan(En .*n.*En)];... [sum2nan(m.*n.*Em .*En) sum2nan(m.*Em .*En) sum2nan(n.*Em .*En) sum2nan(Em .*En)... sum2nan(m.*n.*En .*En) sum2nan(m.*En .*En) sum2nan(n.*En .*En) sum2nan(En .*En)]... ]; Derivatives = ... - [sum2nan(El .*m.*n.*Em); ... sum2nan(El .*m.*Em); ... sum2nan(El .*n.*Em); ... sum2nan(El .*Em); ... sum2nan(El .*m.*n.*En); ... sum2nan(El .*m.*En); ... sum2nan(El .*n.*En); ... sum2nan(El .*En) ... ]; % vector of derivatives parameters = DERIVATIVES\Derivatives; disp('est_bilinear: adding identity and converting from pel to normalized [0,1) rep.') parameters(:) = parameters(:) + [0;1;0;0; 0;0;1;0]; % convert relative change like u=func(x+deltax) to absolute like u=func(x) parameters = parameters(:) .* [N;1;N/M;1/M; M;M/N;1;1/N]; if (nargout == 8) | (nargout == 0) % p1 = parameters(1); % if called with no semicolon, do not want to see any ans=[], etc, so make no reference to p1 p2 = parameters(2); p3 = parameters(3); p4 = parameters(4); p5 = parameters(5); p6 = parameters(6); p7 = parameters(7); p8 = parameters(8); end%if if nargout == 8 p1 = parameters(1); end%if if nargout == 1 p1 = parameters; end%if if nargout == 0 disp('est_bilinear: 0 output arguments given so I am displaying result to screen:') disp(sprintf('%g %g %g %g %g %g %g %g',parameters(1),p2,p3,p4,p5,p6,p7,p8)) end%if if (nargout ~=0) & (nargout ~= 1) & (nargout ~= 8) error('est_bilinear: number of output arguments must be 0, 1, or 8') end%if