Code covered by the BSD License  

Highlights from
Create a non Isotropic 3D Gaussian Point Spread Function (PSF)

image thumbnail

Create a non Isotropic 3D Gaussian Point Spread Function (PSF)

by

 

13 Mar 2012 (Updated )

Create an isotropic or non isotropic 3D Gaussian PSF

nonIsotropicGaussianPSF(inSigma,varargin)
function [outKer] = nonIsotropicGaussianPSF(inSigma,varargin)
%% NONISOTROPICGAUSSIANPSF - Creates a isotropic / non isotropic 3D Gaussian kernel.
%Uses the Statistical toolbox if installed (mvnpdf). Works without Statistical Toolbox, but slower and
% with higher limitation when it comes to the size of the PSF support..
%
% Syntax:  [outKer]     = nonIsotropicPSF(inSigma)
%                                  = nonIsotropicPSF(inSigma,sizeDomain)
%                                  = nonIsotropicPSF(inSigma,sizeDomain,precision)
% Inputs:
%    inSigma - scalar (isotropic) or 3x1 vector with the standard deviation of the Gaussian kernel (reminder :
%    sigma=FWHM/(2*sqrt(2*ln(2))) )
%   sizeDomain (optional) - Define the size of the support of the PSF (default: 2.1*max(inSigma))
%   precision (optional) - Add 'single' as input to calculate in single precision (default: double).
%   The precision is important when using the function without the Statistical Toolbox.
%
% Outputs:
%    outKer - 3D non isotropic Gaussian kernel
%
% Example:
%   outKer = nonIsotropicGaussianPSF([5.12 5.9 5.8],3);
%   If Out of Memory, try : 
%   outKer = nonIsotropicGaussianPSF([5.12 5.9 5.8],3,'single');
%
% Other m-files required: areTheseToolboxesInstalled (added in this file)
% Subfunctions: none
% MAT-files required: none

% Author: Christopher Coello
% Work address: Preclinical PET/CT Unit
% Email address: s.c.coello@medisin.uio.no
% Website: http://www.med.uio.no/imb/english/services/public/pet/
% 2012/03/13; Last revision: 2012/03/16
% Created with Matlab version: 7.13.0.564 (R2011b)
%%
% Init
outKer=0;
% Input check
switch length(varargin),
    case 2
        if strcmp(varargin{2},'single'),
            indS=1;
        else
            display('Wrong precision argument. Only single is accepted (default : double)');return;
        end
        extentSupport=varargin{1};
    case 1
        if isnumeric(varargin{1})
            extentSupport=varargin{1};
            indS=0;
        elseif strcmp(varargin{1},'single'),
            indS=1;
            extentSupport=2.1;
        else
            display('Wrong precision argument. Only single is accepted (default : double)');return;
        end
    otherwise
        extentSupport=2.1;
        indS=0;
end

% Defines the covariance matrix
if isscalar(inSigma),
    inSigma=ones(3,1)*inSigma;
end
if indS,
    S=single(diag(inSigma));
else
    S=diag(inSigma);
end

% Defines the size of the kernel in relation with the Gaussian properties
supportSize=ceil(extentSupport*max(inSigma));

% Initialise the volume where the kernel is to be drawn
[X,Y,Z]=meshgrid(-supportSize:1:supportSize);

% Put it in columns
if indS,
    coord=single([X(:) Y(:) Z(:)]);
else
    coord=[X(:) Y(:) Z(:)];
end
mu=mean(coord);

% Define the output size
outsize=size(X);


if (areTheseToolboxesInstalled('Statistics Toolbox')),
    
    %with statistics toolbox
    clear X Y Z
    
    % Check mvnpdf help for details on this function
    p = mvnpdf(coord, mu, S);
    
    % Output vector is reshaped to volume.
    outKer=reshape(p,outsize);
    
else
    
    %without statistics toolbox
    
    % Calculates the amplitude of the PSF
    if indS,
        AmplitudePSF=single(1/((2*pi)^(3/2)*det(S)^(1/2)));
    else
        AmplitudePSF=1/((2*pi)^(3/2)*det(S)^(1/2));
    end
    
    % Center the volume
    clear coord
    if indS,
        c_coord=single([X(:)-mu(1) Y(:)-mu(2) Z(:)-mu(3)]);
    else
        c_coord=[X(:)-mu(1) Y(:)-mu(2) Z(:)-mu(3)];
    end
    
    % Apply the equation of the Gaussian distribution
    T_hand=AmplitudePSF*exp(-0.5*c_coord*(S^-1)*c_coord');
    
    % Reshape to volume
    outKer=reshape(diag(T_hand),outsize);
    
end

% Check if the support is big enough
if ((1-sum(outKer(:)))*100>0.01),
    display(['Warning : ' num2str((1-sum(outKer(:)))*100) '% of the Gaussian is outside the domain.'])
    display('If not acceptable, widen the domain of the PSF by defining a superior second argument (default: 2.1*max(inSigma)).')
end


function tf = areTheseToolboxesInstalled(requiredToolboxes)
%ARETHESETOOLBOXESINSTALLED takes a cell array of toolbox names and checks whether they are currently installed
% SYNOPSIS tf = areTheseToolboxesInstalled(requiredToolboxes)
%
% INPUT requiredToolboxes: cell array with toolbox names to test for. Eg.
%        {'MATLAB','Image Processing Toolbox'}
%
% OUTPUT tf: true or false if the required toolboxes are installed or not
%%%%%%%%%%%%%%%%%%%%%%%%%%

% get all installed toolbox names
v = ver;

% collect the names in a cell array
[installedToolboxes{1:length(v)}] = deal(v.Name);

% check
tf = all(ismember(requiredToolboxes,installedToolboxes));

Contact us