Code covered by the BSD License  

Highlights from
3D Free Form Image Registration Toolbox (GUI)

image thumbnail
from 3D Free Form Image Registration Toolbox (GUI) by Daniel Markel
A toolbox for performing image registrations on 4D RTOG files or any other volumetric image.

imdeform3D(image1,image2,alpha,beta,gamma,iterations,steps,fpoints,fpoints2,res1,res2)
%Imdeform3D
% This function calculates the optimized control grid parameters
% (dgridx,dgridy,dgridz) necessary to register image1 to image2. Image 1
% and 2 are assumed to be globally registered binary contours of matching
% resolution. dimage is the deformed contour image1 after optimization.
% The definitions of the remaining inputs are as follows
%                                                 Recommended  
% Alpha (smoothness weighting factor)                 1-5
% Beta (feature point weighting factor)               5-10
% Gamma (initial step size multiplying                0.2-2
%        factor)
% Iterations (number of times the                     1-3  
%             gradient is recalculated 
%             per level)
% Steps (number of steps evaluated per                3-10
%        gradient calculation to 
%        determine optimal step size)
%       
% fpoints(Mx3 array of coordinates of features points
%         in the source image)
% fpoints2(Mx3 array of the coordinates of the matching 
%          feature points in the target image. fpoints 
%          must be the same size as fpoints2, points 
%          are matched based on their corresponding 
%          order in the arrays, ie. the 8th coord in 
%          fpoints corresponds to the 8th coord in 
%          fpoints2) 
% res1 (the resolution of the first level            [22,22,22]
%       of the control grid mesh, remember  
%       that the actual resolution will  
%       be 2 units smallers in each 
%       dimension due to an assumed           
%       padding around the control grid)
% res2 (resolution of the second level, a finer      [42,42,42]
%       mesh used to match more detailed 
%       regions of the contour)

% Daniel Markel PMH 2007
function [dimage,dgridx,dgridy,dgridz] = imdeform3D(image1,image2,alpha,beta,gamma,iterations,steps,fpoints,fpoints2,res1,res2)

sze = size(image1);
sze2 = size(image2);
if sze(1) ~= sze2(1) || sze(2) ~= sze2(2) || sze(3) ~= sze2(3)
    error('Target and Source image sizes do not match');
