spm_swarp.m 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. function that = spm_swarp(this,def,M)
  2. % Warp surface
  3. % FORMAT that = spm_swarp(this,def)
  4. % this - a gifti object
  5. % def - a deformation (nifti object or filename)
  6. % that - the warped gifti object
  7. %
  8. % FORMAT that = spm_swarp(this,def,M)
  9. % this - a gifti object
  10. % def - a deformation field (nx*ny*nz*1*3)
  11. % M - mapping from voxels to world, for deformation field
  12. % that - the warped gifti object
  13. %
  14. %__________________________________________________________________________
  15. % Copyright (C) 2009-2015 Wellcome Trust Centre for Neuroimaging
  16. % John Ashburner
  17. % $Id: spm_swarp.m 6349 2015-02-26 12:15:06Z guillaume $
  18. %-Input arguments
  19. %--------------------------------------------------------------------------
  20. this = gifti(this);
  21. if nargin<2, that = this; return; end
  22. if ischar(def) || isa(def,'nifti')
  23. if ischar(def)
  24. def = nifti(def);
  25. end
  26. y = def(1).dat(:,:,:,:,:);
  27. M = def(1).mat;
  28. else
  29. y = def;
  30. if nargin<3, M = eye(4); end
  31. end
  32. %-Apply deformation to vertices
  33. %--------------------------------------------------------------------------
  34. v = double(this.vertices);
  35. iM = inv(M);
  36. v = iM(1:3,1:4) * this.mat * [v'; ones(1,size(v,1))];
  37. xyz = {v(1,:)',v(2,:)',v(3,:)'};
  38. v = [spm_bsplins(y(:,:,:,1,1), xyz{:}, [1 1 1 0 0 0]),...
  39. spm_bsplins(y(:,:,:,1,2), xyz{:}, [1 1 1 0 0 0]),...
  40. spm_bsplins(y(:,:,:,1,3), xyz{:}, [1 1 1 0 0 0])];
  41. % Much of the surface data is likely to fall outside the FOV of the
  42. % deformation field. For this reason, the following code attempts to
  43. % extrapolate the surfaces outside this FOV by replacing NaNs in the
  44. % vertice coordinates by some smooth mesh.
  45. %--------------------------------------------------------------------------
  46. if isfield(this, 'faces')
  47. f = double(this.faces);
  48. m = size(v,1);
  49. % Gradients
  50. b = double([v(:,1); v(:,2); v(:,3)]);
  51. w = isfinite(b);
  52. b(~w) = 0;
  53. % Hessian
  54. A = spdiags(w,0,m*3,m*3);
  55. W = sparse(f(:,1),f(:,1),1,m,m) + sparse(f(:,2),f(:,2),1,m,m) + sparse(f(:,3),f(:,3),1,m,m)...
  56. - sparse(f(:,1),f(:,2),1,m,m) - sparse(f(:,2),f(:,3),1,m,m) - sparse(f(:,3),f(:,1),1,m,m);
  57. W = (W'*W + 0.25*W)*1e-2;
  58. Z = sparse([],[],[],m,m);
  59. A = A + [W Z Z; Z W Z; Z Z W];
  60. % Solution to simple linear model
  61. v = full(reshape(A\b,m,3));
  62. end
  63. %-Generate the gifti structure for the warped data
  64. %--------------------------------------------------------------------------
  65. that = this;
  66. that.vertices = v;
  67. that.mat = eye(4); % this.mat already applied to v