Eidors-logo    

EIDORS: Electrical Impedance Tomography and Diffuse Optical Tomography Reconstruction Software

EIDORS (mirror)
Main
Documentation
Examples
Tutorials
− Image Reconst
− Data Structures
− Application Examples
− FEM Modelling
Download
Contrib Data
GREIT
Browse SVN

News
FAQ
Developer
                       

 

Hosted by SourceForge.net Logo

 

GREIT algorithm: NOSER

This algorithm implements a NOSER-type (Newton's one-step error reconstructor) Gauss-Newton normalized difference inverse. This follows the reference:

GREIT NOSER algorithm for time difference

function [img,map]= GREIT_NOSER_diff( ref_meas, reconst_meas )
% Reconstruct GREIT images using NOSER algorithm
%
% (C) 2008 Andy Adler. Licenced under GPL v2 or v3
% $Id: GREIT_NOSER_diff.m 1561 2008-07-27 03:43:12Z aadler $

   [RM,map] = calc_NOSER_RM;

   % Expand ref_meas to the full size of reconst_meas
   num_meas = size(reconst_meas,2);
   ref_meas = ref_meas * ones(1,num_meas);
   dv =  reconst_meas - ref_meas;

   % reconst image
   ds = RM*dv;

   img= reshape(ds, 32,32,num_meas);

function [RM,map] = calc_NOSER_RM
   [J,map] = GREIT_Jacobian_cyl;
   RM = zeros(size(J'));
 
   % Remove space outside FEM model
   J= J(:,map);
   % inefficient code - but for clarity
   diagJtJ = diag(J'*J);
   R= spdiags( diagJtJ,0, length(diagJtJ), length(diagJtJ));

   hp = 2.0;
   RM(map,:)= (J'*J + hp^2*R)\J';

GREIT NOSER algorithm for normalized time difference

function [img,map]= GREIT_NOSER_ndiff( ref_meas, reconst_meas )
% Reconstruct GREIT images using NOSER algorithm
%
% (C) 2008 Andy Adler. Licenced under GPL v2 or v3
% $Id: GREIT_NOSER_ndiff.m 1561 2008-07-27 03:43:12Z aadler $

   [RM,map] = calc_NOSER_RM;

   % Expand ref_meas to the full size of reconst_meas
   num_meas = size(reconst_meas,2);
   ref_meas = ref_meas * ones(1,num_meas);
   dv = ( reconst_meas - ref_meas ) ./ ref_meas; % CHANGE IS HERE:

   % reconst image
   ds = RM*dv;

   img= reshape(ds, 32,32,num_meas);

function [RM,map] = calc_NOSER_RM
   [J,map,vbkgnd] = GREIT_Jacobian_cyl;
   J = J ./ (vbkgnd*ones(1,size(J,2))); % Normalized Jacobian
   RM = zeros(size(J'));
 
   % Remove space outside FEM model
   J= J(:,map);
   % inefficient code - but for clarity
   diagJtJ = diag(J'*J);
   R= spdiags( diagJtJ,0, length(diagJtJ), length(diagJtJ));

   hp = 2.0;
   RM(map,:)= (J'*J + hp^2*R)\J';

Jacobian Calculation

The previous code depends on this function to calculate and cache the Jacobian matrix, based on the 62465 element FEM model available here:
function [J,map,vbkgnd] = GREIT_Jacobian_cyl;
% Calculate the GREIT 32x32 Jacobian for a cylinder
% The FEM Model ng_mdl_16x1_fine must be available
%
% (C) 2008 Andy Adler. Licenced under GPL v2 or v3
% $Id: GREIT_Jacobian_cyl.m 1597 2008-07-30 01:40:14Z aadler $

if exist('GREIT_Jacobian_cyl.mat','file');
   load GREIT_Jacobian_cyl.mat J map vbkgnd
else
   [J,vbkgnd,map] = Jacobian_calc;
   save GREIT_Jacobian_cyl.mat J map vbkgnd
end


function [J,vbkgnd,map] = Jacobian_calc;
use_3d_model = 1;
if use_3d_model % This 3D model has some problems
%  load ng_mdl_16x1_fine;  fmdl= ng_mdl_16x1_fine;
   load ng_tank1_0; 
   fmdl.solve =    @aa_fwd_solve;
   fmdl.jacobian = @aa_calc_jacobian;
   fmdl.system_mat=@aa_calc_system_mat;
   fmdl.elems = double(fmdl.elems);
else
   imdl = mk_common_model('f2d3c',16); fmdl= imdl.fwd_model;
   fmdl.nodes = fmdl.nodes(:,[2,1]);
end

   fmdl.nodes(:,1) = -fmdl.nodes(:,1); % yvec is reversed because image yaxis is reversed

   pixel_grid= 32;
   nodes= fmdl.nodes;
   xyzmin= min(nodes,[],1);  xyzmax= max(nodes,[],1);
   xvec= linspace( xyzmin(1), xyzmax(1), pixel_grid+1);
   yvec= linspace( xyzmin(2), xyzmax(2), pixel_grid+1);

   % CALCULATE MODEL CORRESPONDENCES
if use_3d_model
   zvec= [0.6*xyzmin(3)+0.4*xyzmax(3), 0.4*xyzmin(3)+0.6*xyzmax(3)];
   [rmdl,c2f] = mk_grid_model(fmdl, xvec, yvec, zvec);
else
   [rmdl,c2f] = mk_grid_model(fmdl, xvec, yvec);
end

   img= eidors_obj('image','GREIT-ng_mdl');
   img.fwd_model= fmdl;
   img.fwd_model.coarse2fine = c2f;
   img.rec_model= rmdl;
   img.elem_data= ones(size(img.fwd_model,1));

   % ADJACENT STIMULATION PATTERNS
   img.fwd_model.stimulation= mk_stim_patterns(16, 1, ...
                [0,1],[0,1], {'do_redundant', 'no_meas_current'}, 1);

   % SOLVERS
   img.fwd_model.system_mat= @aa_calc_system_mat;
   img.fwd_model.solve=      @aa_fwd_solve;
   img.fwd_model.jacobian=   @aa_calc_jacobian;

   vbkgnd = fwd_solve(img);
   vbkgnd = vbkgnd.meas;
   J= calc_jacobian(img);

%  map = reshape(sum(c2f,1),pixel_grid,pixel_grid)>0;
   [x,y]= meshgrid(linspace(-1,1,32),linspace(-1,1,32));
   map = x.^2 + y.^2 < 1.1;

Last Modified: $Date: 2008-07-26 19:50:56 -0400 (Sat, 26 Jul 2008) $ by $Author: aadler $