function [wimg, w, a] = TPS_im_warp(img, ipts, opts, verbose)
% function [wimg, w, a] = TPS_im_warp(img, ipts, opts)
%
% This function implements the THIN PLATE SPLINE method of image warping.
% 
% Input Params:
%  img - the image to be warped
%  ipts - the set of input pts that the image is to be warped to
%  opts - the set of input pts that the image is already registered to
%
% Dr. A. I. Hanna (2006).
w = [];
a = [];
if nargin<3
    return;
end
if nargin < 4
    verbose = 0;
end

[w, a, K] = pts2TPS_param(opts, ipts);

BendingEnergyx = w(:,1)'*K*w(:,1)
BendingEnergyy = w(:,2)'*K*w(:,2)


ceil(max(ipts(:,2)))
ceil(max(ipts(:,1)))
wimg = zeros(ceil(max(ipts(:,2))), ceil(max(ipts(:,1))), size(img,3));
if verbose
    fprintf('Image Size: %d by %d\n', size(img,1), size(img,2));
end
size(wimg)
wh = waitbar(0, 'Please wait...');
for i=1:size(wimg,2)
    waitbar(i/size(wimg,2), wh);
    tps = psi_tps([i*ones(size(wimg,1),1),(1:size(wimg,1))'], a, w, ipts);
    tps_x = round(tps(:,1)); tps_y = round(tps(:,2));
    for ii=1:length(tps_x)
        if (tps_x(ii))>0 & (tps_x(ii) < size(img,2)) & (tps_y(ii)>0) & (tps_y(ii)<size(img,1))
            wimg(ii, i, :) = img(tps_y(ii), tps_x(ii), :);
        end
    end
    if verbose; fprintf('.'); if mod(i, 50)==0; fprintf('\n'); end; end;
end
close(wh);
if verbose; fprintf('\n'); end;
wimg = uint8(wimg);
return;