# v_rectifyhomog

## PURPOSE

V_RECTIFYHOMOG Apply rectifying homographies to an image set

## SYNOPSIS

function [imr,xa,ya]=v_rectifyhomog(ims,roc,k0,mode)

## DESCRIPTION

    V_RECTIFYHOMOG Apply rectifying homographies to an image set

     Usage:    figure(101);     % Initial figure for rectiied image display
               v_rectifyhomog(ims,roc,k0,'ga');   % plot in individual figures

     Inputs:
            ims{nc}       cell array of input images (colour or monochrome)
            roc(3,3,nc)   v_rotation matrices from world coordinates to camera coordinates
            k0            camera matrix or focal length in pixels optionally divided by the image width [0.8]
            mode          mode string
                             g  show images on separate figures
                             G  tile images onto a single figure [default if no output arguments]
                             k  clip to original image dimensions
                             l  do not link axes
                             v  k0 contains diffent values for each camera
                             a  orient to average camera orientation
                            [z  make optical axis perpendicular to camera plane]
                            [x  align x axis with camera displacements]
     Outputs:
            imr{nc}(my,mx,nc)  output images (uint8)
            xa{nc}(mx)        x axis for each image
            ya{nc}(my)        y axis for each image

## CROSS-REFERENCE INFORMATION

This function calls:

- v_imagehomog V_IMAGEHOMOG Apply a homography transformation to an image with bilinear interpolation
- v_rotqr2ro ROTQR2RO converts a real quaternion to a 3x3 rotation matrix
- v_rotqrmean V_ROTQRMEAN calculates the mean rotation of a quaternion array [y,s]=[q]
- v_rotro2eu V_ROTRO2EU converts a 3x3 rotation matrix into the corresponding euler angles
- v_rotro2qr V_ROTRO2QR converts a 3x3 rotation matrix to a real quaternion

This function is called by:

