0001 function [V, rimg] = calc_voxels(img, opt, level)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 if ischar(img) && strcmp(img, 'UNIT_TEST'), do_unit_test; return, end
0056
0057 if nargin < 2
0058 opt = struct();
0059 end
0060
0061 if ~isfield(opt, 'method')
0062 opt.method = 'centre';
0063 end
0064
0065 img = data_mapper(img);
0066
0067 do_rimg = false;
0068
0069 switch opt.method
0070 case 'centre'
0071 do_c2f = false;
0072 case 'average'
0073 do_rimg = true;
0074 do_c2f = true;
0075 otherwise
0076 error('EIDORS:WrongInput', 'Method must be centre or average.');
0077 end
0078
0079 if isfield(img, 'node_data') && strcmp(opt.method, 'average')
0080 error('Only the centre method can be used with node data.');
0081 end
0082
0083 if nargout > 1
0084 do_rimg = true;
0085 end
0086
0087 if nargin > 2
0088 img.fwd_model = level_model_slice(img.fwd_model, level);
0089 end
0090
0091 [~, ~, ~, opt] = define_voxels(img.fwd_model, opt);
0092
0093 if do_c2f
0094 rmdl = mk_grid_model([],opt.xvec,opt.yvec,opt.zvec);
0095 c2f = mk_grid_c2f(img.fwd_model, rmdl, opt);
0096 fvol = get_elem_volume(img.fwd_model,'no_c2f');
0097
0098 f2c = bsxfun(@times, c2f, fvol)';
0099
0100 f2c = spdiag(1./sum(f2c,2)) * f2c;
0101 rimg = mk_image(rmdl,f2c*img.elem_data);
0102 V = calc_grid_points(rimg, opt.x_pts, opt.y_pts, opt.z_pts);
0103 else
0104 V = calc_grid_points(img, opt.x_pts, opt.y_pts, opt.z_pts);
0105 if do_rimg
0106 rmdl = mk_grid_model([],opt.xvec,opt.yvec,opt.zvec);
0107 num_elems = size(rmdl.coarse2fine,2);
0108 rimg = mk_image(rmdl, reshape(V,num_elems,[]));
0109 end
0110 end
0111
0112 V = permute(V, [2 1 3 4]);
0113
0114 function do_unit_test
0115 do_cases
0116 do_example
0117
0118 function do_cases
0119
0120 imdl= mk_common_model('n3r2',[16,2]);
0121 fmdl = imdl.fwd_model;
0122
0123 obj01 = [390,391,393,396,402,478,479,480,484,486, ...
0124 664,665,666,667,668,670,671,672,676,677, ...
0125 678,755,760,761];
0126 obj02 = [318,319,321,324,330,439,440,441,445,447, ...
0127 592,593,594,595,596,598,599,600,604,605, ...
0128 606,716,721,722];
0129
0130 test = 1;
0131 while 1
0132 img = mk_image(fmdl, 1);
0133 opt = struct;
0134 error_expected = false;
0135 switch test
0136 case 1
0137 opt.imgsz = [32 32 32];
0138 opt.cube_voxels = 1;
0139 img.elem_data(obj01) = 1.15;
0140 img.elem_data(obj02) = 0.8;
0141 expect_out = [22 22 32];
0142 case 2
0143 opt.imgsz = [32 32 32];
0144 opt.cube_voxels = 1;
0145 img.elem_data(:,2) = img.elem_data;
0146 img.elem_data(obj01,1) = 1.15;
0147 img.elem_data(obj02,2) = 0.8;
0148 expect_out = [22 22 32 2];
0149 case 3
0150 opt.imgsz = [32 32 32];
0151 opt.cube_voxels = 1;
0152 img.elem_data(:,2) = img.elem_data;
0153 img.elem_data(obj01,1) = 1.15;
0154 img.elem_data(obj02,2) = 0.8;
0155 opt.method = 'average';
0156 expect_out = [22 22 32 2];
0157 case 4
0158 opt.imgsz = [32 32 32];
0159 opt.cube_voxels = 1;
0160 img = mk_image(fmdl, 1:num_nodes(fmdl));
0161 expect_out = [22 22 32];
0162 case 5
0163 opt.imgsz = [32 32 32];
0164 opt.cube_voxels = 1;
0165 img = mk_image(fmdl, 1:num_nodes(fmdl));
0166 opt.method = 'average';
0167 error_expected = true;
0168 case 6
0169 img.elem_data(obj01) = 1.15;
0170 img.elem_data(obj02) = 0.8;
0171 expect_out = [22 22 32];
0172 otherwise
0173 break
0174 end
0175 test_txt = sprintf('calc_voxels T#%2d:', test);
0176 try
0177 [V, rimg] = calc_voxels(img, opt);
0178 unit_test_cmp(test_txt, size(V), expect_out);
0179
0180 catch e
0181 if error_expected
0182 unit_test_cmp([test_txt, ' expected error'], error_expected,true);
0183 else
0184 fprintf('Test #%2d: error\n', test);
0185 end
0186 end
0187
0188 show_test(img, V, rimg)
0189 test = test + 1;
0190 end
0191
0192
0193 function show_test(img, V, rimg)
0194 s = warning('query','EIDORS:FirstImageOnly');
0195 warning('off','EIDORS:FirstImageOnly');
0196 try
0197 clf
0198 subplot(131)
0199 show_fem(img)
0200 subplot(132)
0201 show_fem(rimg)
0202 subplot(133)
0203 show_slices(V)
0204 catch e
0205 warning(s, 'EIDORS:FirstImageOnly');
0206 rethrow(e)
0207 end
0208
0209 function do_example
0210 fmdl = ng_mk_ellip_models([1,1.5,0.8,0.1],[],[]);
0211 fmdl.nodes(:,3) = fmdl.nodes(:,3) - .25;
0212 fmdl = fix_model(fmdl, struct('elem_centre',true));
0213 img = mk_image(fmdl, prod(fmdl.elem_centre,2));
0214 [V, rimg] = calc_voxels(img);
0215 subplot(221), show_fem(img)
0216 subplot(222), show_fem(rimg);
0217 subplot(223), show_slices(rimg,3);
0218 subplot(224), show_slices(V);