end
sz = size(image1);
M = res1(1);
N = res1(2);
P = res1(3);
image2 = bwdist(image2,'quasi-euclidean');
dgridx = zeros(M,N,P);
dgridy = zeros(M,N,P);
dgridz = zeros(M,N,P);
errorinit = elocal3D(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
for j = 1:iterations
   
    [gradgridx,gradgridy,gradgridz] = calcgrad3D2(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
    gradgridx = gradgridx./max(max(max(abs(gradgridx))));
    gradgridy = gradgridy./max(max(max(abs(gradgridy))));
    gradgridz = gradgridz./max(max(max(abs(gradgridz))));
    gamma1 = gamma*(max(max(max(image2)))-0.5)*(((res1(1)+res1(1)+res1(1))/3)-3)/((sz(1)+sz(2)+sz(3))/3);
        k = 1;
        while k <= steps
        dgridx = dgridx - gamma1.*gradgridx;
        dgridy = dgridy - gamma1.*gradgridy;
        dgridz = dgridz - gamma1.*gradgridz;
            %perform corrections
              %voxel displacement and mesh folding check
            for t = 2:res1(3)-1 
                [dgridx(:,:,t-1:t+1),dgridy(:,:,t-1:t+1),dgridz(:,:,t-1:t+1)] = amvd3D(sz,res1,[sz(1),sz(2),3],dgridx(:,:,t-1:t+1),dgridy(:,:,t-1:t+1),dgridz(:,:,t-1:t+1));
            end 
              % maximum volume expansion/compression check
%             [dgridx,dgridy,dgridz] = amvold(dgridx,dgridy,dgridz,110);
            
        errorloc = elocal3D(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
        
        if sum(sum(sum(errorloc)))>= sum(sum(sum(errorinit)))
            k = k+1;
            dgridx = dgridx + gamma1.*gradgridx;
            dgridy = dgridy + gamma1.*gradgridy;
            dgridz = dgridz + gamma1.*gradgridz;
            gamma1= gamma1./1.5;
        else
            gamma1 = gamma1./1.5;
            errorinit = errorloc;
            k = k+1;
        end
        
        end
end
zarray1 = zeros(1,1,res1(3));
zarray2 = zeros(1,1,res2(3));
zarray1(:) = 1:res1(3);
zarray2(:) = 1:(res1(3)-1)/(res2(3)-1):res1(3);
dgridx = interp3(repmat(1:res1(2),[res1(1),1,res1(3)]),repmat((1:res1(1))',[1,res1(2),res1(3)]),repmat(zarray1,[res1(1),res1(2),1]),dgridx,repmat(1:(res1(2)-1)/(res2(2)-1):res1(2),[res2(1),1,res2(3)]),repmat((1:(res1(1)-1)/(res2(1)-1):res1(1))',[1,res2(2),res2(3)]),repmat(zarray2,[res2(1),res2(2),1]),'linear');
dgridy = interp3(repmat(1:res1(2),[res1(1),1,res1(3)]),repmat((1:res1(1))',[1,res1(2),res1(3)]),repmat(zarray1,[res1(1),res1(2),1]),dgridy,repmat(1:(res1(2)-1)/(res2(2)-1):res1(2),[res2(1),1,res2(3)]),repmat((1:(res1(1)-1)/(res2(1)-1):res1(1))',[1,res2(2),res2(3)]),repmat(zarray2,[res2(1),res2(2),1]),'linear');
dgridz = interp3(repmat(1:res1(2),[res1(1),1,res1(3)]),repmat((1:res1(1))',[1,res1(2),res1(3)]),repmat(zarray1,[res1(1),res1(2),1]),dgridz,repmat(1:(res1(2)-1)/(res2(2)-1):res1(2),[res2(1),1,res2(3)]),repmat((1:(res1(1)-1)/(res2(1)-1):res1(1))',[1,res2(2),res2(3)]),repmat(zarray2,[res2(1),res2(2),1]),'linear');

errorinit = elocal3D(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
for j = 1:iterations
   

 
    [gradgridx,gradgridy,gradgridz] = calcgrad3D2(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
    gradgridx = gradgridx./max(max(max(abs(gradgridx))));
    gradgridy = gradgridy./max(max(max(abs(gradgridy))));
    gradgridz = gradgridz./max(max(max(abs(gradgridz))));
    gamma1 = gamma*(max(max(max(image2)))-0.5)*(((res2(1)+res2(2)+res2(3))/3)-3)/((sz(1)+sz(2)+sz(3))/3);

        k = 1;
        while k <= steps
        dgridx = dgridx - gamma1.*gradgridx;
        dgridy = dgridy - gamma1.*gradgridy;
        dgridz = dgridz - gamma1.*gradgridz;

        %yup corrections again
for t = 2:res2(3)-1
    [dgridx(:,:,t-1:t+1),dgridy(:,:,t-1:t+1),dgridz(:,:,t-1:t+1)] = amvd3D(sz,res2,[sz(1),sz(2),3],dgridx(:,:,t-1:t+1),dgridy(:,:,t-1:t+1),dgridz(:,:,t-1:t+1));
end 
%  [dgridx,dgridy,dgridz] = amvold(dgridx,dgridy,dgridz,110);
        errorloc = elocal3D(image1,image2,dgridx,dgridy,dgridz,alpha,beta,fpoints,fpoints2);
        

        if sum(sum(sum(errorloc)))>= sum(sum(sum(errorinit)))
            k = k+1;
            dgridx = dgridx + gamma1.*gradgridx;
            dgridy = dgridy + gamma1.*gradgridy;
            dgridz = dgridz + gamma1.*gradgridz;
            gamma1= gamma1./1.5;
        else
            gamma1 = gamma1./1.5;
            errorinit = errorloc;
            k = k+1;
        end
        
        end
end
[dimage,imagedist] = imrecreate3D(image1,dgridx,dgridy,dgridz);

Contact us at files@mathworks.com