## SOURCE CODE

    0001 function [imr,xa,ya]=v_rectifyhomog(ims,roc,k0,mode)
    0002 %V_RECTIFYHOMOG Apply rectifying homographies to an image set
    0003 %
    0004 % Usage:    figure(101);     % Initial figure for rectiied image display
    0005 %           v_rectifyhomog(ims,roc,k0,'ga');   % plot in individual figures
    0006 %
    0007 % Inputs:
    0008 %        ims{nc}       cell array of input images (colour or monochrome)
    0009 %        roc(3,3,nc)   v_rotation matrices from world coordinates to camera coordinates
    0010 %        k0            camera matrix or focal length in pixels optionally divided by the image width [0.8]
    0011 %        mode          mode string
    0012 %                         g  show images on separate figures
    0013 %                         G  tile images onto a single figure [default if no output arguments]
    0014 %                         k  clip to original image dimensions
    0015 %                         l  do not link axes
    0016 %                         v  k0 contains diffent values for each camera
    0017 %                         a  orient to average camera orientation
    0018 %                        [z  make optical axis perpendicular to camera plane]
    0019 %                        [x  align x axis with camera displacements]
    0020 % Outputs:
    0021 %        imr{nc}(my,mx,nc)  output images (uint8)
    0022 %        xa{nc}(mx)        x axis for each image
    0023 %        ya{nc}(my)        y axis for each image
    0024
    0025 %      Copyright (C) Mike Brookes 2012
    0026 %      Version: $Id: v_rectifyhomog.m 10865 2018-09-21 17:22:45Z dmb $
    0027 %
    0028 %   VOICEBOX is a MATLAB toolbox for speech processing.
    0029 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
    0030 %
    0031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0032 %   This program is free software; you can redistribute it and/or modify
    0033 %   it under the terms of the GNU Lesser General Public License as published by
    0034 %   the Free Software Foundation; either version 3 of the License, or
    0035 %   (at your option) any later version.
    0036 %
    0037 %   This program is distributed in the hope that it will be useful,
    0038 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
    0039 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0040 %   GNU Lesser General Public License for more details.
    0041 %
    0042 %   You can obtain a copy of the GNU Lesser General Public License from
    0043 %   https://www.gnu.org/licenses/ .
    0044 %
    0045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0046 if ~iscell(ims)
    0047     ims={ims};
    0048 end
    0049 nc=numel(ims); % number of images
    0050 if ~((nc==1 && isequal(size(roc),[3 3])) || isequal(size(roc),[3 3 nc]))
    0051     error('roc should have dimensions [3,3,%d]',nc);
    0052 end
    0053 if nargin<4 || ~numel(mode)
    0054     mode='';
    0055 end
    0056 if nargin<3 || ~numel(k0)
    0057     k0=0.8;
    0058 end
    0059 if nargin<2 || ~numel(roc)
    0060     roc=repmat(eye(3),[1 1 nc]);
    0061 end
    0062
    0063 % sort out options
    0064
    0065 vv=any(mode=='v');  % different k0 for each camera
    0066 nk=numel(k0)/(1+vv*(nc-1));  % number of k parameters per camera
    0067 switch nk
    0068     case {1,3}
    0069         k0=reshape(k0,[1 nk 1+vv*(nc-1)]);
    0070     case 9
    0071         k0=reshape(k0,[3 3 1+vv*(nc-1)]);
    0072     otherwise
    0073         error('k0 must have 1, 3 or 9 values per camera');
    0074 end
    0075 ncr=1+(nargout>0)*(nc-1);   % numer of output images
    0076 if any(mode=='g')
    0077     gmode=1;
    0078 elseif any(mode=='G') || ~nargout
    0079     gmode=2;
    0080 else
    0081     gmode=0;
    0082 end
    0083 if gmode>0
    0084     fig0=gcf; % initialize the figure
    0085 end
    0086 if any(mode=='k')
    0087     modeh='kxt';
    0088 else
    0089     modeh='t';
    0090 end
    0091
    0092 % determine a global camera v_rotation
    0093
    0094 if any(mode=='a')
    0095     qrc=zeros(4,nc);  % calculate the mean camera orientation
    0096     for i=1:nc
    0097         qrc(:,i)=v_rotro2qr(roc(:,:,i));
    0098     end
    0099     rocmean=v_rotqr2ro(v_rotqrmean(qrc));
    0100 else
    0101     rocmean=eye(3);
    0102 end
    0103
    0104 % now do image transformations
    0105
    0106 imr=cell(ncr,1);
    0107 xa=imr;
    0108 ya=imr;
    0109 axh=zeros(nc,1);
    0110 splx=ceil(sqrt(nc));
    0111 sply=ceil(nc/splx);
    0112 for i=1:nc
    0113     k0i=k0(:,:,1+vv*(i-1));  % camera parameters
    0114     if numel(k0i)<9
    0115         imsz=size(ims{i});
    0116         fe=k0(1);
    0117         if fe<0.1*imsz(2) % focal length is a fraction of the width
    0118             fe=k0*imsz(2);
    0119         end
    0120         if numel(k0i)<3
    0121             xy0=(imsz(2:-1:1)+1)/2;
    0122         else
    0123             xy0=k0i(2:3);
    0124         end
    0125         k0=eye(3);
    0126         k0(1:4:5)=fe;
    0127         k0(7:8)=xy0;
    0128     end
    0129     j=min(i,ncr);
    0130     rocall=rocmean*roc(:,:,i)';
    0131     titl=sprintf('%d: pan-tilt-roll = %.1f�, %.1f�, %.1f�',i,-v_rotro2eu('yxz',rocall)*180/pi);
    0132     [imr{j},xa{j},ya{j}]=v_imagehomog(uint8(ims{i}),k0*rocall/k0,modeh);  % apply inverse of v_rotation matrix
    0133     if gmode>0
    0134         if gmode>1
    0135             subplot(sply,splx,i);
    0136         else
    0137             figure(fig0+i-1);
    0138         end
    0139         imagesc(xa{j},ya{j},imr{j});
    0140         axis image
    0141         title(titl);
    0142         axh(i)=gca;
    0143     end
    0144 end
    0145 if gmode>0 && nc>1
    0146     if ~any(mode=='l')
    0147         linkaxes(axh);
    0148     end
    0149     figure(fig0);
    0150 end