mk_voxel_volume

PURPOSE ^

MK_VOXEL_VOLUME create a voxel model to reconstruct on

SYNOPSIS ^

function [imdl, fmdl] = mk_voxel_volume(varargin)

DESCRIPTION ^

MK_VOXEL_VOLUME create a voxel model to reconstruct on
 OUT = MK_VOXEL_VOLUME(MDL)
 OUT = MK_VOXEL_VOLUME(MDL, OPT)

 Inputs:
  MDL   = an EIDORS forward or inverse model structure
  OPT   = an option structure with the following fields and defaults:
     opt.imgsz = [32 32 4]; % X, Y and Z dimensions of the voxel grid
     opt.xvec  = []          % Specific X cut-planes between voxels
                             % A scalar means the number of planes
                             % Takes precedence over other options
     opt.yvec  = []          % Specific Y cut-planes between voxels
                             % A scalar means the number of planes
                             % Takes precedence over other options
     opt.zvec  = []          % Specific Z cut-planes between voxels
                             % A scalar means the number of planes
                             % Takes precedence over other options
     opt.square_pixels = 0;  % adjust imgsz to get square pixels (in XY)
     opt.cube_voxels = 0;    % adjust imgsz to get cube voxels (in XYZ)  
     opt.prune_model = true  % removes voxels outside the supplied MDL
                             % This runs mk_grid_c2f. For simple
                             % geometries, such a cylinder, it is much
                             % quicker to set to false and prune manually.
     opt.save_memory         % passed to mk_grid_c2f

 Output depends on the type of model supplied. If MDL is a fwd_model
 structure then OUT is a rec_model. If MDL is an inv_model, then OUT is a
 modified version of it, with the voxel volume in inv_model.rec_model and
 updated inv_model.fwd_model.coarse2fine
 
 [OUT FMDL] = MK_VOXEL_VOLUME(MDL, ...) also returns the forward model
 structure with the coarse2fine field.

 See also MK_PIXEL_SLICE, MK_GRID_MODEL, MK_GRID_C2F

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [imdl, fmdl] = mk_voxel_volume(varargin)
0002 %MK_VOXEL_VOLUME create a voxel model to reconstruct on
0003 % OUT = MK_VOXEL_VOLUME(MDL)
0004 % OUT = MK_VOXEL_VOLUME(MDL, OPT)
0005 %
0006 % Inputs:
0007 %  MDL   = an EIDORS forward or inverse model structure
0008 %  OPT   = an option structure with the following fields and defaults:
0009 %     opt.imgsz = [32 32 4]; % X, Y and Z dimensions of the voxel grid
0010 %     opt.xvec  = []          % Specific X cut-planes between voxels
0011 %                             % A scalar means the number of planes
0012 %                             % Takes precedence over other options
0013 %     opt.yvec  = []          % Specific Y cut-planes between voxels
0014 %                             % A scalar means the number of planes
0015 %                             % Takes precedence over other options
0016 %     opt.zvec  = []          % Specific Z cut-planes between voxels
0017 %                             % A scalar means the number of planes
0018 %                             % Takes precedence over other options
0019 %     opt.square_pixels = 0;  % adjust imgsz to get square pixels (in XY)
0020 %     opt.cube_voxels = 0;    % adjust imgsz to get cube voxels (in XYZ)
0021 %     opt.prune_model = true  % removes voxels outside the supplied MDL
0022 %                             % This runs mk_grid_c2f. For simple
0023 %                             % geometries, such a cylinder, it is much
0024 %                             % quicker to set to false and prune manually.
0025 %     opt.save_memory         % passed to mk_grid_c2f
0026 %
0027 % Output depends on the type of model supplied. If MDL is a fwd_model
0028 % structure then OUT is a rec_model. If MDL is an inv_model, then OUT is a
0029 % modified version of it, with the voxel volume in inv_model.rec_model and
0030 % updated inv_model.fwd_model.coarse2fine
0031 %
0032 % [OUT FMDL] = MK_VOXEL_VOLUME(MDL, ...) also returns the forward model
0033 % structure with the coarse2fine field.
0034 %
0035 % See also MK_PIXEL_SLICE, MK_GRID_MODEL, MK_GRID_C2F
0036 
0037 % (C) 2015 Bartlomiej Grychtol - all rights reserved by Swisstom AG
0038 % License: GPL version 2 or 3
0039 % $Id: mk_voxel_volume.m 6809 2024-04-23 14:14:43Z aadler $
0040 
0041 % >> SWISSTOM CONTRIBUTION <<
0042 
0043 imdl = varargin{1};
0044 % if input is 'UNIT_TEST', run tests
0045 if ischar(imdl) && strcmp(imdl,'UNIT_TEST') 
0046     do_unit_test; clear imdl 
0047     return; 
0048 end
0049 
0050 if nargin < 2
0051     opt = struct;
0052 else 
0053     opt = varargin{2};
0054 end
0055 
0056 switch(imdl.type)
0057     case 'inv_model'
0058         fmdl = imdl.fwd_model;
0059     case 'fwd_model'
0060         fmdl = imdl;
0061     otherwise
0062         error('An EIDORS inverse or forward model struct required');
0063 end
0064 
0065 opt = parse_opts(fmdl,opt);
0066 
0067 copt.fstr = 'mk_voxel_volume';
0068 copt.cache_obj = get_cache_obj(fmdl, opt);
0069 [rmdl, c2f] = eidors_cache(@do_voxel_volume,{fmdl, opt},copt);
0070 
0071 if ~isempty(c2f)
0072     fmdl.coarse2fine = c2f;
0073 end
0074 
0075 switch imdl.type
0076    case 'inv_model'
0077       imdl.rec_model = rmdl;
0078       imdl.fwd_model = fmdl;
0079    case 'fwd_model'
0080       imdl = rmdl;
0081 end
0082 
0083 
0084 %-------------------------------------------------------------------------%
0085 % The main function
0086 function [rmdl, c2f] = do_voxel_volume(fmdl,opt)
0087 
0088     rmdl = mk_grid_model([],opt.xvec,opt.yvec,opt.zvec);
0089     
0090        
0091     c2f = [];
0092     if ~opt.prune_model, return, end
0093     
0094     %     fmdl.elems = fmdl.elems( 210714,:);
0095     [c2f, m]  = mk_grid_c2f(fmdl, rmdl, opt);
0096     
0097     inside = any(c2f,1);
0098     c2f(:,~inside) = [];
0099     rm = ~logical(rmdl.coarse2fine*inside');
0100     rmdl.elems(rm,:) = [];
0101     rmdl.coarse2fine(rm,:) = [];
0102     rmdl.coarse2fine(:,~inside) = [];
0103     
0104     
0105     bnd_fcs = ones(1,nnz(inside))*m.vox2face(inside,:) == 1;
0106     rmdl.boundary = m.faces(bnd_fcs,:);
0107     rmdl.inside   = inside; % the inside array is useful in other functions
0108     
0109     rmdl.mdl_slice_mapper.x_pts = opt.x_pts;
0110     rmdl.mdl_slice_mapper.y_pts = opt.y_pts;
0111     rmdl.mdl_slice_mapper.z_pts = opt.z_pts;
0112     
0113     
0114 %-------------------------------------------------------------------------%
0115 % Assemble a reference object for caching
0116 function cache_obj = get_cache_obj(fmdl, opt)
0117     tmp = struct;
0118     flds = {'nodes','elems'};
0119     for f = flds;
0120         tmp.(f{1}) = fmdl.(f{1});
0121     end
0122     cache_obj = {tmp, opt};
0123     
0124 
0125 %-------------------------------------------------------------------------%
0126 % Parse option struct
0127  function opt = parse_opts(fmdl, opt)
0128     if ~isfield(opt, 'imgsz')     
0129         opt.imgsz = [32 32 4]; 
0130     end
0131     if ~isfield(opt, 'square_pixels')
0132         opt.square_pixels = 0;
0133     end
0134     if ~isfield(opt, 'cube_voxels')
0135         opt.cube_voxels = 0;
0136     end
0137     if ~isfield(opt, 'xvec')
0138         opt.xvec = [];
0139     end
0140     if ~isfield(opt, 'yvec')
0141         opt.yvec = [];
0142     end
0143     if ~isfield(opt, 'zvec')
0144         opt.zvec = [];
0145     end
0146     if ~isfield(opt, 'prune_model')
0147         opt.prune_model = true;
0148     end
0149     
0150     [~,~,~,opt] = define_voxels(fmdl, opt);
0151     
0152     if ~isfield(opt, 'do_coarse2fine')
0153         opt.do_coarse2fine = 1;
0154     end
0155     if ~isfield(opt, 'z_depth')
0156         opt.z_depth = inf;
0157     end
0158 
0159 %-------------------------------------------------------------------------%
0160 % Perfom unit tests
0161 function do_unit_test
0162    % Check for convhull errors
0163    vopt.imgsz = [10,10,10];
0164    imdl = mk_common_model('n3r2',[16,2]);
0165    [img.fwd_model,cmdl] = mk_voxel_volume(imdl.fwd_model,vopt);
0166    unit_test_cmp('Simple',cmdl.elems(3,:),[64,65,96,33]);
0167 
0168 
0169 fmdl = mk_library_model('adult_male_16el');
0170 % fmdl= ng_mk_cyl_models([2,2,.4],[16,1],[.1,0,.025]);
0171 opt.square_pixels = 1;
0172 [rmdl, fmdl] = mk_voxel_volume(fmdl, opt);
0173 
0174 
0175 subplot(121)
0176 rimg = mk_image(rmdl,0);
0177 rimg.elem_data = zeros(size(rmdl.coarse2fine,2),1);
0178 idx = round(rand(5,1)* length(rimg.elem_data));
0179 rimg.elem_data(idx) = 1;
0180 show_fem(rimg);
0181 
0182 subplot(122)
0183 img = mk_image(fmdl,0);
0184 img.elem_data = fmdl.coarse2fine * rimg.elem_data;
0185 img.calc_colours.ref_level = 0;
0186 img.calc_colours.transparency_thresh = 1e-2;
0187 
0188 show_fem(img);
0189 
0190 
0191 
0192 
0193

Generated on Sun 29-Dec-2024 11:41:59 by m2html © 2005