diff options
author | Willem Jan Palenstijn <WillemJan.Palenstijn@uantwerpen.be> | 2013-07-01 22:34:11 +0000 |
---|---|---|
committer | wpalenst <WillemJan.Palenstijn@uantwerpen.be> | 2013-07-01 22:34:11 +0000 |
commit | b2fc6c70434674d74551c3a6c01ffb3233499312 (patch) | |
tree | b17f080ebc504ab85ebb7c3d89f917fd87ce9e00 /matlab | |
download | astra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.gz astra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.bz2 astra-b2fc6c70434674d74551c3a6c01ffb3233499312.tar.xz astra-b2fc6c70434674d74551c3a6c01ffb3233499312.zip |
Update version to 1.3
Diffstat (limited to 'matlab')
85 files changed, 13354 insertions, 0 deletions
diff --git a/matlab/algorithms/DART/DARTalgorithm.m b/matlab/algorithms/DART/DARTalgorithm.m new file mode 100644 index 0000000..b7e63b5 --- /dev/null +++ b/matlab/algorithms/DART/DARTalgorithm.m @@ -0,0 +1,229 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef DARTalgorithm < matlab.mixin.Copyable + + % Algorithm class for Discrete Algebraic Reconstruction Technique (DART). + + % todo: reset() + % todo: fixed random seed + % todo: initialize from settings (?) + + %---------------------------------------------------------------------- + properties (GetAccess=public, SetAccess=public) + + tomography = TomographyDefault(); % POLICY: Tomography object. + segmentation = SegmentationDefault(); % POLICY: Segmentation object. + smoothing = SmoothingDefault(); % POLICY: Smoothing object. + masking = MaskingDefault(); % POLICY: Masking object. + output = OutputDefault(); % POLICY: Output object. + statistics = StatisticsDefault(); % POLICY: Statistics object. + + base = struct(); % DATA(set): base structure, should contain: 'sinogram', 'proj_geom', 'phantom' (optional). + + memory = 'yes'; % SETTING: reduce memory usage? (disables some features) + + testdata = struct(); + + end + %---------------------------------------------------------------------- + properties (GetAccess=public, SetAccess=private) + V0 = []; % DATA(get): Initial reconstruction. + V = []; % DATA(get): Reconstruction. + S = []; % DATA(get): Segmentation. + R = []; % DATA(get): Residual projection data. + Mask = []; % DATA(get): Reconstruction Mask. + stats = struct(); % Structure containing various statistics. + iterationcount = 0; % Number of performed iterations. + start_tic = 0; + initialized = 0; % Is initialized? + end + %---------------------------------------------------------------------- + properties (Access=private) + adaptparam_name = {}; + adaptparam_values = {}; + adaptparam_iters = {}; + end + + %---------------------------------------------------------------------- + methods + + %------------------------------------------------------------------ + function this = DARTalgorithm(base) + % Constructor + % >> D = DARTalgorithm(base); base is a matlab struct (or the path towards one) + % that should contain 'sinogram', 'proj_geom'. + + if ischar(base) + this.base = load(base); + else + this.base = base; + end + end + + + %------------------------------------------------------------------ + function D = deepcopy(this) + % Create a deep copy of this object. + % >> D2 = D.deepcopy(); + + D = copy(this); + props = properties(this); + for i = 1:length(props) + if isa(this.(props{i}), 'handle') + D.(props{i}) = copy(this.(props{i})); + end + end + + end + + %------------------------------------------------------------------ + function this = initialize(this) + % Initializes this object. + % >> D.initialize(); + + % Initialize tomography part + this.tomography.initialize(this); + + % Create an Initial Reconstruction + if isfield(this.base, 'V0') + this.V0 = this.base.V0; + else + this.output.pre_initial_iteration(this); + this.V0 = this.tomography.createInitialReconstruction(this, this.base.sinogram); + this.output.post_initial_iteration(this); + end + this.V = this.V0; + if strcmp(this.memory,'yes') + this.base.V0 = []; + this.V0 = []; + end + this.initialized = 1; + end + + %------------------------------------------------------------------ + % iterate + function this = iterate(this, iters) + % Perform several iterations of the DART algorithm. + % >> D.iterate(iterations); + + this.start_tic = tic; + + for iteration = 1:iters + + this.iterationcount = this.iterationcount + 1; + + %---------------------------------------------------------- + % Initial Output + this.output.pre_iteration(this); + + %---------------------------------------------------------- + % Update Adaptive Parameters + for i = 1:numel(this.adaptparam_name) + + for j = 1:numel(this.adaptparam_iters{i}) + if this.iterationcount == this.adaptparam_iters{i}(j) + new_value = this.adaptparam_values{i}(j); + eval(['this.' this.adaptparam_name{i} ' = ' num2str(new_value) ';']); + disp(['value ' this.adaptparam_name{i} ' changed to ' num2str(new_value) ]); + end + end + + end + + %---------------------------------------------------------- + % Segmentation + this.segmentation.estimate_grey_levels(this, this.V); + this.S = this.segmentation.apply(this, this.V); + + %---------------------------------------------------------- + % Select Update and Fixed Pixels + this.Mask = this.masking.apply(this, this.S); + + this.V = (this.V .* this.Mask) + (this.S .* (1 - this.Mask)); + %this.V(this.Mask == 0) = this.S(this.Mask == 0); + + F = this.V; + F(this.Mask == 1) = 0; + + %---------------------------------------------------------- + % Create Residual Projection Difference + %this.testdata.F{iteration} = F; + this.R = this.base.sinogram - this.tomography.createForwardProjection(this, F); + %this.testdata.R{iteration} = this.R; + + %---------------------------------------------------------- + % ART Loose Part + %this.testdata.V1{iteration} = this.V; + %this.testdata.Mask{iteration} = this.Mask; + + %X = zeros(size(this.V)); + %Y = this.tomography.createReconstruction(this, this.R, X, this.Mask); + %this.V(this.Mask) = Y(this.Mask); + this.V = this.tomography.createReconstruction(this, this.R, this.V, this.Mask); + + %this.testdata.V2{iteration} = this.V; + + %---------------------------------------------------------- + % Blur + this.V = this.smoothing.apply(this, this.V); + %this.testdata.V3{iteration} = this.V; + + %---------------------------------------------------------- + % Calculate Statistics + this.stats = this.statistics.apply(this); + + %---------------------------------------------------------- + % Output + this.output.post_iteration(this); + + end % end iteration loop + + %test = this.testdata; + %save('testdata.mat','test'); + + end + + %------------------------------------------------------------------ + % get data + function data = getdata(this, string) + if numel(this.(string)) == 1 + data = astra_mex_data2d('get',this.(string)); + else + data = this.(string); + end + end + + %------------------------------------------------------------------ + % add adaptive parameter + function this = adaptiveparameter(this, name, values, iterations) + this.adaptparam_name{end+1} = name; + this.adaptparam_values{end+1} = values; + this.adaptparam_iters{end+1} = iterations; + end + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = tomography.getsettings(); + + settings.tomography = this.tomography.getsettings(); + settings.smoothing = this.smoothing.getsettings(); + settings.masking = this.masking.getsettings(); + settings.segmentation = this.segmentation.getsettings(); + end + %------------------------------------------------------------------ + + end % methods + +end % class + + diff --git a/matlab/algorithms/DART/IterativeTomography.m b/matlab/algorithms/DART/IterativeTomography.m new file mode 100644 index 0000000..b30640e --- /dev/null +++ b/matlab/algorithms/DART/IterativeTomography.m @@ -0,0 +1,455 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef IterativeTomography < matlab.mixin.Copyable + + % Algorithm class for 2D Iterative Tomography. + + %---------------------------------------------------------------------- + properties (SetAccess=public, GetAccess=public) + superresolution = 1; % SETTING: Volume upsampling factor. + proj_type = 'linear'; % SETTING: Projector type, only when gpu='no'. + method = 'SIRT_CUDA'; % SETTING: Iterative method (see ASTRA toolbox documentation). + gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'} + gpu_core = 0; % SETTING: Which gpu core to use? Only when gpu='yes'. + inner_circle = 'yes'; % SETTING: Do roi only? {'yes', 'no'} + image_size = []; % SETTING: Overwrite default reconstruction size. Only if no vol_geom is specified. + use_minc = 'no'; % SETTING: Use minimum constraint. {'no', 'yes'} + end + %---------------------------------------------------------------------- + properties (SetAccess=public, GetAccess=public) + sinogram = []; % DATA: Projection data. + proj_geom = []; % DATA: Projection geometry. + V = []; % DATA: Volume data. Also used to set initial estimate (optional). + vol_geom = []; % DATA: Volume geometry. + end + %---------------------------------------------------------------------- + properties (SetAccess=private, GetAccess=public) + initialized = 0; % Is this object initialized? + end + %---------------------------------------------------------------------- + properties (SetAccess=protected, GetAccess=protected) + proj_geom_sr = []; % PROTECTED: geometry of sinogram (with super-resolution) + proj_id = []; % PROTECTED: astra id of projector (when gpu='no') + proj_id_sr = []; % PROTECTED: astra id of super-resolution projector (when gpu='no') + cfg_base = struct(); % PROTECTED: base configuration structure for the reconstruction algorithm. + end + %---------------------------------------------------------------------- + + methods (Access=public) + + %------------------------------------------------------------------ + function this = IterativeTomography(varargin) + % Constructor + % >> tomography = IterativeTomography(); + % >> tomography = IterativeTomography(base); base struct should contain fields 'sinogram' and 'proj_geom'. + % >> tomography = IterativeTomography(base_filename); mat-file should contain 'sinogram' and 'proj_geom'. + % >> tomography = IterativeTomography(proj_geom, vol_geom); + % >> tomography = IterativeTomography(sinogram, proj_geom); + + % Input: IterativeTomography(base) + if nargin == 1 + if ischar(varargin{1}) + this.sinogram = load(varargin{1},'sinogram'); + this.proj_geom = load(varargin{1},'proj_geom'); + else + this.sinogram = varargin{1}.sinogram; + this.proj_geom = varargin{1}.proj_geom; + end + end + % Input: IterativeTomography(proj_geom, vol_geom) + if nargin == 2 && isstruct(varargin{1}) && isstruct(varargin{2}) + this.proj_geom = varargin{1}; + this.vol_geom = varargin{2}; + % Input: IterativeTomography(sinogram, proj_geom) + elseif nargin == 2 + this.sinogram = varargin{1}; + this.proj_geom = varargin{2}; + end + + end + + %------------------------------------------------------------------ + function delete(this) + % Destructor + % >> clear tomography; + if strcmp(this.gpu,'no') && numel(this.proj_id) > 0 + astra_mex_projector('delete', this.proj_id, this.proj_id_sr); + end + end + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = tomography.getsettings(); + settings.superresolution = this.superresolution; + settings.proj_type = this.proj_type; + settings.method = this.method; + settings.gpu = this.gpu; + settings.gpu_core = this.gpu_core; + settings.inner_circle = this.inner_circle; + settings.image_size = this.image_size; + settings.use_minc = this.use_minc; + end + + %------------------------------------------------------------------ + function ok = initialize(this) + % Initialize this object. Returns 1 if succesful. + % >> tomography.initialize(); + + % create projection geometry with super-resolution + this.proj_geom_sr = astra_geom_superresolution(this.proj_geom, this.superresolution); + + % if no volume geometry is specified by the user: create volume geometry + if numel(this.vol_geom) == 0 + if numel(this.image_size) < 2 + this.image_size(1) = this.proj_geom.DetectorCount; + this.image_size(2) = this.proj_geom.DetectorCount; + end + this.vol_geom = astra_create_vol_geom(this.image_size(1) * this.superresolution, this.image_size(2) * this.superresolution, ... + -this.image_size(1)/2, this.image_size(1)/2, -this.image_size(2)/2, this.image_size(2)/2); + else + this.image_size(1) = this.vol_geom.GridRowCount; + this.image_size(2) = this.vol_geom.GridColCount; + end + + % create projector + if strcmp(this.gpu, 'no') + this.proj_id = astra_create_projector(this.proj_type, this.proj_geom, this.vol_geom); + this.proj_id_sr = astra_create_projector(this.proj_type, this.proj_geom_sr, this.vol_geom); + end + + % create reconstruction configuration + this.cfg_base = astra_struct(upper(this.method)); + if strcmp(this.gpu,'no') + this.cfg_base.ProjectorId = this.proj_id; + this.cfg_base.ProjectionGeometry = this.proj_geom; + this.cfg_base.ReconstructionGeometry = this.vol_geom; + this.cfg_base.option.ProjectionOrder = 'random'; + end + this.cfg_base.option.DetectorSuperSampling = this.superresolution; + %this.cfg_base.option.DetectorSuperSampling = 8; + if strcmp(this.gpu,'yes') + this.cfg_base.option.GPUindex = this.gpu_core; + end + this.cfg_base.option.UseMinConstraint = this.use_minc; + + this.initialized = 1; + ok = this.initialized; + end + + %------------------------------------------------------------------ + function P = project(this, volume) + % Compute forward projection. + % Stores sinogram in tomography.sinogram if it is still empty. + % >> P = tomography.project(); projects 'tomography.V'. + % >> P = tomography.project(volume); projects 'volume'. + + if ~this.initialized + this.initialize(); + end + + if nargin == 1 % tomography.project(); + P = this.project_c(this.V); + + elseif nargin == 2 % tomography.project(volume); + P = this.project_c(volume); + end + + % store + if numel(this.sinogram) == 0 + this.sinogram = P; + end + end + + %------------------------------------------------------------------ + function V = reconstruct(this, iterations) + % Compute reconstruction. + % Uses tomography.sinogram + % Initial solution (if available) should be stored in tomography.V + % >> V = tomography.reconstruct(iterations); + + if ~this.initialized + this.initialize(); + end + + this.V = this.reconstruct_c(this.sinogram, this.V, [], iterations); + if strcmp(this.inner_circle,'yes') + this.V = this.selectROI(this.V); + end + V = this.V; + end + + %------------------------------------------------------------------ + function I = reconstructMask(this, mask, iterations) + % Compute reconstruction with mask. + % Uses tomography.sinogram + % Initial solution (if available) should be stored in tomography.V + % >> V = tomography.reconstructMask(mask, iterations); + + if ~this.initialized + this.initialize(); + end + + if strcmp(this.inner_circle,'yes') + mask = this.selectROI(mask); + end + I = this.reconstruct_c(this.sinogram, this.V, mask, iterations); + end + %------------------------------------------------------------------ + + end + + %---------------------------------------------------------------------- + methods (Access = protected) + + %------------------------------------------------------------------ + % Protected function: create FP + function sinogram = project_c(this, volume) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % data is stored in astra memory + if numel(volume) == 1 + + if strcmp(this.gpu, 'yes') + sinogram_tmp = astra_create_sino_cuda(volume, this.proj_geom_sr, this.vol_geom, this.gpu_core); + else + sinogram_tmp = astra_create_sino(volume, this.proj_id); + end + + % sinogram downsampling + if this.superresolution > 1 + sinogram_data = astra_mex_data2d('get', sinogram_tmp); + astra_mex_data2d('delete', sinogram_tmp); + sinogram_data = downsample_sinogram(sinogram_data, this.superresolution); + %if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + % sinogram = sinogram / this.superresolution; + %end + sinogram = astra_mex_data2d('create','sino', this.proj_geom, sinogram_data); + else + sinogram = sinogram_tmp; + end + + % data is stored in matlab memory + else + + % 2D and 3D slice by slice + sinogram_tmp = zeros([astra_geom_size(this.proj_geom_sr), size(volume,3)]); + sinogram_tmp2 = zeros([astra_geom_size(this.proj_geom), size(volume,3)]); + for slice = 1:size(volume,3) + + if strcmp(this.gpu, 'yes') + [tmp_id, sinogram_tmp2(:,:,slice)] = astra_create_sino_sampling(volume(:,:,slice), this.proj_geom, this.vol_geom, this.gpu_core, this.superresolution); + astra_mex_data2d('delete', tmp_id); + else + [tmp_id, tmp] = astra_create_sino(volume(:,:,slice), this.proj_id_sr); + sinogram_tmp2(:,:,slice) = downsample_sinogram(tmp, this.superresolution) * (this.superresolution^2); + astra_mex_data2d('delete', tmp_id); + end + + end + + % sinogram downsampling + if strcmp(this.gpu, 'yes') + %sinogram = downsample_sinogram(sinogram_tmp, this.superresolution); + sinogram2 = sinogram_tmp2; + if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + sinogram2 = sinogram2 / this.superresolution; + elseif strcmp(this.proj_geom.type,'parallel') + sinogram2 = sinogram2 / (this.superresolution * this.superresolution); + end + sinogram = sinogram2; + else + sinogram = sinogram_tmp2; + end + + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct + function V = reconstruct_c(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % data is stored in astra memory + if numel(sinogram) == 1 + V = this.reconstruct_c_astra(sinogram, V0, mask, iterations); + + % data is stored in matlab memory + else + V = this.reconstruct_c_matlab(sinogram, V0, mask, iterations); + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct (data in matlab) + function V = reconstruct_c_matlab(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % parse method + method2 = upper(this.method); + if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA') + iterations = iterations * size(sinogram,1); + elseif strcmp(method2, 'ART') + iterations = iterations * numel(sinogram); + end + + % create data objects + V = zeros(this.vol_geom.GridRowCount, this.vol_geom.GridColCount, size(sinogram,3)); + reconstruction_id = astra_mex_data2d('create', '-vol', this.vol_geom); + sinogram_id = astra_mex_data2d('create', '-sino', this.proj_geom); + if numel(mask) > 0 + mask_id = astra_mex_data2d('create', '-vol', this.vol_geom); + end + + % algorithm configuration + cfg = this.cfg_base; + cfg.ProjectionDataId = sinogram_id; + cfg.ReconstructionDataId = reconstruction_id; + if numel(mask) > 0 + cfg.option.ReconstructionMaskId = mask_id; + end + alg_id = astra_mex_algorithm('create', cfg); + + % loop slices + for slice = 1:size(sinogram,3) + + % fetch slice of initial reconstruction + if numel(V0) > 0 + astra_mex_data2d('store', reconstruction_id, V0(:,:,slice)); + else + astra_mex_data2d('store', reconstruction_id, 0); + end + + % fetch slice of sinogram + astra_mex_data2d('store', sinogram_id, sinogram(:,:,slice)); + + % fecth slice of mask + if numel(mask) > 0 + astra_mex_data2d('store', mask_id, mask(:,:,slice)); + end + + % iterate + astra_mex_algorithm('iterate', alg_id, iterations); + + % fetch data + V(:,:,slice) = astra_mex_data2d('get', reconstruction_id); + + end + + % correct attenuation factors for super-resolution + if this.superresolution > 1 && strcmp(this.gpu,'yes') + if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + if numel(mask) > 0 + V(mask > 0) = V(mask > 0) ./ this.superresolution; + else + V = V ./ this.superresolution; + end + end + end + + % garbage collection + astra_mex_algorithm('delete', alg_id); + astra_mex_data2d('delete', sinogram_id, reconstruction_id); + if numel(mask) > 0 + astra_mex_data2d('delete', mask_id); + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct (data in astra) + function V = reconstruct_c_astra(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + if numel(V0) > 1 || numel(mask) > 1 || numel(sinogram) > 1 + error('Not all required data is stored in the astra memory'); + end + + if numel(V0) == 0 + V0 = astra_mex_data2d('create', '-vol', this.vol_geom, 0); + end + + % parse method + method2 = upper(this.method); + if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA') + iterations = iterations * astra_geom_size(this.proj_geom, 1); + elseif strcmp(method2, 'ART') + s = astra_geom_size(this.proj_geom); + iterations = iterations * s(1) * s(2); + end + + % algorithm configuration + cfg = this.cfg_base; + cfg.ProjectionDataId = sinogram; + cfg.ReconstructionDataId = V0; + if numel(mask) > 0 + cfg.option.ReconstructionMaskId = mask; + end + alg_id = astra_mex_algorithm('create', cfg); + + % iterate + astra_mex_algorithm('iterate', alg_id, iterations); + + % fetch data + V = V0; + + % correct attenuation factors for super-resolution + if this.superresolution > 1 + if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + if numel(mask) > 0 + astra_data_op_masked('$1./s1', [V V], [this.superresolution this.superresolution], mask, this.gpu_core); + else + astra_data_op('$1./s1', [V V], [this.superresolution this.superresolution], this.gpu_core); + end + end + end + + % garbage collection + astra_mex_algorithm('delete', alg_id); + + end + + %------------------------------------------------------------------ + function V_out = selectROI(~, V_in) + + if numel(V_in) == 1 + cfg = astra_struct('RoiSelect_CUDA'); + cfg.DataId = V_in; + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('run', alg_id); + astra_mex_algorithm('delete', alg_id); + V_out = V_in; + else + V_out = ROIselectfull(V_in, min([size(V_in,1), size(V_in,2)])); + end + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/IterativeTomography3D.m b/matlab/algorithms/DART/IterativeTomography3D.m new file mode 100644 index 0000000..3f89457 --- /dev/null +++ b/matlab/algorithms/DART/IterativeTomography3D.m @@ -0,0 +1,433 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef IterativeTomography3D < matlab.mixin.Copyable + + % Algorithm class for 3D Iterative Tomography. + + %---------------------------------------------------------------------- + properties (SetAccess=public, GetAccess=public) + superresolution = 1; % SETTING: Volume upsampling factor. + proj_type = 'linear'; % SETTING: Projector type, only when gpu='no'. + method = 'SIRT3D_CUDA'; % SETTING: Iterative method (see ASTRA toolbox documentation). + gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'} + gpu_core = 0; % SETTING: Which gpu core to use? Only when gpu='yes'. + inner_circle = 'yes'; % SETTING: Do roi only? {'yes', 'no'} + image_size = []; % SETTING: Overwrite default reconstruction size. Only if no vol_geom is specified. + use_minc = 'no'; % SETTING: Use minimum constraint. {'no', 'yes'} + maxc = +Inf; % SETTING: Maximum constraint. +Inf means off. + end + %---------------------------------------------------------------------- + properties (SetAccess=public, GetAccess=public) + sinogram = []; % DATA: Projection data. + proj_geom = []; % DATA: Projection geometry. + V = []; % DATA: Volume data. Also used to set initial estimate (optional). + vol_geom = []; % DATA: Volume geometry. + end + %---------------------------------------------------------------------- + properties (SetAccess=private, GetAccess=public) + initialized = 0; % Is this object initialized? + end + %---------------------------------------------------------------------- + properties (SetAccess=protected, GetAccess=protected) + proj_geom_sr = []; % PROTECTED: geometry of sinogram (with super-resolution) + proj_id = []; % PROTECTED: astra id of projector (when gpu='no') + proj_id_sr = []; % PROTECTED: astra id of super-resolution projector (when gpu='no') + cfg_base = struct(); % PROTECTED: base configuration structure for the reconstruction algorithm. + end + %---------------------------------------------------------------------- + + methods (Access=public) + + %------------------------------------------------------------------ + function this = IterativeTomography(varargin) + % Constructor + % >> tomography = IterativeTomography(); + % >> tomography = IterativeTomography(base); base struct should contain fields 'sinogram' and 'proj_geom'. + % >> tomography = IterativeTomography(base_filename); mat-file should contain 'sinogram' and 'proj_geom'. + % >> tomography = IterativeTomography(proj_geom, vol_geom); + % >> tomography = IterativeTomography(sinogram, proj_geom); + + % Input: IterativeTomography(base) + if nargin == 1 + if ischar(varargin{1}) + this.sinogram = load(varargin{1},'sinogram'); + this.proj_geom = load(varargin{1},'proj_geom'); + else + this.sinogram = varargin{1}.sinogram; + this.proj_geom = varargin{1}.proj_geom; + end + end + % Input: IterativeTomography(proj_geom, vol_geom) + if nargin == 2 && isstruct(varargin{1}) && isstruct(varargin{2}) + this.proj_geom = varargin{1}; + this.vol_geom = varargin{2}; + % Input: IterativeTomography(sinogram, proj_geom) + elseif nargin == 2 + this.sinogram = varargin{1}; + this.proj_geom = varargin{2}; + end + + end + + %------------------------------------------------------------------ + function delete(this) + % Destructor + % >> clear tomography; + if strcmp(this.gpu,'no') && numel(this.proj_id) > 0 + astra_mex_projector('delete', this.proj_id, this.proj_id_sr); + end + end + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = tomography.getsettings(); + settings.superresolution = this.superresolution; + settings.proj_type = this.proj_type; + settings.method = this.method; + settings.gpu = this.gpu; + settings.gpu_core = this.gpu_core; + settings.inner_circle = this.inner_circle; + settings.image_size = this.image_size; + settings.use_minc = this.use_minc; + settings.maxc = this.maxc; + end + + %------------------------------------------------------------------ + function ok = initialize(this) + % Initialize this object. Returns 1 if succesful. + % >> tomography.initialize(); + +% % create projection geometry with super-resolution +% this.proj_geom_sr = astra_geom_superresolution(this.proj_geom, this.superresolution); + + % if no volume geometry is specified by the user: create volume geometry + if numel(this.vol_geom) == 0 + if numel(this.image_size) < 2 + this.image_size(1) = this.proj_geom.DetectorRowCount; + this.image_size(2) = this.proj_geom.DetectorColCount; + end + this.vol_geom = astra_create_vol_geom(this.proj_geom.DetectorColCount, this.proj_geom.DetectorColCount, this.proj_geom.DetectorRowCount); + else + this.image_size(1) = this.vol_geom.GridRowCount; + this.image_size(2) = this.vol_geom.GridColCount; + end + + % create projector + if strcmp(this.gpu, 'no') + this.proj_id = astra_create_projector(this.proj_type, this.proj_geom, this.vol_geom); + this.proj_id_sr = astra_create_projector(this.proj_type, this.proj_geom_sr, this.vol_geom); + end + + % create reconstruction configuration + this.cfg_base = astra_struct(upper(this.method)); + if strcmp(this.gpu,'no') + this.cfg_base.ProjectorId = this.proj_id; + this.cfg_base.ProjectionGeometry = this.proj_geom; + this.cfg_base.ReconstructionGeometry = this.vol_geom; + this.cfg_base.option.ProjectionOrder = 'random'; + end + this.cfg_base.option.DetectorSuperSampling = this.superresolution; + %this.cfg_base.option.DetectorSuperSampling = 8; + if strcmp(this.gpu,'yes') + this.cfg_base.option.GPUindex = this.gpu_core; + end + this.cfg_base.option.UseMinConstraint = this.use_minc; + if ~isinf(this.maxc) + this.cfg_base.option.UseMaxConstraint = 'yes'; + this.cfg_base.option.MaxConstraintValue = this.maxc; + end + + this.initialized = 1; + ok = this.initialized; + end + + %------------------------------------------------------------------ + function P = project(this, volume) + % Compute forward projection. + % Stores sinogram in tomography.sinogram if it is still empty. + % >> P = tomography.project(); projects 'tomography.V'. + % >> P = tomography.project(volume); projects 'volume'. + + if ~this.initialized + this.initialize(); + end + + if nargin == 1 % tomography.project(); + P = this.project_c(this.V); + + elseif nargin == 2 % tomography.project(volume); + P = this.project_c(volume); + end + + % store + if numel(this.sinogram) == 0 + this.sinogram = P; + end + end + + %------------------------------------------------------------------ + function V = reconstruct(this, iterations) + % Compute reconstruction. + % Uses tomography.sinogram + % Initial solution (if available) should be stored in tomography.V + % >> V = tomography.reconstruct(iterations); + + if ~this.initialized + this.initialize(); + end + + this.V = this.reconstruct_c(this.sinogram, this.V, [], iterations); + if strcmp(this.inner_circle,'yes') + this.V = this.selectROI(this.V); + end + V = this.V; + end + + %------------------------------------------------------------------ + function I = reconstructMask(this, mask, iterations) + % Compute reconstruction with mask. + % Uses tomography.sinogram + % Initial solution (if available) should be stored in tomography.V + % >> V = tomography.reconstructMask(mask, iterations); + + if ~this.initialized + this.initialize(); + end + + if strcmp(this.inner_circle,'yes') + mask = this.selectROI(mask); + end + I = this.reconstruct_c(this.sinogram, this.V, mask, iterations); + end + %------------------------------------------------------------------ + + end + + %---------------------------------------------------------------------- + methods (Access = protected) + + %------------------------------------------------------------------ + % Protected function: create FP + function sinogram = project_c(this, volume) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % data is stored in astra memory + if numel(volume) == 1 + + if strcmp(this.gpu, 'yes') + sinogram_tmp = astra_create_sino_cuda(volume, this.proj_geom_sr, this.vol_geom, this.gpu_core); + else + sinogram_tmp = astra_create_sino(volume, this.proj_id); + end + + % sinogram downsampling + if this.superresolution > 1 + sinogram_data = astra_mex_data2d('get', sinogram_tmp); + astra_mex_data2d('delete', sinogram_tmp); + sinogram_data = downsample_sinogram(sinogram_data, this.superresolution); + %if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + % sinogram = sinogram / this.superresolution; + %end + sinogram = astra_mex_data2d('create','sino', this.proj_geom, sinogram_data); + else + sinogram = sinogram_tmp; + end + + % data is stored in matlab memory + else + + [tmp_id, sinogram] = astra_create_sino3d_cuda(volume, this.proj_geom, this.vol_geom); + astra_mex_data3d('delete', tmp_id); + + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct + function V = reconstruct_c(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % data is stored in astra memory + if numel(sinogram) == 1 + V = this.reconstruct_c_astra(sinogram, V0, mask, iterations); + + % data is stored in matlab memory + else + V = this.reconstruct_c_matlab(sinogram, V0, mask, iterations); + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct (data in matlab) + function V = reconstruct_c_matlab(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + % parse method + method2 = upper(this.method); + if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA') + iterations = iterations * size(sinogram,1); + elseif strcmp(method2, 'ART') + iterations = iterations * numel(sinogram); + end + + % create data objects +% V = zeros(this.vol_geom.GridRowCount, this.vol_geom.GridColCount, size(sinogram,3)); + reconstruction_id = astra_mex_data3d('create', '-vol', this.vol_geom); + sinogram_id = astra_mex_data3d('create', '-proj3d', this.proj_geom); + if numel(mask) > 0 + mask_id = astra_mex_data3d('create', '-vol', this.vol_geom); + end + + % algorithm configuration + cfg = this.cfg_base; + cfg.ProjectionDataId = sinogram_id; + cfg.ReconstructionDataId = reconstruction_id; + if numel(mask) > 0 + cfg.option.ReconstructionMaskId = mask_id; + end + alg_id = astra_mex_algorithm('create', cfg); + +% % loop slices +% for slice = 1:size(sinogram,3) + + % fetch slice of initial reconstruction + if numel(V0) > 0 + astra_mex_data3d('store', reconstruction_id, V0); + else + astra_mex_data3d('store', reconstruction_id, 0); + end + + % fetch slice of sinogram + astra_mex_data3d('store', sinogram_id, sinogram); + + % fecth slice of mask + if numel(mask) > 0 + astra_mex_data3d('store', mask_id, mask); + end + + % iterate + astra_mex_algorithm('iterate', alg_id, iterations); + + % fetch data + V = astra_mex_data3d('get', reconstruction_id); + +% end + + % correct attenuation factors for super-resolution + if this.superresolution > 1 && strcmp(this.gpu,'yes') + if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + if numel(mask) > 0 + V(mask > 0) = V(mask > 0) ./ this.superresolution; + else + V = V ./ this.superresolution; + end + end + end + + % garbage collection + astra_mex_algorithm('delete', alg_id); + astra_mex_data3d('delete', sinogram_id, reconstruction_id); + if numel(mask) > 0 + astra_mex_data3d('delete', mask_id); + end + + end + + %------------------------------------------------------------------ + % Protected function: reconstruct (data in astra) + function V = reconstruct_c_astra(this, sinogram, V0, mask, iterations) + + if this.initialized == 0 + error('IterativeTomography not initialized'); + end + + if numel(V0) > 1 || numel(mask) > 1 || numel(sinogram) > 1 + error('Not all required data is stored in the astra memory'); + end + + if numel(V0) == 0 + V0 = astra_mex_data2d('create', '-vol', this.vol_geom, 0); + end + + % parse method + method2 = upper(this.method); + if strcmp(method2, 'SART') || strcmp(method2, 'SART_CUDA') + iterations = iterations * astra_geom_size(this.proj_geom, 1); + elseif strcmp(method2, 'ART') + s = astra_geom_size(this.proj_geom); + iterations = iterations * s(1) * s(2); + end + + % algorithm configuration + cfg = this.cfg_base; + cfg.ProjectionDataId = sinogram; + cfg.ReconstructionDataId = V0; + if numel(mask) > 0 + cfg.option.ReconstructionMaskId = mask; + end + alg_id = astra_mex_algorithm('create', cfg); + + % iterate + astra_mex_algorithm('iterate', alg_id, iterations); + + % fetch data + V = V0; + + % correct attenuation factors for super-resolution + if this.superresolution > 1 + if strcmp(this.proj_geom.type,'fanflat_vec') || strcmp(this.proj_geom.type,'fanflat') + if numel(mask) > 0 + astra_data_op_masked('$1./s1', [V V], [this.superresolution this.superresolution], mask, this.gpu_core); + else + astra_data_op('$1./s1', [V V], [this.superresolution this.superresolution], this.gpu_core); + end + end + end + + % garbage collection + astra_mex_algorithm('delete', alg_id); + + end + + %------------------------------------------------------------------ + function V_out = selectROI(~, V_in) + + if numel(V_in) == 1 + cfg = astra_struct('RoiSelect_CUDA'); + cfg.DataId = V_in; + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('run', alg_id); + astra_mex_algorithm('delete', alg_id); + V_out = V_in; + else + V_out = ROIselectfull(V_in, min([size(V_in,1), size(V_in,2)])); + end + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/Kernels.m b/matlab/algorithms/DART/Kernels.m new file mode 100644 index 0000000..b5e3134 --- /dev/null +++ b/matlab/algorithms/DART/Kernels.m @@ -0,0 +1,68 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef Kernels + %KERNELS Summary of this class goes here + % Detailed explanation goes here + + properties + + end + + methods(Static) + + function K = BinaryPixelKernel(radius, conn) + + if nargin < 2 + conn = 8; + end + + % 2D, 4conn + if conn == 4 + K = [0 1 0; 1 1 1; 0 1 0]; + for i = 2:radius + K = conv2(K,K); + end + K = double(K >= 1); + + % 2D, 8conn + elseif conn == 8 + K = ones(2*radius+1, 2*radius+1); + + % 3D, 6conn + elseif conn == 6 + K = zeros(3,3,3); + K(:,:,1) = [0 0 0; 0 1 0; 0 0 0]; + K(:,:,2) = [0 1 0; 1 1 1; 0 1 0]; + K(:,:,3) = [0 0 0; 0 1 0; 0 0 0]; + for i = 2:radius + K = convn(K,K); + end + K = double(K >= 1); + + % 2D, 27conn + elseif conn == 26 + K = ones(2*radius+1, 2*radius+1, 2*radius+1); + + else + disp('Invalid conn') + end + end + + + + + + + end + +end + diff --git a/matlab/algorithms/DART/MaskingDefault.m b/matlab/algorithms/DART/MaskingDefault.m new file mode 100644 index 0000000..6bd25a5 --- /dev/null +++ b/matlab/algorithms/DART/MaskingDefault.m @@ -0,0 +1,212 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef MaskingDefault < matlab.mixin.Copyable + + % Default policy class for masking for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + + radius = 1; % SETTING: Radius of masking kernel. + conn = 8; % SETTING: Connectivity window. For 2D: 4 or 8. For 3D: 6 or 26. + edge_threshold = 1; % SETTING: Number of pixels in the window that should be different. + random = 0.1; % SETTING: Percentage of random points. Between 0 and 1. + gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'} + gpu_core = 0; % SETTING: Which gpu core to use, only when gpu='yes'. + + end + + %---------------------------------------------------------------------- + methods (Access=public) + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.masking.getsettings(); + settings.radius = this.radius; + settings.conn = this.conn; + settings.edge_threshold = this.edge_threshold; + settings.random = this.random; + end + + %------------------------------------------------------------------ + function Mask = apply(this, ~, S) + % Applies masking. + % >> Mask = DART.segmentation.apply(DART, S); + + % 2D, one slice + if size(S,3) == 1 + if strcmp(this.gpu,'yes') + Mask = this.apply_2D_gpu(S); + else + Mask = this.apply_2D(S); + end + + % 3D, slice by slice + elseif this.conn == 4 || this.conn == 8 + Mask = zeros(size(S)); + for slice = 1:size(S,3) + if strcmp(this.gpu,'yes') + Mask(:,:,slice) = this.apply_2D_gpu(S(:,:,slice)); + else + Mask(:,:,slice) = this.apply_2D(S(:,:,slice)); + end + end + + % 3D, full + else + if strcmp(this.gpu,'yes') + Mask = this.apply_3D_gpu(S); + else + Mask = this.apply_3D(S); + end + end + + end + + end + + %---------------------------------------------------------------------- + methods (Access=protected) + + %------------------------------------------------------------------ + function Mask = apply_2D_gpu(this, S) + + vol_geom = astra_create_vol_geom(size(S)); + data_id = astra_mex_data2d('create', '-vol', vol_geom, S); + mask_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + + cfg = astra_struct('DARTMASK_CUDA'); + cfg.SegmentationDataId = data_id; + cfg.MaskDataId = mask_id; + cfg.option.GPUindex = this.gpu_core; + cfg.option.Connectivity = this.conn; + cfg.option.Threshold = this.edge_threshold; + cfg.option.Radius = this.radius; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate',alg_id,1); + Mask = astra_mex_data2d('get', mask_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data2d('delete', data_id, mask_id); + + % random + RandomField = double(rand(size(S)) < this.random); + + % combine + Mask = or(Mask, RandomField); + + end + + %------------------------------------------------------------------ + function Mask = apply_2D(this, S) + + r = this.radius; + w = 2 * r + 1; + + kernel = Kernels.BinaryPixelKernel(r, this.conn); + + % edges + Xlarge = zeros(size(S,1)+w-1, size(S,2)+w-1); + Xlarge(1+r:end-r, 1+r:end-r) = S; + + Edges = zeros(size(S)); + for s = -r:r + for t = -r:r + if kernel(s+r+1, t+r+1) == 0 + continue + end + Temp = abs(Xlarge(1+r:end-r, 1+r:end-r) - Xlarge(1+r+s:end-r+s, 1+r+t:end-r+t)); + Edges(Temp > eps) = Edges(Temp > eps) + 1; + end + end + + Edges = Edges > this.edge_threshold; + + % random + RandomField = double(rand(size(S)) < this.random); + + % combine + Mask = or(Edges, RandomField); + + end + + %------------------------------------------------------------------ + function Mask = apply_3D(this, S) + + r = this.radius; + w = 2 * r + 1; + + kernel = Kernels.BinaryPixelKernel(r, this.conn); + + % edges + Xlarge = zeros(size(S,1)+w-1, size(S,2)+w-1, size(S,3)+w-1); + Xlarge(1+r:end-r, 1+r:end-r, 1+r:end-r) = S; + + Edges = zeros(size(S)); + for s = -r:r + for t = -r:r + for u = -r:r + if kernel(s+r+1, t+r+1, u+r+1) == 0 + continue + end + Temp = abs(Xlarge(1+r:end-r, 1+r:end-r, 1+r:end-r) - Xlarge(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u)); + Edges(Temp > eps) = 1; + end + end + end + + clear Xlarge; + + % random + RandomField = double(rand(size(S)) < this.random); + + % combine + Mask = or(Edges, RandomField); + + end + + %------------------------------------------------------------------ + function Mask = apply_3D_gpu(this, S) + + vol_geom = astra_create_vol_geom(size(S)); + data_id = astra_mex_data3d('create', '-vol', vol_geom, S); + + cfg = astra_struct('DARTMASK3D_CUDA'); + cfg.SegmentationDataId = data_id; + cfg.MaskDataId = data_id; + cfg.option.GPUindex = this.gpu_core; + cfg.option.Connectivity = this.conn; + cfg.option.Threshold = this.edge_threshold; + cfg.option.Radius = this.radius; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate',alg_id,1); + Mask = astra_mex_data3d('get', data_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data3d('delete', data_id); + + % random + RandomField = double(rand(size(S)) < this.random); + + % combine + Mask = or(Mask, RandomField); + + end + + %------------------------------------------------------------------ + end + +end + diff --git a/matlab/algorithms/DART/MaskingGPU.m b/matlab/algorithms/DART/MaskingGPU.m new file mode 100644 index 0000000..c4ef2b7 --- /dev/null +++ b/matlab/algorithms/DART/MaskingGPU.m @@ -0,0 +1,94 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef MaskingGPU < matlab.mixin.Copyable + + % Policy class for masking for DART with GPU accelerated code (deprecated). + + %---------------------------------------------------------------------- + properties (Access=public) + + radius = 1; % SETTING: Radius of masking kernel. + conn = 8; % SETTING: Connectivity window. For 2D: 4 or 8. For 3D: 6 or 26. + edge_threshold = 1; % SETTING: Number of pixels in the window that should be different. + gpu_core = 0; % SETTING: + random = 0.1; % SETTING: Percentage of random points. Between 0 and 1. + + end + + %---------------------------------------------------------------------- + methods (Access=public) + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.masking.getsettings(); + settings.radius = this.radius; + settings.conn = this.conn; + settings.edge_threshold = this.edge_threshold; + settings.random = this.random; + end + + %------------------------------------------------------------------ + function Mask = apply(this, ~, V_in) + % Applies masking. + % >> Mask = DART.segmentation.apply(DART, V_in); + + % 2D, one slice + if size(V_in,3) == 1 + Mask = this.apply_2D(V_in); + + % 3D, slice by slice + elseif this.conn == 4 || this.conn == 8 + Mask = zeros(size(V_in)); + for slice = 1:size(V_in,3) + Mask(:,:,slice) = this.apply_2D(V_in(:,:,slice)); + end + + % 3D, full + else + error('Full 3D masking on GPU not implemented.') + end + + end + + end + + %---------------------------------------------------------------------- + methods (Access=protected) + + %------------------------------------------------------------------ + function Mask = apply_2D(this, S) + + vol_geom = astra_create_vol_geom(size(S)); + data_id = astra_mex_data2d('create', '-vol', vol_geom, S); + mask_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + + cfg = astra_struct('DARTMASK_CUDA'); + cfg.SegmentationDataId = data_id; + cfg.MaskDataId = mask_id; + cfg.option.GPUindex = this.gpu_core; + %cfg.option.Connectivity = this.conn; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate',alg_id,1); + Mask = astra_mex_data2d('get', mask_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data2d('delete', data_id, mask_id); + + end + end + + + +end + diff --git a/matlab/algorithms/DART/OutputDefault.m b/matlab/algorithms/DART/OutputDefault.m new file mode 100644 index 0000000..a34a430 --- /dev/null +++ b/matlab/algorithms/DART/OutputDefault.m @@ -0,0 +1,173 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef OutputDefault < matlab.mixin.Copyable + + % Default policy class for output for DART. + + properties (Access=public) + + directory = ''; % SETTING: Directory to save output. + pre = ''; % SETTING: Prefix of output. + + save_images = 'no'; % SETTING: Save the images. 'no', 'yes' (='S') OR {'S', 'I', 'Mask', 'P'} + save_results = 'no'; % SETTING: Save the results. 'yes', 'no' OR {'base', 'stats', 'settings', 'S', 'V', 'V0'} + save_object = 'no'; % SETTING: Save the DART object. {'no','yes'} + + save_interval = 1; % SETTING: # DART iteration between saves. + save_images_interval = []; % SETTING: Overwrite interval for save_images. + save_results_interval = []; % SETTING: Overwrite interval for save_results. + save_object_interval = []; % SETTING: Overwrite interval for save_object. + + slices = 1; % SETTING: In case of 3D, which slices to save? + + verbose = 'no'; % SETTING: Verbose? {'no','yes'} + + end + + methods (Access=public) + + %------------------------------------------------------------------ + function pre_initial_iteration(this, ~) + if strcmp(this.verbose,'yes') + tic + fprintf(1, 'initial iteration...'); + end + end + + %------------------------------------------------------------------ + function post_initial_iteration(this, ~) + if strcmp(this.verbose,'yes') + t = toc; + fprintf(1, 'done in %f s.\n', t); + end + end + + %------------------------------------------------------------------ + function pre_iteration(this, DART) + if strcmp(this.verbose,'yes') + tic; + fprintf(1, '%s dart iteration %d...', this.pre, DART.iterationcount); + end + end + + %------------------------------------------------------------------ + function post_iteration(this, DART) + + % print output + if strcmp(this.verbose,'yes') + t = toc; + s = DART.statistics.tostring(DART.stats); + fprintf(1, 'done in %0.2fs %s.\n', t, s); + end + + % save DART object + if do_object(this, DART) + save(sprintf('%s%sobject_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', 'DART'); + end + + % save .mat + if do_results(this, DART) + base = DART.base; + stats = DART.stats; + S = DART.S; + V = DART.V; + V0 = DART.V0; + settings = DART.getsettings(); + if ~iscell(this.save_results) + save(sprintf('%s%sresults_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', 'base', 'stats', 'S', 'V', 'V0', 'settings'); + else + string = []; + for i = 1:numel(this.save_results) + string = [string this.save_results{i} '|']; + end + save(sprintf('%s%sresults_%i.mat', this.directory, this.pre, DART.iterationcount), '-v7.3', '-regexp', string(1:end-1)); + end + end + + % save images + if do_images(this, DART) + + if ~iscell(this.save_images) && strcmp(this.save_images, 'yes') + output_image(this, DART, 'S') + elseif iscell(this.save_images) + for i = 1:numel(this.save_images) + output_image(this, DART, this.save_images{i}); + end + end + + end + + end + %------------------------------------------------------------------ + + end + + %---------------------------------------------------------------------- + methods (Access=private) + + function output_image(this, DART, data) + % 2D + if numel(size(DART.S)) == 2 + eval(['imwritesc(DART.' data ', sprintf(''%s%s' data '_%i.png'', this.directory, this.pre, DART.iterationcount))']); + % 3D + elseif numel(size(DART.S)) == 3 + for slice = this.slices + eval(['imwritesc(DART.' data '(:,:,slice), sprintf(''%s%s' data '_%i_slice%i.png'', this.directory, this.pre, DART.iterationcount, slice))']); + end + end + end + + %------------------------------------------------------------------ + function out = do_object(this, DART) + if strcmp(this.save_object,'no') + out = 0; + return + end + if numel(this.save_object_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0 + out = 1; + elseif mod(DART.iterationcount, this.save_object_interval) == 0 + out = 1; + else + out = 0; + end + end + %------------------------------------------------------------------ + function out = do_results(this, DART) + if strcmp(this.save_results,'no') + out = 0; + return + end + if numel(this.save_results_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0 + out = 1; + elseif mod(DART.iterationcount, this.save_results_interval) == 0 + out = 1; + else + out = 0; + end + end + + %------------------------------------------------------------------ + function out = do_images(this, DART) + if numel(this.save_images_interval) == 0 && mod(DART.iterationcount, this.save_interval) == 0 + out = 1; + elseif mod(DART.iterationcount, this.save_images_interval) == 0 + out = 1; + else + out = 0; + end + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/SegmentationDefault.m b/matlab/algorithms/DART/SegmentationDefault.m new file mode 100644 index 0000000..c1d7d99 --- /dev/null +++ b/matlab/algorithms/DART/SegmentationDefault.m @@ -0,0 +1,55 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef SegmentationDefault < matlab.mixin.Copyable + + % Default policy class for segmentation for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + rho = []; % SETTING: Grey levels. + tau = []; % SETTING: Threshold values. + end + + %---------------------------------------------------------------------- + methods (Access=public) + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.segmentation.getsettings(); + settings.rho = this.rho; + settings.tau = this.tau; + end + + %------------------------------------------------------------------ + function this = estimate_grey_levels(this, ~, ~) + % Estimates grey levels + % >> DART.segmentation.estimate_grey_levels(); + end + + %------------------------------------------------------------------ + function V_out = apply(this, ~, V_in) + % Applies segmentation. + % >> V_out = DART.segmentation.apply(DART, V_in); + + V_out = ones(size(V_in)) * this.rho(1); + for n = 2:length(this.rho) + V_out(this.tau(n-1) < V_in) = this.rho(n); + end + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/SmoothingDefault.m b/matlab/algorithms/DART/SmoothingDefault.m new file mode 100644 index 0000000..58a8baa --- /dev/null +++ b/matlab/algorithms/DART/SmoothingDefault.m @@ -0,0 +1,179 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef SmoothingDefault < matlab.mixin.Copyable + + % Default policy class for smoothing for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + radius = 1; % SETTING: Radius of smoothing kernel. + b = 0.1; % SETTING: Intensity of smoothing. Between 0 and 1. + full3d = 'yes'; % SETTING: smooth in 3D? {'yes','no'} + gpu = 'yes'; % SETTING: Use gpu? {'yes', 'no'} + gpu_core = 0; % SETTING: Which gpu core to use, only when gpu='yes'. + end + + + %---------------------------------------------------------------------- + methods (Access=public) + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.smoothing.getsettings(); + settings.radius = this.radius; + settings.b = this.b; + settings.full3d = this.full3d; + end + + %------------------------------------------------------------------ + function V_out = apply(this, ~, V_in) + % Applies smoothing. + % >> V_out = DART.smoothing.apply(DART, V_in); + + % 2D, one slice + if size(V_in,3) == 1 + if strcmp(this.gpu,'yes') + V_out = this.apply_2D_gpu(V_in); + else + V_out = this.apply_2D(V_in); + end + + % 3D, slice by slice + elseif ~strcmp(this.full3d,'yes') + V_out = zeros(size(V_in)); + for slice = 1:size(V_in,3) + if strcmp(this.gpu,'yes') + V_out(:,:,slice) = this.apply_2D_gpu(V_in(:,:,slice)); + else + V_out(:,:,slice) = this.apply_2D(V_in(:,:,slice)); + end + end + + % 3D, full + else + if strcmp(this.gpu,'yes') + V_out = this.apply_3D_gpu(V_in); + else + V_out = this.apply_3D(V_in); + end + end + + end + + end + + %---------------------------------------------------------------------- + methods (Access=protected) + + %------------------------------------------------------------------ + function V_out = apply_2D(this, V_in) + + r = this.radius; + w = 2 * r + 1; + + % Set Kernel + K = ones(w) * this.b / (w.^2-1); % edges + K(r+1,r+1) = 1 - this.b; % center + + % output window + V_out = zeros(size(V_in,1) + w-1, size(V_in,2) + w - 1); + + % blur convolution + for s = -r:r + for t = -r:r + V_out(1+r+s:end-r+s, 1+r+t:end-r+t) = V_out(1+r+s:end-r+s, 1+r+t:end-r+t) + K(r+1+s, r+1+t) * V_in; + end + end + + % shrink output window + V_out = V_out(1+r:end-r, 1+r:end-r); + + end + + %------------------------------------------------------------------ + function V_out = apply_2D_gpu(this, V_in) + + vol_geom = astra_create_vol_geom(size(V_in)); + in_id = astra_mex_data2d('create', '-vol', vol_geom, V_in); + out_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + + cfg = astra_struct('DARTSMOOTHING_CUDA'); + cfg.InDataId = in_id; + cfg.OutDataId = out_id; + cfg.option.Intensity = this.b; + cfg.option.Radius = this.radius; + cfg.option.GPUindex = this.gpu_core; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate',alg_id,1); + V_out = astra_mex_data2d('get', out_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data2d('delete', in_id, out_id); + + end + + %------------------------------------------------------------------ + function I_out = apply_3D(this, I_in) + + r = this.radius; + w = 2 * r + 1; + + % Set Kernel + K = ones(w,w,w) * this.b / (w.^3-1); % edges + K(r+1,r+1,r+1) = 1 - this.b; % center + + % output window + I_out = zeros(size(I_in,1)+w-1, size(I_in,2)+w-1, size(I_in,3)+w-1); + + % blur convolution + for s = -r:r + for t = -r:r + for u = -r:r + I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) = I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) + K(r+1+s, r+1+t, r+1+u) * I_in; + end + end + end + + % shrink output window + I_out = I_out(1+r:end-r, 1+r:end-r, 1+r:end-r); + + end + + %------------------------------------------------------------------ + function V_out = apply_3D_gpu(this, V_in) + + vol_geom = astra_create_vol_geom(size(V_in)); + data_id = astra_mex_data3d('create', '-vol', vol_geom, V_in); + + cfg = astra_struct('DARTSMOOTHING3D_CUDA'); + cfg.InDataId = data_id; + cfg.OutDataId = data_id; + cfg.option.Intensity = this.b; + cfg.option.Radius = this.radius; + cfg.option.GPUindex = this.gpu_core; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate', alg_id, 1); + V_out = astra_mex_data3d('get', data_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data3d('delete', data_id); + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/SmoothingGPU.m b/matlab/algorithms/DART/SmoothingGPU.m new file mode 100644 index 0000000..857da37 --- /dev/null +++ b/matlab/algorithms/DART/SmoothingGPU.m @@ -0,0 +1,119 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef SmoothingGPU < matlab.mixin.Copyable + + % Default policy class for smoothing for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + radius = 1; % SETTING: Radius of smoothing kernel. + b = 0.1; % SETTING: Intensity of smoothing. Between 0 and 1. + full3d = 'yes'; % SETTING: smooth in 3D? {'yes','no'} + gpu_core = 0; % SETTING: + end + + + %---------------------------------------------------------------------- + methods (Access=public) + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.smoothing.getsettings(); + settings.radius = this.radius; + settings.b = this.b; + settings.full3d = this.full3d; + end + + %------------------------------------------------------------------ + function V_out = apply(this, ~, V_in) + % Applies smoothing. + % >> V_out = DART.smoothing.apply(DART, V_in); + + % 2D, one slice + if size(V_in,3) == 1 + V_out = this.apply_2D(V_in); + + % 3D, slice by slice + elseif ~strcmp(this.full3d,'yes') + V_out = zeros(size(V_in)); + for slice = 1:size(V_in,3) + V_out(:,:,slice) = this.apply_2D(V_in(:,:,slice)); + end + + % 3D, full + else + V_out = this.apply_3D(V_in); + end + + end + + end + + %---------------------------------------------------------------------- + methods (Access=protected) + + %------------------------------------------------------------------ + function V_out = apply_2D(this, V_in) + + vol_geom = astra_create_vol_geom(size(V_in)); + in_id = astra_mex_data2d('create', '-vol', vol_geom, V_in); + out_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + + cfg = astra_struct('DARTSMOOTHING_CUDA'); + cfg.InDataId = in_id; + cfg.OutDataId = out_id; + cfg.Intensity = this.b; + cfg.option.GPUindex = this.gpu_core; + + alg_id = astra_mex_algorithm('create',cfg); + astra_mex_algorithm('iterate',alg_id,1); + V_out = astra_mex_data2d('get', out_id); + + astra_mex_algorithm('delete', alg_id); + astra_mex_data2d('delete', in_id, out_id); + + + end + + %------------------------------------------------------------------ + function I_out = apply_3D(this, I_in) + + r = this.radius; + w = 2 * r + 1; + + % Set Kernel + K = ones(w,w,w) * this.b / (w.^3-1); % edges + K(r+1,r+1,r+1) = 1 - this.b; % center + + % output window + I_out = zeros(size(I_in,1)+w-1, size(I_in,2)+w-1, size(I_in,3)+w-1); + + % blur convolution + for s = -r:r + for t = -r:r + for u = -r:r + I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) = I_out(1+r+s:end-r+s, 1+r+t:end-r+t, 1+r+u:end-r+u) + K(r+1+s, r+1+t, r+1+u) * I_in; + end + end + end + + % shrink output window + I_out = I_out(1+r:end-r, 1+r:end-r, 1+r:end-r); + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/StatisticsDefault.m b/matlab/algorithms/DART/StatisticsDefault.m new file mode 100644 index 0000000..7822c5f --- /dev/null +++ b/matlab/algorithms/DART/StatisticsDefault.m @@ -0,0 +1,72 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef StatisticsDefault < matlab.mixin.Copyable + + % Default policy class for statistics for DART. + + properties (Access=public) + pixel_error = 'yes'; % SETTING: Store pixel error? {'yes','no'} + proj_diff = 'yes'; % SETTING: Store projection difference? {'yes','no'} + timing = 'yes'; % SETTING: Store timings? {'yes','no'} + end + + + methods (Access=public) + + %------------------------------------------------------------------ + function stats = apply(this, DART) + % Applies statistics. + % >> stats = DART.statistics.apply(DART); + + stats = DART.stats; + + % timing + if strcmp(this.timing, 'yes') + stats.timing(DART.iterationcount) = toc(DART.start_tic); + end + + % pixel error + if strcmp(this.pixel_error, 'yes') && isfield(DART.base,'phantom') + [stats.rnmp, stats.nmp] = compute_rnmp(DART.base.phantom, DART.S); + stats.rnmp_hist(DART.iterationcount) = stats.rnmp; + stats.nmp_hist(DART.iterationcount) = stats.nmp; + end + + % projection difference + if strcmp(this.proj_diff, 'yes') + new_sino = DART.tomography.createForwardProjection(DART, DART.S); + stats.proj_diff = sum((new_sino(:) - DART.base.sinogram(:)) .^2 ) ./ (sum(DART.base.sinogram(:)) ); + stats.proj_diff_hist(DART.iterationcount) = stats.proj_diff; + end + + end + + %------------------------------------------------------------------ + function s = tostring(~, stats) + % To string. + % >> stats = DART.statistics.apply(stats); + + s = ''; + if isfield(stats, 'nmp') + s = sprintf('%s [%d]', s, stats.nmp); + end + if isfield(stats, 'proj_diff') + s = sprintf('%s {%0.2d}', s, stats.proj_diff); + end + + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/TomographyDefault.m b/matlab/algorithms/DART/TomographyDefault.m new file mode 100644 index 0000000..4db3905 --- /dev/null +++ b/matlab/algorithms/DART/TomographyDefault.m @@ -0,0 +1,73 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef TomographyDefault < IterativeTomography + + % Policy class for tomography for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + t = 5; % SETTING: # ARMiterations, each DART iteration. + t0 = 100; % SETTING: # ARM iterations at DART initialization. + end + %---------------------------------------------------------------------- + + methods + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.tomography.getsettings(); +% settings = getsettings@IterativeTomography(); + settings.t = this.t; + settings.t0 = this.t0; + end + + %------------------------------------------------------------------ + function initialize(this, DART) + % Initializes this object. + % >> DART.tomography.initialize(); + this.proj_geom = DART.base.proj_geom; + this.initialize@IterativeTomography(); + end + + %------------------------------------------------------------------ + function P = createForwardProjection(this, ~, volume) + % Compute forward projection. + % >> DART.tomography.createForwardProjection(DART, volume); + P = this.project_c(volume); + end + + %------------------------------------------------------------------ + function I = createReconstruction(this, ~, sinogram, V0, mask) + % Compute reconstruction (with mask). + % >> DART.tomography.createReconstruction(DART, sinogram, V0, mask); + if strcmp(this.inner_circle,'yes') + mask = ROIselectfull(mask, size(mask,1)); + end + I = this.reconstruct_c(sinogram, V0, mask, this.t); + end + + %------------------------------------------------------------------ + function I = createInitialReconstruction(this, ~, sinogram) + % Compute reconstruction (initial). + % >> DART.tomography.createInitialReconstruction(DART, sinogram); + I = this.reconstruct_c(sinogram, [], [], this.t0); + if strcmp(this.inner_circle,'yes') + I = ROIselectfull(I, size(I,1)); + end + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/TomographyDefault3D.m b/matlab/algorithms/DART/TomographyDefault3D.m new file mode 100644 index 0000000..2be1b17 --- /dev/null +++ b/matlab/algorithms/DART/TomographyDefault3D.m @@ -0,0 +1,73 @@ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +% +% Author of this DART Algorithm: Wim van Aarle + + +classdef TomographyDefault3D < IterativeTomography3D + + % Policy class for 3D tomography for DART. + + %---------------------------------------------------------------------- + properties (Access=public) + t = 5; % SETTING: # ARMiterations, each DART iteration. + t0 = 100; % SETTING: # ARM iterations at DART initialization. + end + %---------------------------------------------------------------------- + + methods + + %------------------------------------------------------------------ + function settings = getsettings(this) + % Returns a structure containing all settings of this object. + % >> settings = DART.tomography.getsettings(); +% settings = getsettings@IterativeTomography(); + settings.t = this.t; + settings.t0 = this.t0; + end + + %------------------------------------------------------------------ + function initialize(this, DART) + % Initializes this object. + % >> DART.tomography.initialize(); + this.proj_geom = DART.base.proj_geom; + this.initialize@IterativeTomography3D(); + end + + %------------------------------------------------------------------ + function P = createForwardProjection(this, ~, volume) + % Compute forward projection. + % >> DART.tomography.createForwardProjection(DART, volume); + P = this.project_c(volume); + end + + %------------------------------------------------------------------ + function I = createReconstruction(this, ~, sinogram, V0, mask) + % Compute reconstruction (with mask). + % >> DART.tomography.createReconstruction(DART, sinogram, V0, mask); + if strcmp(this.inner_circle,'yes') + mask = ROIselectfull(mask, size(mask,1)); + end + I = this.reconstruct_c(sinogram, V0, mask, this.t); + end + + %------------------------------------------------------------------ + function I = createInitialReconstruction(this, ~, sinogram) + % Compute reconstruction (initial). + % >> DART.tomography.createInitialReconstruction(DART, sinogram); + I = this.reconstruct_c(sinogram, [], [], this.t0); + if strcmp(this.inner_circle,'yes') + I = ROIselectfull(I, size(I,1)); + end + end + %------------------------------------------------------------------ + + end + +end + diff --git a/matlab/algorithms/DART/examples/cylinders.png b/matlab/algorithms/DART/examples/cylinders.png Binary files differnew file mode 100644 index 0000000..8d1c0b2 --- /dev/null +++ b/matlab/algorithms/DART/examples/cylinders.png diff --git a/matlab/algorithms/DART/examples/example1.m b/matlab/algorithms/DART/examples/example1.m new file mode 100644 index 0000000..daa3ce8 --- /dev/null +++ b/matlab/algorithms/DART/examples/example1.m @@ -0,0 +1,79 @@ +clear all; + +addpath('..'); + +% +% Example 1: parallel beam, three slices. +% + +% Configuration +proj_count = 20; +slice_count = 3; +dart_iterations = 20; +filename = 'cylinders.png'; +outdir = './'; +prefix = 'example1'; +rho = [0, 1]; +tau = 0.5; +gpu_core = 0; + +% Load phantom. +I = double(imread(filename)) / 255; + +% Create projection and volume geometries. +det_count = size(I, 1); +angles = linspace(0, pi - pi / proj_count, proj_count); +proj_geom = astra_create_proj_geom('parallel3d', 1, 1, slice_count, det_count, angles); +vol_geom = astra_create_vol_geom(det_count, det_count, 1); + +% Create sinogram. +[sinogram_id, sinogram] = astra_create_sino3d_cuda(I, proj_geom, vol_geom); +astra_mex_data3d('delete', sinogram_id); + +% +% DART +% + +base.sinogram = sinogram; +base.proj_geom = proj_geom; + +D = DARTalgorithm(base); + +D.tomography = TomographyDefault3D(); +D.tomography.t0 = 100; +D.tomography.t = 10; +D.tomography.method = 'SIRT3D_CUDA'; +D.tomography.gpu_core = gpu_core; +D.tomography.use_minc = 'yes'; +% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration. + +D.segmentation.rho = rho; +D.segmentation.tau = tau; + +D.smoothing.b = 0.1; +D.smoothing.full3d = 'yes'; +D.smoothing.gpu_core = gpu_core; + +D.masking.random = 0.1; +D.masking.conn = 6; +D.masking.gpu_core = gpu_core; + +D.output.directory = outdir; +D.output.pre = [prefix '_']; +D.output.save_images = 'no'; +D.output.save_results = {'stats', 'settings', 'S', 'V'}; +D.output.save_interval = dart_iterations; +D.output.verbose = 'yes'; + +D.statistics.proj_diff = 'no'; + +D.initialize(); + +disp([D.output.directory D.output.pre]); + +D.iterate(dart_iterations); + +% Convert middle slice of final iteration to png. +load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']); +imwritesc(D.S(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_S.png']); +imwritesc(D.V(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_V.png']); diff --git a/matlab/algorithms/DART/examples/example2.m b/matlab/algorithms/DART/examples/example2.m new file mode 100644 index 0000000..8ee8cba --- /dev/null +++ b/matlab/algorithms/DART/examples/example2.m @@ -0,0 +1,80 @@ +clear all; + +addpath('..'); + +% +% Example 2: cone beam, full cube. +% + +% Configuration +det_count = 128; +proj_count = 45; +slice_count = det_count; +dart_iterations = 20; +outdir = './'; +prefix = 'example2'; +rho = [0 0.5 1]; +tau = [0.25 0.75]; +gpu_core = 0; + +% Create phantom. +% I = phantom3d([1 0.9 0.9 0.9 0 0 0 0 0 0; -0.5 0.8 0.8 0.8 0 0 0 0 0 0; -0.5 0.3 0.3 0.3 0 0 0 0 0 0], det_count); +% save('phantom3d', 'I'); +load('phantom3d'); % Loads I. + +% Create projection and volume geometries. +angles = linspace(0, pi - pi / proj_count, proj_count); +proj_geom = astra_create_proj_geom('cone', 1, 1, slice_count, det_count, angles, 500, 0); +vol_geom = astra_create_vol_geom(det_count, det_count, slice_count); + +% Create sinogram. +[sinogram_id, sinogram] = astra_create_sino3d_cuda(I, proj_geom, vol_geom); +astra_mex_data3d('delete', sinogram_id); + +% +% DART +% + +base.sinogram = sinogram; +base.proj_geom = proj_geom; + +D = DARTalgorithm(base); + +D.tomography = TomographyDefault3D(); +D.tomography.t0 = 100; +D.tomography.t = 10; +D.tomography.method = 'SIRT3D_CUDA'; +D.tomography.gpu_core = gpu_core; +D.tomography.use_minc = 'yes'; +% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration. + +D.segmentation.rho = rho; +D.segmentation.tau = tau; + +D.smoothing.b = 0.1; +D.smoothing.full3d = 'yes'; +D.smoothing.gpu_core = gpu_core; + +D.masking.random = 0.1; +D.masking.conn = 6; +D.masking.gpu_core = gpu_core; + +D.output.directory = outdir; +D.output.pre = [prefix '_']; +D.output.save_images = 'no'; +D.output.save_results = {'stats', 'settings', 'S', 'V'}; +D.output.save_interval = dart_iterations; +D.output.verbose = 'yes'; + +D.statistics.proj_diff = 'no'; + +D.initialize(); + +disp([D.output.directory D.output.pre]); + +D.iterate(dart_iterations); + +% Convert middle slice of final iteration to png. +load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']); +imwritesc(D.S(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_S.png']); +imwritesc(D.V(:, :, round(slice_count / 2)), [outdir '/' prefix '_slice_2_V.png']); diff --git a/matlab/algorithms/DART/examples/example3.m b/matlab/algorithms/DART/examples/example3.m new file mode 100644 index 0000000..f6e360e --- /dev/null +++ b/matlab/algorithms/DART/examples/example3.m @@ -0,0 +1,79 @@ +clear all; + +addpath('..'); + +% +% Example 3: parallel beam, 2D +% + +% Configuration +proj_count = 30; +dart_iterations = 20; +filename = 'cylinders.png'; +outdir = './'; +prefix = 'example3'; +rho = [0, 1]; +tau = 0.5; +gpu_core = 0; + +% Load phantom. +I = double(imread(filename)) / 255; + +% Create projection and volume geometries. +det_count = size(I, 1); +angles = linspace(0, pi - pi / proj_count, proj_count); +proj_geom = astra_create_proj_geom('parallel', 1, det_count, angles); +vol_geom = astra_create_vol_geom(det_count, det_count); + +% Create sinogram. +[sinogram_id, sinogram] = astra_create_sino_cuda(I, proj_geom, vol_geom); +astra_mex_data2d('delete', sinogram_id); + +% +% DART +% + +base.sinogram = sinogram; +base.proj_geom = proj_geom; + +D = DARTalgorithm(base); + +%D.tomography = TomographyDefault3D(); +D.tomography.t0 = 100; +D.tomography.t = 10; +D.tomography.method = 'SIRT_CUDA'; +D.tomography.proj_type = 'strip'; +D.tomography.gpu_core = gpu_core; +D.tomography.use_minc = 'yes'; +% D.tomography.maxc = 0.003; % Not a sensible value, just for demonstration. + +D.segmentation.rho = rho; +D.segmentation.tau = tau; + +D.smoothing.b = 0.1; +D.smoothing.full3d = 'yes'; +D.smoothing.gpu_core = gpu_core; + +D.masking.random = 0.1; +D.masking.conn = 6; +D.masking.gpu_core = gpu_core; + +D.output.directory = outdir; +D.output.pre = [prefix '_']; +D.output.save_images = 'no'; +D.output.save_results = {'stats', 'settings', 'S', 'V'}; +D.output.save_interval = dart_iterations; +D.output.verbose = 'yes'; + +D.statistics.proj_diff = 'no'; + +D.initialize(); + +disp([D.output.directory D.output.pre]); + +D.iterate(dart_iterations); + +% Convert output of final iteration to png. +load([outdir '/' prefix '_results_' num2str(dart_iterations) '.mat']); +imwritesc(D.S, [outdir '/' prefix '_S.png']); +imwritesc(D.V, [outdir '/' prefix '_V.png']); diff --git a/matlab/algorithms/DART/examples/phantom3d.mat b/matlab/algorithms/DART/examples/phantom3d.mat Binary files differnew file mode 100644 index 0000000..6d70c16 --- /dev/null +++ b/matlab/algorithms/DART/examples/phantom3d.mat diff --git a/matlab/mex/astra_mex.cpp b/matlab/mex/astra_mex.cpp new file mode 100644 index 0000000..4b77f76 --- /dev/null +++ b/matlab/mex/astra_mex.cpp @@ -0,0 +1,121 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +#include <mex.h> +#include "mexHelpFunctions.h" + +#include "astra/Globals.h" + +using namespace std; +using namespace astra; + + +//----------------------------------------------------------------------------------------- +/** astra_mex('credits'); + * + * Print Credits + */ +void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + cout << "All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by" << endl; + cout << " * Joost Batenburg, PhD" << endl; + cout << " * Gert Merckx" << endl; + cout << " * Willem Jan Palenstijn" << endl; + cout << " * Tom Roelandts" << endl; + cout << " * Prof. Dr. Jan Sijbers" << endl; + cout << " * Wim van Aarle" << endl; + cout << " * Sander van der Maar" << endl; + cout << " * Gert Van Gompel, PhD" << endl; +} + +//----------------------------------------------------------------------------------------- +/** use_cuda = astra_mex('use_cuda'); + * + * Is CUDA enabled? + */ +void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(astra::cudaEnabled() ? 1 : 0); + } +} + +//----------------------------------------------------------------------------------------- +/** version_number = astra_mex('version'); + * + * Fetch the version number of the toolbox. + */ +void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(astra::getVersion()); + } else { + cout << "astra toolbox version " << astra::getVersionString() << endl; + } +} + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf(" Valid modes: version, use_cuda, credits\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex(type,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT0: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == std::string("version")) { + astra_mex_version(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("use_cuda")) { + astra_mex_use_cuda(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("credits")) { + astra_mex_credits(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp new file mode 100644 index 0000000..7476ba4 --- /dev/null +++ b/matlab/mex/astra_mex_algorithm_c.cpp @@ -0,0 +1,348 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_algorithm_c.cpp + * + * \brief Creates and manages algorithms (reconstruction,projection,...). + */ +#include <mex.h> +#include "mexHelpFunctions.h" + +#define USE_MATLAB_UNDOCUMENTED + +#ifdef USE_MATLAB_UNDOCUMENTED +extern "C" { bool utIsInterruptPending(); } + +#ifdef __linux__ +#define USE_PTHREADS_CTRLC +#include <pthread.h> +#else +#include <boost/thread.hpp> +#endif + +#endif + + + +#include "astra/Globals.h" + +#include "astra/AstraObjectManager.h" +#include "astra/AstraObjectFactory.h" + +#include "astra/XMLNode.h" +#include "astra/XMLDocument.h" + +using namespace std; +using namespace astra; +//----------------------------------------------------------------------------------------- +/** id = astra_mex_algorithm('create', cfg); + * + * Create and configure a new algorithm object. + * cfg: MATLAB struct containing the configuration parameters, see doxygen documentation for details. + * id: identifier of the algorithm object as it is now stored in the astra-library. + */ +void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + if (!mxIsStruct(prhs[1])) { + mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n"); + } + + // turn MATLAB struct to an XML-based Config object + XMLDocument* xml = struct2XML("Algorithm", prhs[1]); + Config cfg; + cfg.self = xml->getRootNode(); + + CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg.self->getAttribute("type")); + if (!pAlg) { + delete xml; + mexErrMsgTxt("Unknown algorithm. \n"); + return; + } + + // create algorithm + if (!pAlg->initialize(cfg)) { + delete xml; + delete pAlg; + mexErrMsgTxt("Algorithm not initialized. \n"); + return; + } + + delete xml; + + // store algorithm + int iIndex = CAlgorithmManager::getSingleton().store(pAlg); + + // step4: set output + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } + +} + +#ifdef USE_MATLAB_UNDOCUMENTED + +#ifndef USE_PTHREADS_CTRLC + +// boost version +void waitForInterrupt_boost(CAlgorithm* _pAlg) +{ + boost::posix_time::milliseconds rel(2000); + + while (!utIsInterruptPending()) { + + // This is an interruption point. If the main thread calls + // interrupt(), this thread will terminate here. + boost::this_thread::sleep(rel); + } + + //mexPrintf("Aborting. Please wait.\n"); + + // One last quick check to see if the algorithm already finished + boost::this_thread::interruption_point(); + + _pAlg->signalAbort(); +} + +#else + +// pthreads version +void *waitForInterrupt_pthreads(void *threadid) +{ + CAlgorithm* _pAlg = (CAlgorithm*)threadid; + + while (!utIsInterruptPending()) { + usleep(50000); + pthread_testcancel(); + } + + //mexPrintf("Aborting. Please wait.\n"); + + // One last quick check to see if the algorithm already finished + pthread_testcancel(); + + _pAlg->signalAbort(); + + return 0; +} + +#endif +#endif + +//----------------------------------------------------------------------------------------- +/** astra_mex_algorithm('run', id); or astra_mex_algorithm('iterate', id, iterations); + * + * Run or do iterations on a certain algorithm. + * id: identifier of the algorithm object as stored in the astra-library. + * iterations: if the algorithm is iterative, this specifies the number of iterations to perform. + */ +void astra_mex_algorithm_run(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iAid = (int)(mxGetScalar(prhs[1])); + int iIterations = 0; + if (3 <= nrhs) { + iIterations = (int)(mxGetScalar(prhs[2])); + } + + // step2: get algorithm object + CAlgorithm* pAlg = CAlgorithmManager::getSingleton().get(iAid); + if (!pAlg) { + mexErrMsgTxt("Invalid algorithm ID.\n"); + return; + } + if (!pAlg->isInitialized()) { + mexErrMsgTxt("Algorithm not initialized. \n"); + return; + } + + // step3: perform actions +#ifndef USE_MATLAB_UNDOCUMENTED + + pAlg->run(iIterations); + +#elif defined(USE_PTHREADS_CTRLC) + + // Start a new thread to watch if the user pressed Ctrl-C + pthread_t thread; + pthread_create(&thread, 0, waitForInterrupt_pthreads, (void*)pAlg); + + pAlg->run(iIterations); + + // kill the watcher thread in case it's still running + pthread_cancel(thread); + pthread_join(thread, 0); + +#else + + // Start a new thread to watch if the user pressed Ctrl-C + boost::thread interruptThread(waitForInterrupt_boost, pAlg); + + pAlg->run(iIterations); + + // kill the watcher thread in case it's still running + interruptThread.interrupt(); + interruptThread.join(); + +#endif +} +//----------------------------------------------------------------------------------------- +/** astra_mex_algorithm('get_res_norm', id); + * + * Get the L2-norm of the residual sinogram. Not all algorithms + * support this operation. + */ +void astra_mex_algorithm_get_res_norm(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iAid = (int)(mxGetScalar(prhs[1])); + + // step2: get algorithm object + CAlgorithm* pAlg = CAlgorithmManager::getSingleton().get(iAid); + if (!pAlg) { + mexErrMsgTxt("Invalid algorithm ID.\n"); + return; + } + if (!pAlg->isInitialized()) { + mexErrMsgTxt("Algorithm not initialized. \n"); + return; + } + + CReconstructionAlgorithm2D* pAlg2D = dynamic_cast<CReconstructionAlgorithm2D*>(pAlg); + CReconstructionAlgorithm3D* pAlg3D = dynamic_cast<CReconstructionAlgorithm3D*>(pAlg); + + float res = 0.0f; + bool ok; + if (pAlg2D) + ok = pAlg2D->getResidualNorm(res); + else if (pAlg3D) + ok = pAlg3D->getResidualNorm(res); + else + ok = false; + + if (!ok) { + mexErrMsgTxt("Operation not supported.\n"); + return; + } + + plhs[0] = mxCreateDoubleScalar(res); +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_algorithm('delete', id1, id2, ...); + * + * Delete one or more algorithm objects currently stored in the astra-library. + * id1, id2, ... : identifiers of the algorithm objects as stored in the astra-library. + */ +void astra_mex_algorithm_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get algorithm ID + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iAid = (int)(mxGetScalar(prhs[i])); + CAlgorithmManager::getSingleton().remove(iAid); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_algorithm('clear'); + * + * Delete all algorithm objects currently stored in the astra-library. + */ +void astra_mex_algorithm_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CAlgorithmManager::getSingleton().clear(); +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_algorithm('info'); + * + * Print information about all the algorithm objects currently stored in the astra-library. + */ +void astra_mex_algorithm_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("%s", astra::CAlgorithmManager::getSingleton().info().c_str()); +} + +//----------------------------------------------------------------------------------------- +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: create, info, delete, clear, run/iterate, get_res_norm\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_algorithm(mode, ...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + // INPUT: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == "create") { + astra_mex_algorithm_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == "info") { + astra_mex_algorithm_info(nlhs, plhs, nrhs, prhs); + } else if (sMode == "delete") { + astra_mex_algorithm_delete(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_algorithm_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == "run" || sMode == "iterate") { + astra_mex_algorithm_run(nlhs, plhs, nrhs, prhs); + } else if (sMode == "get_res_norm") { + astra_mex_algorithm_get_res_norm(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + return; +} diff --git a/matlab/mex/astra_mex_algorithm_vc08.vcproj b/matlab/mex/astra_mex_algorithm_vc08.vcproj new file mode 100644 index 0000000..baa4c44 --- /dev/null +++ b/matlab/mex/astra_mex_algorithm_vc08.vcproj @@ -0,0 +1,593 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_algorithm" + ProjectGUID="{056BF7A9-294D-487C-8CC3-BE629077CA94}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="false" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + BrowseInformation="1" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft;..\..\lib\win32" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft;..\..\lib\x64" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_algorithm_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp new file mode 100644 index 0000000..0068664 --- /dev/null +++ b/matlab/mex/astra_mex_c.cpp @@ -0,0 +1,127 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_c.cpp + * + * \brief Contains some basic "about" functions. + */ + +#include <mex.h> +#include "mexHelpFunctions.h" + +#include "astra/Globals.h" + +using namespace std; +using namespace astra; + + +//----------------------------------------------------------------------------------------- +/** astra_mex('credits'); + * + * Print Credits + */ +void astra_mex_credits(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("All Scale Tomographic Reconstruction Antwerp Toolbox (ASTRA-Toolbox) was developed at the University of Antwerp by\n"); + mexPrintf(" * Prof. dr. Joost Batenburg\n"); + mexPrintf(" * Andrei Dabravolski\n"); + mexPrintf(" * Gert Merckx\n"); + mexPrintf(" * Willem Jan Palenstijn\n"); + mexPrintf(" * Tom Roelandts\n"); + mexPrintf(" * Prof. dr. Jan Sijbers\n"); + mexPrintf(" * dr. Wim van Aarle\n"); + mexPrintf(" * Sander van der Maar\n"); + mexPrintf(" * dr. Gert Van Gompel\n"); +} + +//----------------------------------------------------------------------------------------- +/** use_cuda = astra_mex('use_cuda'); + * + * Is CUDA enabled? + */ +void astra_mex_use_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(astra::cudaEnabled() ? 1 : 0); + } +} + +//----------------------------------------------------------------------------------------- +/** version_number = astra_mex('version'); + * + * Fetch the version number of the toolbox. + */ +void astra_mex_version(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(astra::getVersion()); + } else { + mexPrintf("astra toolbox version %s\n", astra::getVersionString()); + } +} + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf(" Valid modes: version, use_cuda, credits\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex(type,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT0: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == std::string("version")) { + astra_mex_version(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("use_cuda")) { + astra_mex_use_cuda(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("credits")) { + astra_mex_credits(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp new file mode 100644 index 0000000..99fb38e --- /dev/null +++ b/matlab/mex/astra_mex_data2d_c.cpp @@ -0,0 +1,667 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_data2d_c.cpp + * + * \brief Creates, manages and manipulates 2D volume and projection data objects. + */ +#include <mex.h> +#include "mexHelpFunctions.h" + +#include <list> + +#include "astra/Globals.h" + +#include "astra/AstraObjectManager.h" + +#include "astra/Float32ProjectionData2D.h" +#include "astra/Float32VolumeData2D.h" +#include "astra/SparseMatrixProjectionGeometry2D.h" +#include "astra/FanFlatProjectionGeometry2D.h" +#include "astra/FanFlatVecProjectionGeometry2D.h" + +using namespace std; +using namespace astra; + +//----------------------------------------------------------------------------------------- +/** astra_mex_data2d('delete', id1, id2, ...); + * + * Delete one or more data objects currently stored in the astra-library. + * id1, id2, ... : identifiers of the 2d data objects as stored in the astra-library. + */ +void astra_mex_data2d_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + // step2: delete all specified data objects + for (int i = 1; i < nrhs; i++) { + int iDataID = (int)(mxGetScalar(prhs[i])); + CData2DManager::getSingleton().remove(iDataID); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_data2d('clear'); + * + * Delete all data objects currently stored in the astra-library. + */ +void astra_mex_data2d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CData2DManager::getSingleton().clear(); +} + +//----------------------------------------------------------------------------------------- +/** id = astra_mex_data2d('create', datatype, geometry, data); + * + * Create a new data 2d object in the astra-library. + * type: '-vol' for volume data, '-sino' for projection data + * geom: MATLAB struct with the geometry for the data + * data: Optional. Can be either a MATLAB matrix containing the data. In that case the dimensions + * should match that of the geometry of the object. It can also be a single value, in which case + * the entire data will be set to that value. If this isn't specified all values are set to 0. + * id: identifier of the 2d data object as it is now stored in the astra-library. + */ +void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) +{ + // step1: get datatype + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + string sDataType = mex_util_get_string(prhs[1]); + CFloat32Data2D* pDataObject2D = NULL; + + if (nrhs >= 4 && !(mex_is_scalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) { + mexErrMsgTxt("Data must be single, double or logical."); + return; + } + + // SWITCH DataType + if (sDataType == "-vol") { + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]); + if (!xml) + return; + Config cfg; + cfg.self = xml->getRootNode(); + CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D(); + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete xml; + delete pGeometry; + return; + } + // If data is specified, check dimensions + if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { + if (pGeometry->getGridColCount() != mxGetN(prhs[3]) || pGeometry->getGridRowCount() != mxGetM(prhs[3])) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete xml; + delete pGeometry; + return; + } + } + // Initialize data object + pDataObject2D = new CFloat32VolumeData2D(pGeometry); + delete pGeometry; + delete xml; + } + else if (sDataType == "-sino") { + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); + if (!xml) + return; + Config cfg; + cfg.self = xml->getRootNode(); + // FIXME: Change how the base class is created. (This is duplicated + // in 'change_geometry' and Projector2D.cpp.) + std::string type = cfg.self->getAttribute("type"); + CProjectionGeometry2D* pGeometry; + if (type == "sparse_matrix") { + pGeometry = new CSparseMatrixProjectionGeometry2D(); + } else if (type == "fanflat") { + //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D(); + //pFanFlatProjectionGeometry->initialize(Config(node)); + //m_pProjectionGeometry = pFanFlatProjectionGeometry; + pGeometry = new CFanFlatProjectionGeometry2D(); + } else if (type == "fanflat_vec") { + pGeometry = new CFanFlatVecProjectionGeometry2D(); + } else { + pGeometry = new CParallelProjectionGeometry2D(); + } + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete pGeometry; + delete xml; + return; + } + // If data is specified, check dimensions + if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { + if (pGeometry->getDetectorCount() != mxGetN(prhs[3]) || pGeometry->getProjectionAngleCount() != mxGetM(prhs[3])) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete pGeometry; + delete xml; + return; + } + } + // Initialize data object + pDataObject2D = new CFloat32ProjectionData2D(pGeometry); + delete pGeometry; + delete xml; + } + else { + mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-sino'. \n"); + return; + } + + // Check initialization + if (!pDataObject2D->isInitialized()) { + mexErrMsgTxt("Couldn't initialize data object.\n"); + delete pDataObject2D; + return; + } + + // Store data + if (nrhs == 3) { + for (int i = 0; i < pDataObject2D->getSize(); ++i) { + pDataObject2D->getData()[i] = 0.0f; + } + } + + // Store data + if (nrhs >= 4) { + // fill with scalar value + if (mex_is_scalar(prhs[3])) { + float32 fValue = (float32)mxGetScalar(prhs[3]); + for (int i = 0; i < pDataObject2D->getSize(); ++i) { + pDataObject2D->getData()[i] = fValue; + } + } + // fill with array value + else { + const mwSize* dims = mxGetDimensions(prhs[3]); + // Check Data dimensions + if (pDataObject2D->getWidth() != mxGetN(prhs[3]) || pDataObject2D->getHeight() != mxGetM(prhs[3])) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + return; + } + + // logical data + if (mxIsLogical(prhs[3])) { + bool* pbMatlabData = mxGetLogicals(prhs[3]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject2D->getData2D()[row][col] = (float32)pbMatlabData[i]; + ++i; + } + } + // double data + } else if (mxIsDouble(prhs[3])) { + double* pdMatlabData = mxGetPr(prhs[3]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject2D->getData2D()[row][col] = pdMatlabData[i]; + ++i; + } + } + // single data + } else if (mxIsSingle(prhs[3])) { + const float* pfMatlabData = (const float *)mxGetData(prhs[3]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject2D->getData2D()[row][col] = pfMatlabData[i]; + ++i; + } + } + } else { + ASTRA_ASSERT(false); + } + } + } + + // step4: store data object + int iIndex = CData2DManager::getSingleton().store(pDataObject2D); + + // step5: return data id + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } + +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_data2d('store', id, data); + * + * Store data in an existing astra 2d dataobject with a MATLAB matrix or with a scalar value. + * id: identifier of the 2d data object as stored in the astra-library. + * data: can be either a MATLAB matrix containing the data. In that case the dimensions should match that of the geometry of the object. It can also be a single value, in which case the entire data will be set to that value. + */ +void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) { + mexErrMsgTxt("Data must be single, double or logical."); + return; + } + + // step2: get data object + CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // step3: insert data + // fill with scalar value + if (mex_is_scalar(prhs[2])) { + float32 fValue = (float32)mxGetScalar(prhs[2]); + for (int i = 0; i < pDataObject->getSize(); ++i) { + pDataObject->getData()[i] = fValue; + } + } else { + // Check Data dimensions + if (pDataObject->getWidth() != mxGetN(prhs[2]) || pDataObject->getHeight() != mxGetM(prhs[2])) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + return; + } + const mwSize* dims = mxGetDimensions(prhs[2]); + + // logical data + if (mxIsLogical(prhs[2])) { + bool* pbMatlabData = mxGetLogicals(prhs[2]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject->getData2D()[row][col] = (float32)pbMatlabData[i]; + ++i; + } + } + // double data + } else if (mxIsDouble(prhs[2])) { + double* pdMatlabData = mxGetPr(prhs[2]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject->getData2D()[row][col] = pdMatlabData[i]; + ++i; + } + } + // single data + } else if (mxIsSingle(prhs[2])) { + const float* pfMatlabData = (const float *)mxGetData(prhs[2]); + int i = 0; + int col, row; + for (col = 0; col < dims[1]; ++col) { + for (row = 0; row < dims[0]; ++row) { + pDataObject->getData2D()[row][col] = pfMatlabData[i]; + ++i; + } + } + } else { + ASTRA_ASSERT(false); + } + } +} + +//----------------------------------------------------------------------------------------- +/** geom = astra_mex_data2d('get_geometry', id); + * + * Fetch the geometry of a 2d data object stored in the astra-library. + * id: identifier of the 2d data object as stored in the astra-library. + * geom: MATLAB-struct containing information about the used geometry. + */ +void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + if (pDataObject->getType() == CFloat32Data2D::PROJECTION) { + CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject); + plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry()); + } + else if (pDataObject->getType() == CFloat32Data2D::VOLUME) { + CFloat32VolumeData2D* pDataObject2 = dynamic_cast<CFloat32VolumeData2D*>(pDataObject); + plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry()); + } + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_data2d('change_geometry', id, geom); + * + * Change the associated geometry of a 2d data object (volume or sinogram) + * id: identifier of the 2d data object as stored in the astra-library. + * geom: the new geometry struct, as created by astra_create_vol/proj_geom + */ +void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: check input + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + + // step2: get data object + int iDataID = (int)(mxGetScalar(prhs[1])); + CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + CFloat32ProjectionData2D* pSinogram = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject); + + if (pSinogram) { + // Projection data + + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); + Config cfg; + cfg.self = xml->getRootNode(); + // FIXME: Change how the base class is created. (This is duplicated + // in 'create' and Projector2D.cpp.) + std::string type = cfg.self->getAttribute("type"); + CProjectionGeometry2D* pGeometry; + if (type == "sparse_matrix") { + pGeometry = new CSparseMatrixProjectionGeometry2D(); + } else if (type == "fanflat") { + //CFanFlatProjectionGeometry2D* pFanFlatProjectionGeometry = new CFanFlatProjectionGeometry2D(); + //pFanFlatProjectionGeometry->initialize(Config(node)); + //m_pProjectionGeometry = pFanFlatProjectionGeometry; + pGeometry = new CFanFlatProjectionGeometry2D(); + } else if (type == "fanflat_vec") { + pGeometry = new CFanFlatVecProjectionGeometry2D(); + } else { + pGeometry = new CParallelProjectionGeometry2D(); + } + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete pGeometry; + delete xml; + return; + } + // If data is specified, check dimensions + if (pGeometry->getDetectorCount() != pSinogram->getDetectorCount() || pGeometry->getProjectionAngleCount() != pSinogram->getAngleCount()) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete pGeometry; + delete xml; + return; + } + + // If ok, change geometry + pSinogram->changeGeometry(pGeometry); + delete pGeometry; + delete xml; + + return; + } + + CFloat32VolumeData2D* pVolume = dynamic_cast<CFloat32VolumeData2D*>(pDataObject); + + if (pVolume) { + // Volume data + + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]); + Config cfg; + cfg.self = xml->getRootNode(); + CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D(); + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete xml; + delete pGeometry; + return; + } + // If data is specified, check dimensions + if (pGeometry->getGridColCount() != pVolume->getWidth() || pGeometry->getGridRowCount() != pVolume->getHeight()) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete xml; + delete pGeometry; + return; + } + + // If ok, change geometry + pVolume->changeGeometry(pGeometry); + delete xml; + delete pGeometry; + + } + + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; +} + +//----------------------------------------------------------------------------------------- +/** data = astra_mex_data2d('get', id); + * + * Fetch data from the astra-library to a MATLAB matrix. + * id: identifier of the 2d data object as stored in the astra-library. + * data: MATLAB data + */ +void astra_mex_data2d_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: check input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + + // step2: get data object + int iDataID = (int)(mxGetScalar(prhs[1])); + CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleMatrix(pDataObject->getHeight(), // # rows + pDataObject->getWidth(), // # cols + mxREAL); // datatype 64-bits + double* out = mxGetPr(plhs[0]); + int i = 0; + int row, col; + for (col = 0; col < pDataObject->getWidth(); ++col) { + for (row = 0; row < pDataObject->getHeight(); ++row) { + out[i] = pDataObject->getData2D()[row][col]; + ++i; + } + } + } + +} + +//----------------------------------------------------------------------------------------- +/** data = astra_mex_data2d('get_single', id); + * + * Fetch data from the astra-library to a MATLAB matrix. + * id: identifier of the 2d data object as stored in the astra-library. + * data: MATLAB data + */ +void astra_mex_data2d_get_single(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: check input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + + // step2: get data object + int iDataID = (int)(mxGetScalar(prhs[1])); + CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + mwSize dims[2]; + dims[0] = pDataObject->getHeight(); + dims[1] = pDataObject->getWidth(); + plhs[0] = mxCreateNumericArray(2, dims, mxSINGLE_CLASS, mxREAL); + float* out = (float *)mxGetData(plhs[0]); + int i = 0; + int row, col; + for (col = 0; col < pDataObject->getWidth(); ++col) { + for (row = 0; row < pDataObject->getHeight(); ++row) { + out[i] = pDataObject->getData2D()[row][col]; + ++i; + } + } + } + +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_data2d('info'); + * + * Print information about all the 2d data objects currently stored in the astra-library. + */ +void astra_mex_data2d_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("%s", astra::CData2DManager::getSingleton().info().c_str()); +} + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: get, get_single, delete, clear, set/store, create, get_geometry, change_geometry, info\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_data2d(type,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT0: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == std::string("get")) { + astra_mex_data2d_get(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("get_single")) { + astra_mex_data2d_get_single(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("delete")) { + astra_mex_data2d_delete(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_data2d_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("store") || + sMode == std::string("set")) { + astra_mex_data2d_store(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("create")) { + astra_mex_data2d_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("get_geometry")) { + astra_mex_data2d_get_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("change_geometry")) { + astra_mex_data2d_change_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("info")) { + astra_mex_data2d_info(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/matlab/mex/astra_mex_data2d_vc08.vcproj b/matlab/mex/astra_mex_data2d_vc08.vcproj new file mode 100644 index 0000000..8f1fc13 --- /dev/null +++ b/matlab/mex/astra_mex_data2d_vc08.vcproj @@ -0,0 +1,591 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_data2d" + ProjectGUID="{E4092269-B19C-46F7-A84E-4F146CC70E44}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""$(CUDA_INC_PATH)";$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + BrowseInformation="1" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_data2d_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp new file mode 100644 index 0000000..1af8844 --- /dev/null +++ b/matlab/mex/astra_mex_data3d_c.cpp @@ -0,0 +1,1036 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_data3d_c.cpp + * + * \brief Creates, manages and manipulates 3D volume and projection data objects. + */ +#include <mex.h> +#include "mexHelpFunctions.h" + +#include <list> + +#include "astra/Globals.h" + +#include "astra/AstraObjectManager.h" + +#include "astra/Float32ProjectionData2D.h" +#include "astra/Float32VolumeData2D.h" +#include "astra/Float32ProjectionData3D.h" +#include "astra/Float32ProjectionData3DMemory.h" +#include "astra/Float32VolumeData3D.h" +#include "astra/Float32VolumeData3DMemory.h" +#include "astra/ParallelProjectionGeometry3D.h" +#include "astra/ParallelVecProjectionGeometry3D.h" +#include "astra/ConeProjectionGeometry3D.h" +#include "astra/ConeVecProjectionGeometry3D.h" + +using namespace std; +using namespace astra; + + + +//----------------------------------------------------------------------------------------- +/** + * id = astra_mex_io_data('create', datatype, geometry, data); + * datatype: ['-vol','-sino','-sinocone'] + */ +void astra_mex_data3d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) +{ + // step1: get datatype + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + string sDataType = mex_util_get_string(prhs[1]); + CFloat32Data3DMemory* pDataObject3D = NULL; + + if (nrhs >= 4 && !(mex_is_scalar(prhs[3]) || mxIsDouble(prhs[3]) || mxIsSingle(prhs[3]))) { + mexErrMsgTxt("Data must be single or double."); + return; + } + + mwSize dims[3]; + + // SWITCH DataType + if (sDataType == "-vol") { + + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + Config cfg; + XMLDocument* xml = struct2XML("VolumeGeometry", prhs[2]); + if (!xml) + return; + cfg.self = xml->getRootNode(); + CVolumeGeometry3D* pGeometry = new CVolumeGeometry3D(); + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete pGeometry; + delete xml; + return; + } + delete xml; + + // If data is specified, check dimensions + if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { + get3DMatrixDims(prhs[3], dims); + if (pGeometry->getGridColCount() != dims[0] || pGeometry->getGridRowCount() != dims[1] || pGeometry->getGridSliceCount() != dims[2]) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete pGeometry; + return; + } + } + + // Initialize data object + pDataObject3D = new CFloat32VolumeData3DMemory(pGeometry); + delete pGeometry; + } + + else if (sDataType == "-sino" || sDataType == "-proj3d") { + + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); + if (!xml) + return; + Config cfg; + cfg.self = xml->getRootNode(); + + // FIXME: Change how the base class is created. (This is duplicated + // in Projector2D.cpp.) + std::string type = cfg.self->getAttribute("type"); + CProjectionGeometry3D* pGeometry = 0; + if (type == "parallel3d") { + pGeometry = new CParallelProjectionGeometry3D(); + } else if (type == "parallel3d_vec") { + pGeometry = new CParallelVecProjectionGeometry3D(); + } else if (type == "cone") { + pGeometry = new CConeProjectionGeometry3D(); + } else if (type == "cone_vec") { + pGeometry = new CConeVecProjectionGeometry3D(); + } else { + mexErrMsgTxt("Invalid geometry type.\n"); + return; + } + + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete pGeometry; + delete xml; + return; + } + delete xml; + + // If data is specified, check dimensions + if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { + get3DMatrixDims(prhs[3], dims); + if (pGeometry->getDetectorColCount() != dims[0] || pGeometry->getProjectionCount() != dims[1] || pGeometry->getDetectorRowCount() != dims[2]) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete pGeometry; + return; + } + } + + // Initialize data object + pDataObject3D = new CFloat32ProjectionData3DMemory(pGeometry); + } + + else if (sDataType == "-sinocone") { + // Read geometry + if (!mxIsStruct(prhs[2])) { + mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n"); + } + XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]); + if (!xml) + return; + Config cfg; + cfg.self = xml->getRootNode(); + CConeProjectionGeometry3D* pGeometry = new CConeProjectionGeometry3D(); + if (!pGeometry->initialize(cfg)) { + mexErrMsgTxt("Geometry class not initialized. \n"); + delete xml; + delete pGeometry; + return; + } + delete xml; + // If data is specified, check dimensions + if (nrhs >= 4 && !mex_is_scalar(prhs[3])) { + get3DMatrixDims(prhs[3], dims); + if (pGeometry->getDetectorRowCount() != dims[2] || pGeometry->getProjectionCount() != dims[1] || pGeometry->getDetectorColCount() != dims[0]) { + mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n"); + delete pGeometry; + return; + } + } + // Initialize data object + pDataObject3D = new CFloat32ProjectionData3DMemory(pGeometry); + delete pGeometry; + } + else { + mexErrMsgTxt("Invalid datatype. Please specify '-vol' or '-proj3d'. \n"); + return; + } + + // Check initialization + if (!pDataObject3D->isInitialized()) { + mexErrMsgTxt("Couldn't initialize data object.\n"); + delete pDataObject3D; + return; + } + + // Store data + + // fill with scalar value + if (nrhs < 4 || mex_is_scalar(prhs[3])) { + float32 fValue = 0.0f; + if (nrhs >= 4) + fValue = (float32)mxGetScalar(prhs[3]); + for (int i = 0; i < pDataObject3D->getSize(); ++i) { + pDataObject3D->getData()[i] = fValue; + } + } + // fill with array value + else if (mxIsDouble(prhs[3])) { + double* pdMatlabData = mxGetPr(prhs[3]); + int i = 0; + int col, row, slice; + for (slice = 0; slice < dims[2]; ++slice) { + for (row = 0; row < dims[1]; ++row) { + for (col = 0; col < dims[0]; ++col) { + // TODO: Benchmark and remove triple indexing? + pDataObject3D->getData3D()[slice][row][col] = pdMatlabData[i]; + ++i; + } + } + } + } + else if (mxIsSingle(prhs[3])) { + const float* pfMatlabData = (const float*)mxGetData(prhs[3]); + int i = 0; + int col, row, slice; + for (slice = 0; slice < dims[2]; ++slice) { + for (row = 0; row < dims[1]; ++row) { + for (col = 0; col < dims[0]; ++col) { + // TODO: Benchmark and remove triple indexing? + pDataObject3D->getData3D()[slice][row][col] = pfMatlabData[i]; + ++i; + } + } + } + } + pDataObject3D->updateStatistics(); + + // step4: store data object + int iIndex = CData3DManager::getSingleton().store(pDataObject3D); + + // step5: return data id + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } + +} + +//----------------------------------------------------------------------------------------- +/** + * [id] = astra_mex_io_data('create_cache', config); + */ +void astra_mex_data3d_create_cache(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +// if (nrhs < 2) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// +// if (!mxIsStruct(prhs[1])) { +// mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n"); +// } +// +// // turn MATLAB struct to an XML-based Config object +// XMLDocument* xml = struct2XML("Data3D", prhs[1]); +// Config cfg; +// cfg.self = xml->getRootNode(); +// +// // create dataobject +// string sType = cfg.self->getAttribute("type"); +// int iIndex; +// if (sType == "ProjectionCached") { +// CFloat32ProjectionData3DCached* pData = new CFloat32ProjectionData3DCached(cfg); +// iIndex = CData3DManager::getSingleton().store(pData); +// } +//// else if (sType == "VolumeCached") { +//// CFloat32VolumeData3DCached* pData = new CFloat32VolumeData3DCached(cfg); +//// pData->initialize(cfg); +//// iIndex = CData3DManager::getSingleton().store(pData); +//// } +// +// // step4: set output +// if (1 <= nlhs) { +// plhs[0] = mxCreateDoubleScalar(iIndex); +// } + +} + + +//----------------------------------------------------------------------------------------- +/** + * data = astra_mex_data3d('get', id); + * + * Fetch data from the astra-library to a MATLAB matrix. + * id: identifier of the 3d data object as stored in the astra-library. + * data: MATLAB data + + */ +void astra_mex_data3d_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID)); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + mwSize dims[3]; + dims[0] = pDataObject->getWidth(); + dims[1] = pDataObject->getHeight(); + dims[2] = pDataObject->getDepth(); + + plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); + double* out = mxGetPr(plhs[0]); + + int i = 0; + for (int slice = 0; slice < pDataObject->getDepth(); slice++) { + for (int row = 0; row < pDataObject->getHeight(); row++) { + for (int col = 0; col < pDataObject->getWidth(); col++) { + // TODO: Benchmark and remove triple indexing? + out[i] = pDataObject->getData3D()[slice][row][col]; + ++i; + } + } + } + } + +} + +//----------------------------------------------------------------------------------------- +/** + * data = astra_mex_data3d('get_single', id); + * + * Fetch data from the astra-library to a MATLAB matrix. + * id: identifier of the 3d data object as stored in the astra-library. + * data: MATLAB data + + */ +void astra_mex_data3d_get_single(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID)); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + mwSize dims[3]; + dims[0] = pDataObject->getWidth(); + dims[1] = pDataObject->getHeight(); + dims[2] = pDataObject->getDepth(); + + plhs[0] = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); + float* out = (float *)mxGetData(plhs[0]); + + int i = 0; + for (int slice = 0; slice < pDataObject->getDepth(); slice++) { + for (int row = 0; row < pDataObject->getHeight(); row++) { + for (int col = 0; col < pDataObject->getWidth(); col++) { + // TODO: Benchmark and remove triple indexing? + out[i] = pDataObject->getData3D()[slice][row][col]; + ++i; + } + } + } + } + +} + + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_data3d('store', id, data); + * + * Store MATLAB matrix data in the astra-library. + * id: identifier of the 3d data object as stored in the astra-library. + * data: MATLAB data + + */ +void astra_mex_data3d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CFloat32Data3DMemory* pDataObject = dynamic_cast<CFloat32Data3DMemory*>(astra::CData3DManager::getSingleton().get(iDataID)); + if (!pDataObject || !pDataObject->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsSingle(prhs[2]))) { + mexErrMsgTxt("Data must be single or double."); + return; + } + + // fill with scalar value + if (mex_is_scalar(prhs[2])) { + float32 fValue = (float32)mxGetScalar(prhs[2]); + for (int i = 0; i < pDataObject->getSize(); ++i) { + pDataObject->getData()[i] = fValue; + } + } + // fill with array value + else if (mxIsDouble(prhs[2])) { + mwSize dims[3]; + get3DMatrixDims(prhs[2], dims); + if (dims[0] != pDataObject->getWidth() || dims[1] != pDataObject->getHeight() || dims[2] != pDataObject->getDepth()) { + mexErrMsgTxt("Data object dimensions don't match.\n"); + return; + + } + double* pdMatlabData = mxGetPr(prhs[2]); + int i = 0; + int col, row, slice; + for (slice = 0; slice < dims[2]; ++slice) { + for (row = 0; row < dims[1]; ++row) { + for (col = 0; col < dims[0]; ++col) { + // TODO: Benchmark and remove triple indexing? + pDataObject->getData3D()[slice][row][col] = pdMatlabData[i]; + ++i; + } + } + } + } + else if (mxIsSingle(prhs[2])) { + mwSize dims[3]; + get3DMatrixDims(prhs[2], dims); + if (dims[0] != pDataObject->getWidth() || dims[1] != pDataObject->getHeight() || dims[2] != pDataObject->getDepth()) { + mexErrMsgTxt("Data object dimensions don't match.\n"); + return; + + } + const float* pfMatlabData = (const float *)mxGetData(prhs[2]); + int i = 0; + int col, row, slice; + for (slice = 0; slice < dims[2]; ++slice) { + for (row = 0; row < dims[1]; ++row) { + for (col = 0; col < dims[0]; ++col) { + // TODO: Benchmark and remove triple indexing? + pDataObject->getData3D()[slice][row][col] = pfMatlabData[i]; + ++i; + } + } + } + } + pDataObject->updateStatistics(); +} + + +//----------------------------------------------------------------------------------------- +/** + * [id] = astra_mex_io_data('fetch_slice', id, slicenr); + */ +void astra_mex_data3d_fetch_slice_z(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +// // step1: get input +// if (nrhs < 3) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iDid = (int)(mxGetScalar(prhs[1])); +// int iSliceNr = (int)(mxGetScalar(prhs[2])); +// +// // Get data object +// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); +// if (!pData) { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +// +// CFloat32Data2D* res = NULL; +// // Projection Data +// if (pData->getType() == CFloat32Data3D::PROJECTION) { +// CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); +//// res = pData2->fetchSlice(iSliceNr); +// } +// // Volume Data +// else if (pData->getType() == CFloat32Data3D::VOLUME) { +// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); +//// res = pData2->fetchSliceZ(iSliceNr); +// } +// // Error +// else { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +// +// // store data +// int iIndex = CData2DManager::getSingleton().store(res); +// +// // step4: set output +// if (1 <= nlhs) { +// plhs[0] = mxCreateDoubleScalar(iIndex); +// } +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_io_data('returnSlice', id, slicenr); + */ +void astra_mex_data3d_return_slice_z(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +// // step1: get input +// if (nrhs < 3) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iDid = (int)(mxGetScalar(prhs[1])); +// int iSliceNr = (int)(mxGetScalar(prhs[2])); +// +// // Get data object +// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); +// if (!pData) { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +// +// // Projection Data +// if (pData->getType() == CFloat32Data3D::PROJECTION) { +// CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); +//// TODO: think about returning slices +//// pData2->returnSlice(iSliceNr); +// } +// // Volume Data +// else if (pData->getType() == CFloat32Data3D::VOLUME) { +// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); +//// TODO: think about returning slices +//// pData2->returnSliceZ(iSliceNr); +// } +// // Error +// else { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +} + +//----------------------------------------------------------------------------------------- +/** + * [id] = astra_mex_io_data('fetch_projection', id, slicenr); + */ +void astra_mex_data3d_fetch_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// step1: get input + //if (nrhs < 3) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + //int iProjectionNr = (int)(mxGetScalar(prhs[2])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //CFloat32Data2D* res = NULL; + //// Projection Data + //if (pData->getType() == CFloat32Data3D::PROJECTION) { + // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); + // res = pData2->fetchProjection(iProjectionNr); + //} + //// Error + //else { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + // + //// store data + //int iIndex = CData2DManager::getSingleton().store(res); + + //// step4: set output + //if (1 <= nlhs) { + // plhs[0] = mxCreateDoubleScalar(iIndex); + //} +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_io_data('return_projection', id, slicenr); + */ +void astra_mex_data3d_return_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// step1: get input + //if (nrhs < 3) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + //int iProjectionNr = (int)(mxGetScalar(prhs[2])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //// Projection Data + //if (pData->getType() == CFloat32Data3D::PROJECTION) { + // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); + //// pData2->returnProjection(iProjectionNr); + //} + //// Error + //else { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} +} + +//----------------------------------------------------------------------------------------- +/** + * [id] = astra_mex_io_data('fetch_projection', id, slicenr); + */ +void astra_mex_data3d_fetch_slice_x(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// step1: get input + //if (nrhs < 3) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + //int iSliceNr = (int)(mxGetScalar(prhs[2])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //CFloat32Data2D* res = NULL; + //// Projection Data + //if (pData->getType() == CFloat32Data3D::VOLUME) { + // CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); + // res = pData2->fetchSliceX(iSliceNr); + //} + //// Error + //else { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + // + //// store data + //int iIndex = CData2DManager::getSingleton().store(res); + + //// step4: set output + //if (1 <= nlhs) { + // plhs[0] = mxCreateDoubleScalar(iIndex); + //} +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_io_data('return_slice_x', id, slicenr); + */ +void astra_mex_data3d_return_slice_x(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +// // step1: get input +// if (nrhs < 3) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iDid = (int)(mxGetScalar(prhs[1])); +// int iSliceNr = (int)(mxGetScalar(prhs[2])); +// +// // Get data object +// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); +// if (!pData) { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +// +// // Projection Data +// if (pData->getType() == CFloat32Data3D::VOLUME) { +// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); +//// TODO: think about returning slices +//// pData2->returnSliceX(iSliceNr); +// } +// // Error +// else { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +} + + +//----------------------------------------------------------------------------------------- +/** + * [id] = astra_mex_io_data('fetch_slice_y', id, slicenr); + */ +void astra_mex_data3d_fetch_slice_y(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// step1: get input + //if (nrhs < 3) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + //int iSliceNr = (int)(mxGetScalar(prhs[2])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //CFloat32Data2D* res = NULL; + //// Projection Data + //if (pData->getType() == CFloat32Data3D::VOLUME) { + // CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); + // res = pData2->fetchSliceY(iSliceNr); + //} + //// Error + //else { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + // + //// store data + //int iIndex = CData2DManager::getSingleton().store(res); + + //// step4: set output + //if (1 <= nlhs) { + // plhs[0] = mxCreateDoubleScalar(iIndex); + //} +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_io_data('return_slice_y', id, slicenr); + */ +void astra_mex_data3d_return_slice_y(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ +// // step1: get input +// if (nrhs < 3) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iDid = (int)(mxGetScalar(prhs[1])); +// int iSliceNr = (int)(mxGetScalar(prhs[2])); +// +// // Get data object +// CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); +// if (!pData) { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +// +// // Projection Data +// if (pData->getType() == CFloat32Data3D::VOLUME) { +// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); +//// TODO: think about returning slices +//// pData2->returnSliceY(iSliceNr); +// } +// // Error +// else { +// mexErrMsgTxt("DataObject not valid. \n"); +// return; +// } +} + +//----------------------------------------------------------------------------------------- +/** + * [dim_x dim_y dim_z] = astra_mex_io_data('dimensions', id); + */ +void astra_mex_data3d_dimensions(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iDid = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CFloat32Data3D* pData; + if (!(pData = CData3DManager::getSingleton().get(iDid))) { + mexErrMsgTxt("DataObject not valid. \n"); + return; + } + + // step3: output + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(pData->getWidth()); + } + if (2 <= nlhs) { + plhs[1] = mxCreateDoubleScalar(pData->getHeight()); + } + if (3 <= nlhs) { + plhs[2] = mxCreateDoubleScalar(pData->getDepth()); + } +} + +//----------------------------------------------------------------------------------------- +/** + * [geom] = astra_mex_data3d('geometry', id); + */ +void astra_mex_data3d_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// Get input + //if (nrhs < 2) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //// Projection Data + //if (pData->getType() == CFloat32Data3D::PROJECTION) { + // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); + // CProjectionGeometry3D* pProjGeom = pData2->getGeometry(); + // XMLDocument* config = pProjGeom->toXML(); + + // if (1 <= nlhs) { + // plhs[0] = XML2struct(config); + // } + //} + //// Volume Data + //else if (pData->getType() == CFloat32Data3D::VOLUME) { + //// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); + //// CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr); + //// if (1 <= nlhs) { + //// plhs[0] = createVolumeGeometryStruct(pVolGeom); + //// } + //} + //// Error + //else { + // mexErrMsgTxt("Type not valid. \n"); + // return; + //} +} + +//----------------------------------------------------------------------------------------- +/** + * [geom_xml] = astra_mex_data3d('geometry_xml', id); + */ +void astra_mex_data3d_geometry_xml(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// Get input + //if (nrhs < 2) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iDid = (int)(mxGetScalar(prhs[1])); + + //// Get data object + //CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid); + //if (!pData) { + // mexErrMsgTxt("DataObject not valid. \n"); + // return; + //} + + //// Projection Data + //if (pData->getType() == CFloat32Data3D::PROJECTION) { + // CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData); + // CProjectionGeometry3D* pProjGeom = pData2->getGeometry(); + // XMLDocument* config = pProjGeom->toXML(); + + // if (1 <= nlhs) { + // plhs[0] = mxCreateString(config->getRootNode()->toString().c_str()); + // } + //} + //// Volume Data + //else if (pData->getType() == CFloat32Data3D::VOLUME) { + //// CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData); + //// CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr); + //// if (1 <= nlhs) { + //// plhs[0] = createVolumeGeometryStruct(pVolGeom); + //// } + //} + //// Error + //else { + // mexErrMsgTxt("Type not valid. \n"); + // return; + //} +} +//----------------------------------------------------------------------------------------- +/** + * astra_mex_data3d('delete', did1, did2, ...); + */ +void astra_mex_data3d_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iDataID = (int)(mxGetScalar(prhs[i])); + CData3DManager::getSingleton().remove(iDataID); + } +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_data3d('clear'); + */ +void astra_mex_data3d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CData3DManager::getSingleton().clear(); +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_data3d('info'); + */ +void astra_mex_data3d_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("%s", astra::CData3DManager::getSingleton().info().c_str()); +} + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: create, create_cache, get, get_single, delete, clear, info\n"); + mexPrintf(" fetch_projection, return_projection, fetch_slice[_z],\n"); + mexPrintf(" return_slice[_z], fetch_slice_x, return slice_x\n"); + mexPrintf(" fetch_slice_y, return slice_y, dimensions, geometry\n"); + mexPrintf(" geometry_xml\n"); +} + + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_io_data(mode,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // 3D data + if (sMode == std::string("create")) { + astra_mex_data3d_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("create_cache")) { + astra_mex_data3d_create_cache(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("get")) { + astra_mex_data3d_get(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("get_single")) { + astra_mex_data3d_get_single(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("store") || + sMode == std::string("set")) { + astra_mex_data3d_store(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("delete")) { + astra_mex_data3d_delete(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_data3d_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == "info") { + astra_mex_data3d_info(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("fetch_projection")) { + astra_mex_data3d_fetch_projection(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("return_projection")) { + astra_mex_data3d_return_projection(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("fetch_slice") || sMode == std::string("fetch_slice_z")) { + astra_mex_data3d_fetch_slice_z(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("return_slice") || sMode == std::string("return_slice_z")) { + astra_mex_data3d_return_slice_z(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("fetch_slice_x")) { + astra_mex_data3d_fetch_slice_x(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("return_slice_x")) { + astra_mex_data3d_return_slice_x(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("fetch_slice_y")) { + astra_mex_data3d_fetch_slice_y(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("return_slice_y")) { + astra_mex_data3d_return_slice_y(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("dimensions")) { + astra_mex_data3d_dimensions(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("geometry")) { + astra_mex_data3d_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("geometry_xml")) { + astra_mex_data3d_geometry_xml(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/matlab/mex/astra_mex_data3d_vc08.vcproj b/matlab/mex/astra_mex_data3d_vc08.vcproj new file mode 100644 index 0000000..2e69c16 --- /dev/null +++ b/matlab/mex/astra_mex_data3d_vc08.vcproj @@ -0,0 +1,588 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_data3d" + ProjectGUID="{0BEC029B-0929-4BF9-BD8B-9C9806A52065}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_data3d_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp new file mode 100644 index 0000000..accaab5 --- /dev/null +++ b/matlab/mex/astra_mex_matrix_c.cpp @@ -0,0 +1,437 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_matrix_c.cpp + * + * \brief Create sparse (projection) matrices in the ASTRA workspace + */ +#include <mex.h> +#include "mexHelpFunctions.h" + +#include <list> + +#include "astra/Globals.h" + +#include "astra/AstraObjectManager.h" + +#include "astra/SparseMatrix.h" + +using namespace std; +using namespace astra; + +//----------------------------------------------------------------------------------------- +/** astra_mex_matrix('delete', id1, id2, ...); + * + * Delete one or more data objects currently stored in the astra-library. + * id1, id2, ... : identifiers of the 2d data objects as stored in the astra-library. + */ +void astra_mex_matrix_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + // step2: delete all specified data objects + for (int i = 1; i < nrhs; i++) { + int iDataID = (int)(mxGetScalar(prhs[i])); + CMatrixManager::getSingleton().remove(iDataID); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_matrix('clear'); + * + * Delete all data objects currently stored in the astra-library. + */ +void astra_mex_matrix_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CMatrixManager::getSingleton().clear(); +} + + + +static bool matlab_to_astra(const mxArray* _rhs, CSparseMatrix* _pMatrix) +{ + // Check input + if (!mxIsSparse (_rhs)) { + mexErrMsgTxt("Argument is not a valid MATLAB sparse matrix.\n"); + return false; + } + if (!_pMatrix->isInitialized()) { + mexErrMsgTxt("Couldn't initialize data object.\n"); + return false; + } + + unsigned int iHeight = mxGetM(_rhs); + unsigned int iWidth = mxGetN(_rhs); + unsigned long lSize = mxGetNzmax(_rhs); + + if (_pMatrix->m_lSize < lSize || _pMatrix->m_iHeight < iHeight) { + // TODO: support resizing? + mexErrMsgTxt("Matrix too large to store in this object.\n"); + return false; + } + + // Transpose matrix, as matlab stores a matrix column-by-column + // but we want it row-by-row. + // 1. Compute sizes of rows. We store these in _pMatrix->m_plRowStarts. + // 2. Fill data structure + // Complexity: O( #rows + #entries ) + + for (unsigned int i = 0; i <= iHeight; ++i) + _pMatrix->m_plRowStarts[i] = 0; + + mwIndex *colStarts = mxGetJc(_rhs); + mwIndex *rowIndices = mxGetIr(_rhs); + double *floatValues = 0; + bool *boolValues = 0; + bool bLogical = mxIsLogical(_rhs); + if (bLogical) + boolValues = mxGetLogicals(_rhs); + else + floatValues = mxGetPr(_rhs); + + for (mwIndex i = 0; i < colStarts[iWidth]; ++i) { + unsigned int iRow = rowIndices[i]; + assert(iRow < iHeight); + _pMatrix->m_plRowStarts[iRow+1]++; + } + + // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in row i + + for (unsigned int i = 1; i <= iHeight; ++i) + _pMatrix->m_plRowStarts[i] += _pMatrix->m_plRowStarts[i-1]; + + // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in rows <= i, + // so the intended start of row i+1 + + int iCol = 0; + for (mwIndex i = 0; i < colStarts[iWidth]; ++i) { + while (i >= colStarts[iCol+1]) + iCol++; + + unsigned int iRow = rowIndices[i]; + assert(iRow < iHeight); + float32 fVal; + if (bLogical) + fVal = (float32)boolValues[i]; + else + fVal = (float32)floatValues[i]; + + unsigned long lIndex = _pMatrix->m_plRowStarts[iRow]++; + _pMatrix->m_pfValues[lIndex] = fVal; + _pMatrix->m_piColIndices[lIndex] = iCol; + } + + // Now _pMatrix->m_plRowStarts[i] is the start of row i+1 + + for (unsigned int i = iHeight; i > 0; --i) + _pMatrix->m_plRowStarts[i] = _pMatrix->m_plRowStarts[i-1]; + _pMatrix->m_plRowStarts[0] = 0; + +#if 0 + // Debugging: dump matrix + for (unsigned int i = 0; i < iHeight; ++i) { + printf("Row %d: %ld-%ld\n", i, _pMatrix->m_plRowStarts[i], _pMatrix->m_plRowStarts[i+1]); + for (unsigned long j = _pMatrix->m_plRowStarts[i]; j < _pMatrix->m_plRowStarts[i+1]; ++j) { + printf("(%d,%d) = %f\n", i, _pMatrix->m_piColIndices[j], _pMatrix->m_pfValues[j]); + } + } +#endif + + return true; +} + +static bool astra_to_matlab(const CSparseMatrix* _pMatrix, mxArray*& _lhs) +{ + if (!_pMatrix->isInitialized()) { + mexErrMsgTxt("Uninitialized data object.\n"); + return false; + } + + unsigned int iHeight = _pMatrix->m_iHeight; + unsigned int iWidth = _pMatrix->m_iWidth; + unsigned long lSize = _pMatrix->m_lSize; + + _lhs = mxCreateSparse(iHeight, iWidth, lSize, mxREAL); + if (!mxIsSparse (_lhs)) { + mexErrMsgTxt("Couldn't initialize matlab sparse matrix.\n"); + return false; + } + + mwIndex *colStarts = mxGetJc(_lhs); + mwIndex *rowIndices = mxGetIr(_lhs); + double *floatValues = mxGetPr(_lhs); + + for (unsigned int i = 0; i <= iWidth; ++i) + colStarts[i] = 0; + + for (unsigned int i = 0; i < _pMatrix->m_plRowStarts[iHeight]; ++i) { + unsigned int iCol = _pMatrix->m_piColIndices[i]; + assert(iCol < iWidth); + colStarts[iCol+1]++; + } + // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in row i + + for (unsigned int i = 1; i <= iWidth; ++i) + colStarts[i] += colStarts[i-1]; + // Now _pMatrix->m_plRowStarts[i+1] is the number of entries in rows <= i, + // so the intended start of row i+1 + + unsigned int iRow = 0; + for (unsigned int i = 0; i < _pMatrix->m_plRowStarts[iHeight]; ++i) { + while (i >= _pMatrix->m_plRowStarts[iRow+1]) + iRow++; + + unsigned int iCol = _pMatrix->m_piColIndices[i]; + assert(iCol < iWidth); + double fVal = _pMatrix->m_pfValues[i]; + unsigned long lIndex = colStarts[iCol]++; + floatValues[lIndex] = fVal; + rowIndices[lIndex] = iRow; + } + // Now _pMatrix->m_plRowStarts[i] is the start of row i+1 + + for (unsigned int i = iWidth; i > 0; --i) + colStarts[i] = colStarts[i-1]; + colStarts[0] = 0; + + return true; +} + +//----------------------------------------------------------------------------------------- +/** id = astra_mex_matrix('create', data); + * + * Create a new matrix object in the astra-library. + * data: a sparse MATLAB matrix containing the data. + * id: identifier of the matrix object as it is now stored in the astra-library. + */ +void astra_mex_matrix_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray* prhs[]) +{ + // step1: get datatype + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + if (!mxIsSparse (prhs[1])) { + mexErrMsgTxt("Argument is not a valid MATLAB sparse matrix.\n"); + return; + } + + unsigned int iHeight = mxGetM(prhs[1]); + unsigned int iWidth = mxGetN(prhs[1]); + unsigned long lSize = mxGetNzmax(prhs[1]); + + CSparseMatrix* pMatrix = new CSparseMatrix(iHeight, iWidth, lSize); + + // Check initialization + if (!pMatrix->isInitialized()) { + mexErrMsgTxt("Couldn't initialize data object.\n"); + delete pMatrix; + return; + } + + bool bResult = matlab_to_astra(prhs[1], pMatrix); + + if (!bResult) { + mexErrMsgTxt("Failed to create data object.\n"); + delete pMatrix; + return; + } + + // store data object + int iIndex = CMatrixManager::getSingleton().store(pMatrix); + + // return data id + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_matrix('store', id, data); + * + * Store a sparse MATLAB matrix in an existing astra matrix dataobject. + * id: identifier of the 2d data object as stored in the astra-library. + * data: a sparse MATLAB matrix. + */ +void astra_mex_matrix_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID); + if (!pMatrix || !pMatrix->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + bool bResult = matlab_to_astra(prhs[2], pMatrix); + if (!bResult) { + mexErrMsgTxt("Failed to store matrix.\n"); + } +} + +//----------------------------------------------------------------------------------------- +/** geom = astra_mex_matrix('get_size', id); + * + * Fetch the dimensions and size of a matrix stored in the astra-library. + * id: identifier of the 2d data object as stored in the astra-library. + * geom: a 1x2 matrix containing [rows, columns] + */ +void astra_mex_matrix_get_size(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID); + if (!pMatrix || !pMatrix->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + // TODO +} + +//----------------------------------------------------------------------------------------- +/** data = astra_mex_matrix('get', id); + * + * Fetch data from the astra-library to a MATLAB matrix. + * id: identifier of the matrix data object as stored in the astra-library. + * data: MATLAB + */ +void astra_mex_matrix_get(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: check input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + if (!mxIsDouble(prhs[1])) { + mexErrMsgTxt("Identifier should be a scalar value. \n"); + return; + } + int iDataID = (int)(mxGetScalar(prhs[1])); + + // step2: get data object + CSparseMatrix* pMatrix = astra::CMatrixManager::getSingleton().get(iDataID); + if (!pMatrix || !pMatrix->isInitialized()) { + mexErrMsgTxt("Data object not found or not initialized properly.\n"); + return; + } + + // create output + if (1 <= nlhs) { + bool bResult = astra_to_matlab(pMatrix, plhs[0]); + if (!bResult) { + mexErrMsgTxt("Failed to get matrix.\n"); + } + } + +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_matrix('info'); + * + * Print information about all the matrix objects currently stored in the astra-library. + */ +void astra_mex_matrix_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("%s", astra::CMatrixManager::getSingleton().info().c_str()); +} + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: get, delete, clear, store, create, get_size, info\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_matrix(type,...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + + // INPUT0: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == std::string("get")) { + astra_mex_matrix_get(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("delete")) { + astra_mex_matrix_delete(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_matrix_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("store")) { + astra_mex_matrix_store(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("create")) { + astra_mex_matrix_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("get_size")) { + astra_mex_matrix_get_size(nlhs, plhs, nrhs, prhs); + } else if (sMode == std::string("info")) { + astra_mex_matrix_info(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + + return; +} + + diff --git a/matlab/mex/astra_mex_matrix_vc08.vcproj b/matlab/mex/astra_mex_matrix_vc08.vcproj new file mode 100644 index 0000000..47509f6 --- /dev/null +++ b/matlab/mex/astra_mex_matrix_vc08.vcproj @@ -0,0 +1,591 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_matrix" + ProjectGUID="{9D041710-2119-4230-BCF2-5FBE753FDE49}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""$(CUDA_INC_PATH)";$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + BrowseInformation="1" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_matrix_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp new file mode 100644 index 0000000..1385863 --- /dev/null +++ b/matlab/mex/astra_mex_projector3d_c.cpp @@ -0,0 +1,433 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_projector3d_c.cpp + * + * \brief Create and manage 3d projectors in the ASTRA workspace + */ + +#include <mex.h> +#include "mexHelpFunctions.h" + +#include "astra/Globals.h" + +#include "astra/Projector3D.h" +#include "astra/AstraObjectManager.h" +#include "astra/AstraObjectFactory.h" + +#include "astra/ProjectionGeometry3D.h" +#include "astra/VolumeGeometry3D.h" + +#include <map> +#include <vector> + +using namespace std; +using namespace astra; + +//----------------------------------------------------------------------------------------- +/** +* [pid] = astra_mex_projector('create', cfgstruct); +*/ +void astra_mex_projector3d_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + if (!mxIsStruct(prhs[1])) { + mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n"); + } + + // turn MATLAB struct to an XML-based Config object + XMLDocument* xml = struct2XML("Projector3D", prhs[1]); + Config cfg; + cfg.self = xml->getRootNode(); + + // create algorithm + CProjector3D* pProj = CProjector3DFactory::getSingleton().create(cfg); + if (pProj == NULL) { + mexErrMsgTxt("Error creating Projector3D. \n"); + return; + } + + // store projector + int iIndex = CProjector3DManager::getSingleton().store(pProj); + + // step4: set output + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } + + } + +//----------------------------------------------------------------------------------------- +/** +* astra_mex_projector3d('destroy', pid1, pid2, ...); +*/ +void astra_mex_projector3d_destroy(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iPid = (int)(mxGetScalar(prhs[i])); + CProjector3DManager::getSingleton().remove(iPid); + } +} + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_projector3d('clear'); + */ +void astra_mex_projector3d_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CProjector3DManager::getSingleton().clear(); +} + + +//----------------------------------------------------------------------------------------- +/** +* [proj_geom] = astra_mex_projector3d('get_projection_geometry', pid); +*/ +void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector3D* pProjector; + if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) { + mexErrMsgTxt("Projector not found.\n"); + return; + } + + // step3: get projection_geometry and turn it into a MATLAB struct + //if (1 <= nlhs) { + // plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry()); + //} +} + +//----------------------------------------------------------------------------------------- +/** +* [recon_geom] = astra_mex_projector3d('get_volume_geometry', pid); +*/ +void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector3D* pProjector; + if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) { + mexErrMsgTxt("Projector not found.\n"); + return; + } + + // step3: get projection_geometry and turn it into a MATLAB struct + //if (1 <= nlhs) { + // plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry()); + //} +} + +//----------------------------------------------------------------------------------------- +/** +* [weights] = astra_mex_projector3d('weights_single_ray', pid, projection_index, detector_index); +*/ +void astra_mex_projector_weights_single_ray(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + //// step1: get input + //if (nrhs < 4) { + // mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + // return; + //} + //int iPid = (int)(mxGetScalar(prhs[1])); + //int iProjectionIndex = (int)(mxGetScalar(prhs[2])); + //int iDetectorIndex = (int)(mxGetScalar(prhs[3])); + + //// step2: get projector + //CProjector3D* pProjector; + //if (!(pProjector = CProjector3DManager::getSingleton().get(iPid))) { + // mexErrMsgTxt("Projector not found.\n"); + // return; + //} + // + //// step3: create output vars + //int iStoredPixelCount; + //int iMaxPixelCount = pProjector->getProjectionWeightsCount(iProjectionIndex); + //SWeightedPixel* pPixelsWeights = new SWeightedPixel3D[iMaxPixelCount]; + // + //// step4: perform operation + //pProjector->computeSingleRayWeights(iProjectionIndex, + // iDetectorIndex, + // pPixelsWeights, + // iMaxPixelCount, + // iStoredPixelCount); + + //// step5: return output + //if (1 <= nlhs) { + // mwSize dims[2]; + // dims[0] = iStoredPixelCount; + // dims[1] = 2; + + // plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); + // double* out = mxGetPr(plhs[0]); + + // for (int col = 0; col < iStoredPixelCount; col++) { + // out[col] = pPixelsWeights[col].m_iIndex; + // out[iStoredPixelCount+col] = pPixelsWeights[col].m_fWeight; + // //cout << pPixelsWeights[col].m_iIndex << " " << pPixelsWeights[col].m_fWeight <<endl; + // } + //} + // + //// garbage collection + //delete[] pPixelsWeights; +} + +////----------------------------------------------------------------------------------------- +///** +//* [weights] = astra_mex_projector('weights_projection', pid, projection_index); +//*/ +//void astra_mex_projector_weights_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +//{ +// // step1: get input +// if (nrhs < 3) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iPid = (int)(mxGetScalar(prhs[1])); +// int iProjectionIndex = (int)(mxGetScalar(prhs[2])); +// +// // step2: get projector +// CProjector2D* pProjector; +// if (!(pProjector = CProjectorManager::getSingleton().get(iPid))) { +// mexErrMsgTxt("Projector not found.\n"); +// return; +// } +// +// // step3: create output vars +// SWeightedPixel2D* pPixelsWheights = new SWeightedPixel2D[pProjector->getProjectionWeightsCount(iProjectionIndex)]; +// int* piRayStoredPixelCount = new int[pProjector->getProjectionGeometry()->getDetectorCount()]; +// +// // step4: perform operation +// pProjector->computeProjectionRayWeights(iProjectionIndex, pPixelsWheights, piRayStoredPixelCount); +// +// // step5: return output +// if (1 <= nlhs) { +// // get basic values +// int iMatrixSize = pProjector->getVolumeGeometry()->getWindowLengthX() * +// pProjector->getVolumeGeometry()->getWindowLengthY(); +// int iDetectorCount = pProjector->getProjectionGeometry()->getDetectorCount(); +// int iTotalStoredPixelCount = 0; +// for (int i = 0; i < iDetectorCount; i++) { +// iTotalStoredPixelCount += piRayStoredPixelCount[i]; +// } +// +// // create matlab sparse matrix +// plhs[0] = mxCreateSparse(iMatrixSize, // number of rows (#pixels) +// iDetectorCount, // number of columns (#detectors) +// iTotalStoredPixelCount, // number of non-zero elements +// mxREAL); // element type +// double* values = mxGetPr(plhs[0]); +// mwIndex* rows = mxGetIr(plhs[0]); +// mwIndex* cols = mxGetJc(plhs[0]); +// +// int currentBase = 0; +// int currentIndex = 0; +// for (int i = 0; i < iDetectorCount; i++) { +// for (int j = 0; j < piRayStoredPixelCount[i]; j++) { +// values[currentIndex + j] = pPixelsWheights[currentBase + j].m_fWeight; +// rows[currentIndex + j] = pPixelsWheights[currentBase + j].m_iIndex; +// } +// +// currentBase += pProjector->getProjectionWeightsCount(iProjectionIndex) / pProjector->getProjectionGeometry()->getDetectorCount(); +// currentIndex += piRayStoredPixelCount[i]; +// } +// cols[0] = piRayStoredPixelCount[0]; +// for (int j = 1; j < iDetectorCount; j++) { +// cols[j] = cols[j-1] + piRayStoredPixelCount[j]; +// } +// cols[iDetectorCount] = iTotalStoredPixelCount; +// } +// +//} +// +////----------------------------------------------------------------------------------------- +///** +//* output = astra_mex_projector('splat', pid, x, y); +//*/ +//void astra_mex_projector_splat(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +//{ +// // step1: get input +// if (nrhs < 4) { +// mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); +// return; +// } +// int iPid = (int)(mxGetScalar(prhs[1])); +// int iX = (int)(mxGetScalar(prhs[2])); +// int iY = (int)(mxGetScalar(prhs[3])); +// +// // step2: get projector +// CProjector2D* pProjector; +// if (!(pProjector = CProjectorManager::getSingleton().get(iPid))) { +// mexErrMsgTxt("Projector not found.\n"); +// return; +// } +// +// // step3: perform action +// vector<SDetector2D> detinfo = pProjector->projectPoint(iX, iY); +// +// // step4: output +// if (nlhs <= 1) { +// plhs[0] = mxCreateDoubleMatrix(detinfo.size(), // # rows +// 2, // # cols +// mxREAL); // datatype 32-bits +// double* out = mxGetPr(plhs[0]); +// +// // fill up output +// int i = 0; +// for (int x = 0; x < detinfo.size() ; x++) { +// out[i] = detinfo[x].m_iAngleIndex; +// i++; +// } +// for (int x = 0; x < detinfo.size() ; x++) { +// out[i] = detinfo[x].m_iDetectorIndex; +// i++; +// } +// } +// +// +//} + +//----------------------------------------------------------------------------------------- +/** result = astra_mex_projector3d('is_cuda', id); + * + * Return is the specified projector is a cuda projector. + * id: identifier of the projector object as stored in the astra-library. + */ +void astra_mex_projector3d_is_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector3D* pProjector = CProjector3DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + +#ifdef ASTRA_CUDA + CCudaProjector3D* pCP = dynamic_cast<CCudaProjector3D*>(pProjector); + plhs[0] = mxCreateLogicalScalar(pCP ? 1 : 0); +#else + plhs[0] = mxCreateLogicalScalar(0); +#endif +} + + +//----------------------------------------------------------------------------------------- +/** + * astra_mex_projector3d('help'); + */ +void astra_mex_projector3d_help(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + cout << "astra_mex_projector3d help:" <<endl; + cout << "---------------------------" <<endl; +} + + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: create, delete, clear, get_projection_geometry,\n"); + mexPrintf(" get_volume_geometry, weights_single_ray, weights_projection\n"); + mexPrintf(" splat, is_cuda\n"); +} + +//----------------------------------------------------------------------------------------- +/** + * [pid] = astra_mex_projector('read', projection_geometry, reconstruction_geometry); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + // INPUT: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == "create") { + astra_mex_projector3d_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == "delete") { + astra_mex_projector3d_destroy(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_projector3d_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == "get_projection_geometry") { + astra_mex_projector3d_get_projection_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == "get_volume_geometry") { + astra_mex_projector3d_get_reconstruction_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == "weights_single_ray") { + astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs); + //} else if (sMode == "weights_projection") { + // astra_mex_projector_weights_projection(nlhs, plhs, nrhs, prhs); + //} else if (sMode == "splat") { + // astra_mex_projector_splat(nlhs, plhs, nrhs, prhs); + } else if (sMode == "is_cuda") { + astra_mex_projector3d_is_cuda(nlhs, plhs, nrhs, prhs); + } else if (sMode == "help") { + astra_mex_projector3d_help(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + return; +} + + diff --git a/matlab/mex/astra_mex_projector3d_vc08.vcproj b/matlab/mex/astra_mex_projector3d_vc08.vcproj new file mode 100644 index 0000000..bedc53b --- /dev/null +++ b/matlab/mex/astra_mex_projector3d_vc08.vcproj @@ -0,0 +1,588 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_projector3d" + ProjectGUID="{F94CCD79-AA11-42DF-AC8A-6C9D2238A883}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_projector3d_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp new file mode 100644 index 0000000..5cbe502 --- /dev/null +++ b/matlab/mex/astra_mex_projector_c.cpp @@ -0,0 +1,510 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file astra_mex_projector_c.cpp + * + * \brief Create and manage 2d projectors in the ASTRA workspace + */ +#include "astra/Globals.h" + +#include <mex.h> +#include "mexHelpFunctions.h" + +#include "astra/AstraObjectManager.h" +#include "astra/Projector2D.h" +#include "astra/AstraObjectFactory.h" + +#include "astra/Float32VolumeData2D.h" + +#include "astra/ProjectionGeometry2D.h" +#include "astra/ParallelProjectionGeometry2D.h" +#include "astra/VolumeGeometry2D.h" + + +#include <map> +#include <vector> + +using namespace std; +using namespace astra; + +//----------------------------------------------------------------------------------------- +/** id = astra_mex_projector('create', cfg); + * + * Create and configure a new projector object. + * cfg: MATLAB struct containing the configuration parameters, see doxygen documentation for details. + * id: identifier of the projector object as it is now stored in the astra-library. + */ +void astra_mex_projector_create(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + int iIndex = 0; + + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + if (!mxIsStruct(prhs[1])) { + mexErrMsgTxt("Argument 1 not a valid MATLAB struct. \n"); + } + + + // turn MATLAB struct to an XML-based Config object + XMLDocument* xml = struct2XML("Projector2D", prhs[1]); + Config cfg; + cfg.self = xml->getRootNode(); + + // create algorithm + CProjector2D* pProj = CProjector2DFactory::getSingleton().create(cfg); + if (pProj == NULL) { + delete xml; + mexErrMsgTxt("Error creating projector. \n"); + return; + } + + delete xml; + + // store projector + iIndex = CProjector2DManager::getSingleton().store(pProj); + + // step4: set output + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_projector('delete', id1, id2, ...); + * + * Delete one or more projector objects currently stored in the astra-library. + * id1, id2, ... : identifiers of the projector objects as stored in the astra-library. + */ +void astra_mex_projector_delete(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + + for (int i = 1; i < nrhs; i++) { + int iPid = (int)(mxGetScalar(prhs[i])); + CProjector2DManager::getSingleton().remove(iPid); + } +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_projector('clear'); + * + * Delete all projector objects currently stored in the astra-library. + */ +void astra_mex_projector_clear(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + CProjector2DManager::getSingleton().clear(); +} + +//----------------------------------------------------------------------------------------- +/** astra_mex_projector('info'); + * + * Print information about all the projector objects currently stored in the astra-library. + */ +void astra_mex_projector_info(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + mexPrintf("%s", astra::CProjector2DManager::getSingleton().info().c_str()); +} + +//----------------------------------------------------------------------------------------- +/** proj_geom = astra_mex_projector('projection_geometry', id); + * + * Fetch the projection geometry of a certain projector. + * id: identifier of the projector object as stored in the astra-library. + * proj_geom: MATLAB struct containing all information about the projection geometry +*/ +void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + // step3: get projection_geometry and turn it into a MATLAB struct + if (1 <= nlhs) { + plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry()); + } +} + +//----------------------------------------------------------------------------------------- +/** vol_geom = astra_mex_projector('volume_geometry', id); + * + * Fetch the volume geometry of a certain projector. + * id: identifier of the projector object as stored in the astra-library. + * vol_geom: MATLAB struct containing all information about the volume geometry + */ +void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: read input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + // step3: get projection_geometry and turn it into a MATLAB struct + if (1 <= nlhs) { + plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry()); + } +} + +//----------------------------------------------------------------------------------------- +/** weights = astra_mex_projector('weights_single_ray', id, projection_index, detector_index); + * + * Calculate the nonzero weights of a certain projection ray. + * id: identifier of the projector object as stored in the astra-library. + * projection_index: index of the projection angle + * detector_index: index of the detector + * weights: list of computed weights [pixel_index, weight] + */ +void astra_mex_projector_weights_single_ray(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 4) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + int iProjectionIndex = (int)(mxGetScalar(prhs[2])); + int iDetectorIndex = (int)(mxGetScalar(prhs[3])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + // step3: create output vars + int iStoredPixelCount; + int iMaxPixelCount = pProjector->getProjectionWeightsCount(iProjectionIndex); + SPixelWeight* pPixelsWeights = new SPixelWeight[iMaxPixelCount]; + + // step4: perform operation + pProjector->computeSingleRayWeights(iProjectionIndex, + iDetectorIndex, + pPixelsWeights, + iMaxPixelCount, + iStoredPixelCount); + + // step5: return output + if (1 <= nlhs) { + mwSize dims[2]; + dims[0] = iStoredPixelCount; + dims[1] = 2; + + plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); + double* out = mxGetPr(plhs[0]); + + for (int col = 0; col < iStoredPixelCount; col++) { + out[col] = pPixelsWeights[col].m_iIndex; + out[iStoredPixelCount+col] = pPixelsWeights[col].m_fWeight; + } + } + + // garbage collection + delete[] pPixelsWeights; +} + +//----------------------------------------------------------------------------------------- +/** weights = astra_mex_projector('weights_projection', id, projection_index); + * + * Calculate the nonzero weights of all rays in a certain projection. + * id: identifier of the projector object as stored in the astra-library. + * projection_index: index of the projection angle + * weights: sparse matrix containing the rows of the projection matric belonging to the requested projection angle. + */ +void astra_mex_projector_weights_projection(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 3) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + int iProjectionIndex = (int)(mxGetScalar(prhs[2])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + // step3: create output vars + SPixelWeight* pPixelsWheights = new SPixelWeight[pProjector->getProjectionWeightsCount(iProjectionIndex)]; + int* piRayStoredPixelCount = new int[pProjector->getProjectionGeometry()->getDetectorCount()]; + + // step4: perform operation + pProjector->computeProjectionRayWeights(iProjectionIndex, pPixelsWheights, piRayStoredPixelCount); + + // step5: return output + if (1 <= nlhs) { + // get basic values + int iMatrixSize = pProjector->getVolumeGeometry()->getWindowLengthX() * + pProjector->getVolumeGeometry()->getWindowLengthY(); + int iDetectorCount = pProjector->getProjectionGeometry()->getDetectorCount(); + int iTotalStoredPixelCount = 0; + for (int i = 0; i < iDetectorCount; i++) { + iTotalStoredPixelCount += piRayStoredPixelCount[i]; + } + + // create matlab sparse matrix + plhs[0] = mxCreateSparse(iMatrixSize, // number of rows (#pixels) + iDetectorCount, // number of columns (#detectors) + iTotalStoredPixelCount, // number of non-zero elements + mxREAL); // element type + double* values = mxGetPr(plhs[0]); + mwIndex* rows = mxGetIr(plhs[0]); + mwIndex* cols = mxGetJc(plhs[0]); + + int currentBase = 0; + int currentIndex = 0; + for (int i = 0; i < iDetectorCount; i++) { + for (int j = 0; j < piRayStoredPixelCount[i]; j++) { + values[currentIndex + j] = pPixelsWheights[currentBase + j].m_fWeight; + rows[currentIndex + j] = pPixelsWheights[currentBase + j].m_iIndex; + } + + currentBase += pProjector->getProjectionWeightsCount(iProjectionIndex) / pProjector->getProjectionGeometry()->getDetectorCount(); + currentIndex += piRayStoredPixelCount[i]; + } + cols[0] = piRayStoredPixelCount[0]; + for (int j = 1; j < iDetectorCount; j++) { + cols[j] = cols[j-1] + piRayStoredPixelCount[j]; + } + cols[iDetectorCount] = iTotalStoredPixelCount; + } + + delete[] pPixelsWheights; + delete[] piRayStoredPixelCount; +} + +//----------------------------------------------------------------------------------------- +/** hit_detectors = astra_mex_projector('splat', id, col, row); + * + * Create a list of detector indices which have a nonzero contribution to the projection matrix for a pixel [row,col]. + * id: identifier of the projector object as stored in the astra-library. + * col: column of the pixel + * row: row of the pixel + * hit_detectors: list of detector indices [angle_index, det_index] that are hit + */ +void astra_mex_projector_splat(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 4) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + int iX = (int)(mxGetScalar(prhs[2])); + int iY = (int)(mxGetScalar(prhs[3])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + // step3: perform action + vector<SDetector2D> detinfo = pProjector->projectPoint(iX, iY); + + // step4: output + if (nlhs <= 1) { + plhs[0] = mxCreateDoubleMatrix(detinfo.size(), // # rows + 2, // # cols + mxREAL); // datatype 32-bits + double* out = mxGetPr(plhs[0]); + + // fill up output + int i = 0; + int x; + for (x = 0; x < detinfo.size(); ++x) { + out[i] = detinfo[x].m_iAngleIndex; + ++i; + } + for (x = 0; x < detinfo.size(); ++x) { + out[i] = detinfo[x].m_iDetectorIndex; + ++i; + } + } + + +} + +//----------------------------------------------------------------------------------------- +/** matrix_id = astra_mex_projector('matrix', id); + * + * Create an explicit projection matrix for this projector. + * It returns an ID usable with astra_mex_matrix(). + * id: identifier of the projector object as stored in the astra-library. + */ +void astra_mex_projector_matrix(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + + CSparseMatrix* pMatrix = pProjector->getMatrix(); + if (!pMatrix || !pMatrix->isInitialized()) { + mexErrMsgTxt("Couldn't initialize data object.\n"); + delete pMatrix; + return; + } + + // store data object + int iIndex = CMatrixManager::getSingleton().store(pMatrix); + + // return data id + if (1 <= nlhs) { + plhs[0] = mxCreateDoubleScalar(iIndex); + } +} + +//----------------------------------------------------------------------------------------- +/** result = astra_mex_projector('is_cuda', id); + * + * Return is the specified projector is a cuda projector. + * id: identifier of the projector object as stored in the astra-library. + */ +void astra_mex_projector_is_cuda(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) +{ + // step1: get input + if (nrhs < 2) { + mexErrMsgTxt("Not enough arguments. See the help document for a detailed argument list. \n"); + return; + } + int iPid = (int)(mxGetScalar(prhs[1])); + + // step2: get projector + CProjector2D* pProjector = CProjector2DManager::getSingleton().get(iPid); + if (!pProjector || !pProjector->isInitialized()) { + mexErrMsgTxt("Projector not initialized.\n"); + return; + } + +#ifdef ASTRA_CUDA + CCudaProjector2D* pCP = dynamic_cast<CCudaProjector2D*>(pProjector); + plhs[0] = mxCreateLogicalScalar(pCP ? 1 : 0); +#else + plhs[0] = mxCreateLogicalScalar(0); +#endif +} + + + +//----------------------------------------------------------------------------------------- + +static void printHelp() +{ + mexPrintf("Please specify a mode of operation.\n"); + mexPrintf("Valid modes: create, delete, clear, info, projection_geometry,\n"); + mexPrintf(" volume_geometry, weights_single_ray, weights_projection\n"); + mexPrintf(" splat, matrix, is_cuda\n"); +} + + +//----------------------------------------------------------------------------------------- +/** + * ... = astra_mex_projector(mode, ...); + */ +void mexFunction(int nlhs, mxArray* plhs[], + int nrhs, const mxArray* prhs[]) +{ + // INPUT: Mode + string sMode = ""; + if (1 <= nrhs) { + sMode = mex_util_get_string(prhs[0]); + } else { + printHelp(); + return; + } + + // SWITCH (MODE) + if (sMode == "create") { + astra_mex_projector_create(nlhs, plhs, nrhs, prhs); + } else if (sMode == "delete") { + astra_mex_projector_delete(nlhs, plhs, nrhs, prhs); + } else if (sMode == "clear") { + astra_mex_projector_clear(nlhs, plhs, nrhs, prhs); + } else if (sMode == "info") { + astra_mex_projector_info(nlhs, plhs, nrhs, prhs); + } else if (sMode == "projection_geometry") { + astra_mex_projector_projection_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == "volume_geometry") { + astra_mex_projector_volume_geometry(nlhs, plhs, nrhs, prhs); + } else if (sMode == "weights_single_ray") { + astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs); + } else if (sMode == "weights_projection") { + astra_mex_projector_weights_projection(nlhs, plhs, nrhs, prhs); + } else if (sMode == "splat") { + astra_mex_projector_splat(nlhs, plhs, nrhs, prhs); + } else if (sMode == "matrix") { + astra_mex_projector_matrix(nlhs, plhs, nrhs, prhs); + } else if (sMode == "is_cuda") { + astra_mex_projector_is_cuda(nlhs, plhs, nrhs, prhs); + } else { + printHelp(); + } + return; +} + + diff --git a/matlab/mex/astra_mex_projector_vc08.vcproj b/matlab/mex/astra_mex_projector_vc08.vcproj new file mode 100644 index 0000000..1380061 --- /dev/null +++ b/matlab/mex/astra_mex_projector_vc08.vcproj @@ -0,0 +1,591 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex_projector" + ProjectGUID="{4DD6056F-8EEE-4C9A-B2A9-923F01A32E97}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories=""$(MATLAB_ROOT)\extern\include\";"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + BrowseInformation="1" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_projector_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/astra_mex_vc08.vcproj b/matlab/mex/astra_mex_vc08.vcproj new file mode 100644 index 0000000..58c1e0a --- /dev/null +++ b/matlab/mex/astra_mex_vc08.vcproj @@ -0,0 +1,591 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="astra_mex" + ProjectGUID="{3FDA35E0-0D54-4663-A3E6-5ABA96F32221}" + RootNamespace="astraMatlab" + TargetFrameworkVersion="131072" + > + <Platforms> + <Platform + Name="Win32" + /> + <Platform + Name="x64" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;"$(CUDA_INC_PATH)";..\..\lib\include;..\..\lib\include\cuda;..\..\include\;" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="2" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug_CUDA|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories=""$(CUDA_INC_PATH)";$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + PreprocessorDefinitions="ASTRA_CUDA" + RuntimeLibrary="3" + BrowseInformation="1" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="AstraCuda64D.lib libmex.lib libmx.lib libut.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra32D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw32" + AdditionalLibraryDirectories="..\..\bin\win32;$(MATLAB_ROOT)\extern\lib\win32\microsoft" + ModuleDefinitionFile="mex.def" + GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)bin\$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(OutDir)\obj\$(ProjectName)" + ConfigurationType="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(MATLAB_ROOT)\extern\include\;..\..\lib\include;..\..\include" + RuntimeLibrary="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="Astra64D.lib libmex.lib libmx.lib" + OutputFile="$(OutDir)\$(ProjectName)_c.mexw64" + AdditionalLibraryDirectories="..\..\bin\x64;$(MATLAB_ROOT)\extern\lib\win64\microsoft" + ModuleDefinitionFile="mex.def" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath=".\astra_mex_c.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.cpp" + > + </File> + <File + RelativePath=".\mexHelpFunctions.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/matlab/mex/mex.def b/matlab/mex/mex.def new file mode 100644 index 0000000..c54c4e0 --- /dev/null +++ b/matlab/mex/mex.def @@ -0,0 +1 @@ +EXPORTS mexFunction
\ No newline at end of file diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp new file mode 100644 index 0000000..4105ee1 --- /dev/null +++ b/matlab/mex/mexHelpFunctions.cpp @@ -0,0 +1,642 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +/** \file mexHelpFunctions.cpp + * + * \brief Contains some functions for interfacing matlab with c data structures + */ +#include "mexHelpFunctions.h" + +#include "astra/SparseMatrixProjectionGeometry2D.h" +#include "astra/FanFlatVecProjectionGeometry2D.h" +#include "astra/AstraObjectManager.h" + +using namespace std; +using namespace astra; + + +//----------------------------------------------------------------------------------------- +// get string from matlab +std::string mex_util_get_string(const mxArray* pInput) +{ + if (!mxIsChar(pInput)) { + return ""; + } + mwSize iLength = mxGetNumberOfElements(pInput) + 1; + char* buf = new char[iLength]; + mxGetString(pInput, buf, iLength); + std::string res = std::string(buf); + delete[] buf; + return res; +} + +//----------------------------------------------------------------------------------------- +// is option +bool isOption(std::list<std::string> lOptions, std::string sOption) +{ + return std::find(lOptions.begin(), lOptions.end(), sOption) != lOptions.end(); +} + +//----------------------------------------------------------------------------------------- +// turn a matlab struct into a c++ map +std::map<std::string, mxArray*> parseStruct(const mxArray* pInput) +{ + std::map<std::string, mxArray*> res; + + // check type + if (!mxIsStruct(pInput)) { + mexErrMsgTxt("Input must be a struct."); + return res; + } + + // get field names + int nfields = mxGetNumberOfFields(pInput); + for (int i = 0; i < nfields; i++) { + std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i)); + res[sFieldName] = mxGetFieldByNumber(pInput,0,i); + } + return res; +} + +//----------------------------------------------------------------------------------------- +// turn a c++ map into a matlab struct +mxArray* buildStruct(std::map<std::string, mxArray*> mInput) +{ + mwSize dims[2] = {1, 1}; + mxArray* res = mxCreateStructArray(2,dims,0,0); + + for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) { + mxAddField(res, (*it).first.c_str()); + mxSetField(res, 0, (*it).first.c_str(), (*it).second); + } + return res; +} + +//----------------------------------------------------------------------------------------- +// parse projection geometry data +astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs) +{ + // parse struct + std::map<string, mxArray*> mStruct = parseStruct(prhs); + + // create projection geometry object + string type = mex_util_get_string(mStruct["type"]); + if (type == "parallel") { + + // detector_width + float32 fDetWidth = 1.0f; + mxArray* tmp = mStruct["detector_width"]; + if (tmp != NULL) { + fDetWidth = (float32)(mxGetScalar(tmp)); + } + + // detector_count + int iDetCount = 100; + tmp = mStruct["detector_count"]; + if (tmp != NULL) { + iDetCount = (int)(mxGetScalar(tmp)); + } + + // angles + float32* pfAngles; + int iAngleCount; + tmp = mStruct["projection_angles"]; + if (tmp != NULL) { + double* angleValues = mxGetPr(tmp); + iAngleCount = mxGetN(tmp) * mxGetM(tmp); + pfAngles = new float32[iAngleCount]; + for (int i = 0; i < iAngleCount; i++) { + pfAngles[i] = angleValues[i]; + } + } else { + mexErrMsgTxt("'angles' not specified, error."); + return NULL; + } + + // create projection geometry + return new astra::CParallelProjectionGeometry2D(iAngleCount, // number of projections + iDetCount, // number of detectors + fDetWidth, // width of the detectors + pfAngles); // angles array + } + + else if (type == "fanflat") { + + // detector_width + float32 fDetWidth = 1.0f; + mxArray* tmp = mStruct["detector_width"]; + if (tmp != NULL) { + fDetWidth = (float32)(mxGetScalar(tmp)); + } + + // detector_count + int iDetCount = 100; + tmp = mStruct["detector_count"]; + if (tmp != NULL) { + iDetCount = (int)(mxGetScalar(tmp)); + } + + // angles + float32* pfAngles; + int iAngleCount; + tmp = mStruct["projection_angles"]; + if (tmp != NULL) { + double* angleValues = mxGetPr(tmp); + iAngleCount = mxGetN(tmp) * mxGetM(tmp); + pfAngles = new float32[iAngleCount]; + for (int i = 0; i < iAngleCount; i++) { + pfAngles[i] = angleValues[i]; + } + } else { + mexErrMsgTxt("'angles' not specified, error."); + return NULL; + } + + // origin_source_dist + int iDistOriginSource = 100; + tmp = mStruct["origin_source_dist"]; + if (tmp != NULL) { + iDistOriginSource = (int)(mxGetScalar(tmp)); + } + + // origin_det_dist + int iDistOriginDet = 100; + tmp = mStruct["origin_det_dist"]; + if (tmp != NULL) { + iDistOriginDet = (int)(mxGetScalar(tmp)); + } + + // create projection geometry + return new astra::CFanFlatProjectionGeometry2D(iAngleCount, // number of projections + iDetCount, // number of detectors + fDetWidth, // width of the detectors + pfAngles, // angles array + iDistOriginSource, // distance origin source + iDistOriginDet); // distance origin detector + } + + else { + mexPrintf("Only parallel and fanflat projection geometry implemented."); + return NULL; + } +} + +//----------------------------------------------------------------------------------------- +// create projection geometry data +mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom) +{ + // temporary map to store the data for the MATLAB struct + std::map<std::string, mxArray*> mGeometryInfo; + + // detectorCount + mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount()); + + if (!_pProjGeom->isOfType("fanflat_vec")) { + // detectorWidth + mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth()); + + // pfProjectionAngles + mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionAngleCount(), mxREAL); + double* out = mxGetPr(pAngles); + for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) { + out[i] = _pProjGeom->getProjectionAngle(i); + } + mGeometryInfo["ProjectionAngles"] = pAngles; + } + else { + astra::CFanFlatVecProjectionGeometry2D* pVecGeom = dynamic_cast<astra::CFanFlatVecProjectionGeometry2D*>(_pProjGeom); + mxArray* pVectors = mxCreateDoubleMatrix(1, pVecGeom->getProjectionAngleCount()*6, mxREAL); + double* out = mxGetPr(pVectors); + int iDetCount = pVecGeom->getDetectorCount(); + for (int i = 0; i < pVecGeom->getProjectionAngleCount(); i++) { + const SFanProjection* p = &pVecGeom->getProjectionVectors()[i]; + out[6*i + 0] = p->fSrcX; + out[6*i + 1] = p->fSrcY; + out[6*i + 2] = p->fDetSX + 0.5f*iDetCount*p->fDetUX; + out[6*i + 3] = p->fDetSY + 0.5f*iDetCount*p->fDetUY; + out[6*i + 4] = p->fDetUX; + out[6*i + 5] = p->fDetUY; + } + mGeometryInfo["Vectors"] = pVectors; + } + + // parallel specific options + if (_pProjGeom->isOfType("parallel")) { + // type + mGeometryInfo["type"] = mxCreateString("parallel"); + } + // fanflat specific options + else if (_pProjGeom->isOfType("fanflat")) { + astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom); + // detectorCount + mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance()); + // detectorWidth + mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance()); + // type + mGeometryInfo["type"] = mxCreateString("fanflat"); + } + else if (_pProjGeom->isOfType("sparse_matrix")) { + astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom = dynamic_cast<astra::CSparseMatrixProjectionGeometry2D*>(_pProjGeom); + mGeometryInfo["type"] = mxCreateString("sparse_matrix"); + mGeometryInfo["MatrixID"] = mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix())); + } + else if(_pProjGeom->isOfType("fanflat_vec")) { + mGeometryInfo["type"] = mxCreateString("fanflat_vec"); + } + + // build and return the MATLAB struct + return buildStruct(mGeometryInfo); +} + +//----------------------------------------------------------------------------------------- +// parse reconstruction geometry data +astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs) +{ + // parse struct + std::map<string, mxArray*> mStruct = parseStruct(prhs); + + std::map<string, mxArray*> mOptions = parseStruct(mStruct["option"]); + + // GridColCount + int iWindowColCount = 128; + mxArray* tmp = mStruct["GridColCount"]; + if (tmp != NULL) { + iWindowColCount = (int)(mxGetScalar(tmp)); + } + + // GridRowCount + int iWindowRowCount = 128; + tmp = mStruct["GridRowCount"]; + if (tmp != NULL) { + iWindowRowCount = (int)(mxGetScalar(tmp)); + } + + // WindowMinX + float32 fWindowMinX = - iWindowColCount / 2; + tmp = mOptions["WindowMinX"]; + if (tmp != NULL) { + fWindowMinX = (float32)(mxGetScalar(tmp)); + } + + // WindowMaxX + float32 fWindowMaxX = iWindowColCount / 2; + tmp = mOptions["WindowMaxX"]; + if (tmp != NULL) { + fWindowMaxX = (float32)(mxGetScalar(tmp)); + } + + // WindowMinY + float32 fWindowMinY = - iWindowRowCount / 2; + tmp = mOptions["WindowMinY"]; + if (tmp != NULL) { + fWindowMinY = (float32)(mxGetScalar(tmp)); + } + + // WindowMaxX + float32 fWindowMaxY = iWindowRowCount / 2; + tmp = mOptions["WindowMaxY"]; + if (tmp != NULL) { + fWindowMaxY = (float32)(mxGetScalar(tmp)); + } + + // create and return reconstruction geometry + return new astra::CVolumeGeometry2D(iWindowColCount, iWindowRowCount, + fWindowMinX, fWindowMinY, + fWindowMaxX, fWindowMaxY); +} + +//----------------------------------------------------------------------------------------- +// create reconstruction geometry data +mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom) +{ + // temporary map to store the data for the MATLAB struct + std::map<std::string, mxArray*> mGeometryInfo; + + // fill up map + mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pReconGeom->getGridColCount()); + mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pReconGeom->getGridRowCount()); + + std::map<std::string, mxArray*> mGeometryOptions; + mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinX()); + mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxX()); + mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinY()); + mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxY()); + + mGeometryInfo["option"] = buildStruct(mGeometryOptions); + + // build and return the MATLAB struct + return buildStruct(mGeometryInfo); +} + + +//----------------------------------------------------------------------------------------- +string matlab2string(const mxArray* pField) +{ + // is string? + if (mxIsChar(pField)) { + return mex_util_get_string(pField); + } + + // is scalar? + if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) { + return boost::lexical_cast<string>(mxGetScalar(pField)); + } + + return ""; +} + +//----------------------------------------------------------------------------------------- +// Options struct to xml node +bool readOptions(XMLNode* node, const mxArray* pOptionStruct) +{ + // loop all fields + int nfields = mxGetNumberOfFields(pOptionStruct); + for (int i = 0; i < nfields; i++) { + std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i)); + const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i); + + if (node->hasOption(sFieldName)) { + mexErrMsgTxt("Duplicate option"); + return false; + } + + // string or scalar + if (mxIsChar(pField) || mex_is_scalar(pField)) { + string sValue = matlab2string(pField); + node->addOption(sFieldName, sValue); + } else + // numerical array + if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) { + if (!mxIsDouble(pField)) { + mexErrMsgTxt("Numeric input must be double."); + return false; + } + + XMLNode* listbase = node->addChildNode("Option"); + listbase->addAttribute("key", sFieldName); + listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); + double* pdValues = mxGetPr(pField); + int index = 0; + for (unsigned int row = 0; row < mxGetM(pField); row++) { + for (unsigned int col = 0; col < mxGetN(pField); col++) { + XMLNode* item = listbase->addChildNode("ListItem"); + item->addAttribute("index", index); + item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); + index++; + delete item; + } + } + delete listbase; + } else { + mexErrMsgTxt("Unsupported option type"); + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------------------- +// struct to xml node +bool readStruct(XMLNode* root, const mxArray* pStruct) +{ + // loop all fields + int nfields = mxGetNumberOfFields(pStruct); + for (int i = 0; i < nfields; i++) { + + // field and fieldname + std::string sFieldName = std::string(mxGetFieldNameByNumber(pStruct, i)); + const mxArray* pField = mxGetFieldByNumber(pStruct, 0, i); + + // string + if (mxIsChar(pField)) { + string sValue = matlab2string(pField); + if (sFieldName == "type") { + root->addAttribute("type", sValue); + } else { + delete root->addChildNode(sFieldName, sValue); + } + } + + // scalar + if (mex_is_scalar(pField)) { + string sValue = matlab2string(pField); + delete root->addChildNode(sFieldName, sValue); + } + + // numerical array + if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) { + if (!mxIsDouble(pField)) { + mexErrMsgTxt("Numeric input must be double."); + return false; + } + XMLNode* listbase = root->addChildNode(sFieldName); + listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField)); + double* pdValues = mxGetPr(pField); + int index = 0; + for (unsigned int row = 0; row < mxGetM(pField); row++) { + for (unsigned int col = 0; col < mxGetN(pField); col++) { + XMLNode* item = listbase->addChildNode("ListItem"); + item->addAttribute("index", index); + item->addAttribute("value", pdValues[col*mxGetM(pField)+row]); + index++; + delete item; + } + } + delete listbase; + } + + + // not castable to a single string + if (mxIsStruct(pField)) { + if (sFieldName == "options" || sFieldName == "option" || sFieldName == "Options" || sFieldName == "Option") { + bool ret = readOptions(root, pField); + if (!ret) + return false; + } else { + XMLNode* newNode = root->addChildNode(sFieldName); + bool ret = readStruct(newNode, pField); + delete newNode; + if (!ret) + return false; + } + } + + } + + return true; +} + +//----------------------------------------------------------------------------------------- +// turn a MATLAB struct into an XML Document +XMLDocument* struct2XML(string rootname, const mxArray* pStruct) +{ + if (!mxIsStruct(pStruct)) { + mexErrMsgTxt("Input must be a struct."); + return NULL; + } + + // create the document + XMLDocument* doc = XMLDocument::createDocument(rootname); + XMLNode* rootnode = doc->getRootNode(); + + // read the struct + bool ret = readStruct(rootnode, pStruct); + //doc->getRootNode()->print(); + delete rootnode; + + if (!ret) { + delete doc; + doc = 0; + } + + return doc; +} + + + + + +//----------------------------------------------------------------------------------------- +// turn an std vector<float32> object to an mxArray +mxArray* vectorToMxArray(std::vector<astra::float32> mInput) +{ + mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL); + double* pdData = mxGetPr(res); + for (unsigned int i = 0; i < mInput.size(); i++) { + pdData[i] = mInput[i]; + } + return res; +} + +//----------------------------------------------------------------------------------------- +// turn a vector<vector<float32>> object to an mxArray +mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput) +{ + unsigned int sizex = mInput.size(); + if (sizex == 0) return mxCreateString("empty"); + unsigned int sizey = mInput[0].size(); + + mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL); + double* pdData = mxGetPr(res); + for (unsigned int i = 0; i < sizex; i++) { + for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) { + pdData[j*sizex+i] = mInput[i][j]; + } + } + return res; +} + +//----------------------------------------------------------------------------------------- +// turn a boost::any object to an mxArray +mxArray* anyToMxArray(boost::any _any) +{ + if (_any.type() == typeid(std::string)) { + std::string str = boost::any_cast<std::string>(_any); + return mxCreateString(str.c_str()); + } + if (_any.type() == typeid(int)) { + return mxCreateDoubleScalar(boost::any_cast<int>(_any)); + } + if (_any.type() == typeid(float32)) { + return mxCreateDoubleScalar(boost::any_cast<float32>(_any)); + } + if (_any.type() == typeid(std::vector<astra::float32>)) { + return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any)); + } + if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) { + return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any)); + } + return NULL; +} +//----------------------------------------------------------------------------------------- +// return true ig the argument is a scalar +bool mex_is_scalar(const mxArray* pInput) +{ + return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1); +} + +//----------------------------------------------------------------------------------------- +mxArray* XML2struct(astra::XMLDocument* xml) +{ + XMLNode* node = xml->getRootNode(); + mxArray* str = XMLNode2struct(xml->getRootNode()); + delete node; + return str; +} + +//----------------------------------------------------------------------------------------- +mxArray* XMLNode2struct(astra::XMLNode* node) +{ + std::map<std::string, mxArray*> mList; + + // type_attribute + if (node->hasAttribute("type")) { + mList["type"] = mxCreateString(node->getAttribute("type").c_str()); + } + + list<XMLNode*> nodes = node->getNodes(); + for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) { + XMLNode* subnode = (*it); + // list + if (subnode->hasAttribute("listsize")) { + cout << "lkmdsqldqsjkl" << endl; + cout << " " << node->getContentNumericalArray().size() << endl; + mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray()); + } + // string + else { + mList[subnode->getName()] = mxCreateString(subnode->getContent().c_str()); + } + delete subnode; + } + + return buildStruct(mList); +} + +void get3DMatrixDims(const mxArray* x, mwSize *dims) +{ + const mwSize* mdims = mxGetDimensions(x); + mwSize dimCount = mxGetNumberOfDimensions(x); + if (dimCount == 1) { + dims[0] = mdims[0]; + dims[1] = 1; + dims[2] = 1; + } else if (dimCount == 2) { + dims[0] = mdims[0]; + dims[1] = mdims[1]; + dims[2] = 1; + } else if (dimCount == 3) { + dims[0] = mdims[0]; + dims[1] = mdims[1]; + dims[2] = mdims[2]; + } else { + dims[0] = 0; + dims[1] = 0; + dims[2] = 0; + } +} diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h new file mode 100644 index 0000000..425b4ef --- /dev/null +++ b/matlab/mex/mexHelpFunctions.h @@ -0,0 +1,76 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox"). + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +#ifndef _INC_ASTRA_MEX_HELPFUNCTIONS +#define _INC_ASTRA_MEX_HELPFUNCTIONS + +#include <string> +#include <list> +#include <iostream> +#include <sstream> +#include <map> +#include <algorithm> +#include <mex.h> + +#include <boost/lexical_cast.hpp> +#include <boost/any.hpp> + +#include "astra/Globals.h" +#include "astra/Utilities.h" + +#include "astra/ParallelProjectionGeometry2D.h" +#include "astra/FanFlatProjectionGeometry2D.h" +#include "astra/VolumeGeometry2D.h" + +#include "astra/XMLDocument.h" +#include "astra/XMLNode.h" + +std::string mex_util_get_string(const mxArray* pInput); +bool isOption(std::list<std::string> lOptions, std::string sOption); + +bool mex_is_scalar(const mxArray* pInput); + +std::map<std::string, mxArray*> parseStruct(const mxArray* pInput); +mxArray* buildStruct(std::map<std::string, mxArray*> mInput); +mxArray* vectorToMxArray(std::vector<astra::float32> mInput); + +mxArray* anyToMxArray(boost::any _any); + +astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*); +mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*); +astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*); +mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom); + +astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct); + +mxArray* XML2struct(astra::XMLDocument* xml); +mxArray* XMLNode2struct(astra::XMLNode* xml); + +void get3DMatrixDims(const mxArray* x, mwSize *dims); + +#endif diff --git a/matlab/tools/ROIselectfull.m b/matlab/tools/ROIselectfull.m new file mode 100644 index 0000000..a50c979 --- /dev/null +++ b/matlab/tools/ROIselectfull.m @@ -0,0 +1,18 @@ +function V_out = ROIselectfull(input, ROI) + + s1 = size(input,1); + s2 = size(input,2); + [x y] = meshgrid(-(s2-1)/2:(s2-1)/2,(s1-1)/2:-1:-(s1-1)/2); + A = Afstand(x,y,0,0); + + V_out = zeros(size(input)); + for slice = 1:size(input,3); + V = input(:,:,slice); + V(A > ROI/2) = 0; + V_out(:,:,slice) = V; + end +end + +function A = Afstand(x1,y1,x2,y2) + A = sqrt((x1-x2).^2+(y1-y2).^2); +end
\ No newline at end of file diff --git a/matlab/tools/astra_add_noise_to_sino.m b/matlab/tools/astra_add_noise_to_sino.m new file mode 100644 index 0000000..a262f49 --- /dev/null +++ b/matlab/tools/astra_add_noise_to_sino.m @@ -0,0 +1,47 @@ +function sinogram_out = astra_add_noise_to_sino(sinogram_in,I0) + +%-------------------------------------------------------------------------- +% sinogram_out = astra_add_noise_to_sino(sinogram_in,I0) +% +% Add poisson noise to a sinogram. +% +% sinogram_in: input sinogram, can be either MATLAB-data or an +% astra-identifier. In the latter case, this operation is inplace and the +% result will also be stored in this data object. +% I0: background intensity, used to set noise level, lower equals more +% noise +% sinogram_out: output sinogram in MATLAB-data. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +if numel(sinogram_in) == 1 + sinogramRaw = astra_mex_data2d('get', sinogram_in); +else + sinogramRaw = sinogram_in; +end + +% scale to [0,1] +max_sinogramRaw = max(sinogramRaw(:)); +sinogramRawScaled = sinogramRaw ./ max_sinogramRaw; +% to detector count +sinogramCT = I0 * exp(-sinogramRawScaled); +% add poison noise +sinogramCT_A = sinogramCT * 1e-12; +sinogramCT_B = double(imnoise(sinogramCT_A, 'poisson')); +sinogramCT_C = sinogramCT_B * 1e12; +% to density +sinogramCT_D = sinogramCT_C / I0; +sinogram_out = -max_sinogramRaw * log(sinogramCT_D); + +if numel(sinogram_in) == 1 + astra_mex_data2d('store', sinogram_in, sinogram_out); +end diff --git a/matlab/tools/astra_clear.m b/matlab/tools/astra_clear.m new file mode 100644 index 0000000..d42e395 --- /dev/null +++ b/matlab/tools/astra_clear.m @@ -0,0 +1,19 @@ +%-------------------------------------------------------------------------- +% Clears and frees memory of all objects (data, projectors, algorithms) +% currently in the astra-library. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +astra_mex_data2d('clear'); +astra_mex_data3d('clear'); +astra_mex_algorithm('clear'); +astra_mex_projector('clear'); diff --git a/matlab/tools/astra_create_backprojection.m b/matlab/tools/astra_create_backprojection.m new file mode 100644 index 0000000..7f0b02f --- /dev/null +++ b/matlab/tools/astra_create_backprojection.m @@ -0,0 +1,63 @@ +function [vol_id, vol] = astra_create_backprojection(data, proj_id) + +%-------------------------------------------------------------------------- +% [vol_id, vol] = astra_create_backprojection(data, proj_id) +% +% Create a CPU based back projection. +% +% data: input sinogram, can be either MATLAB-data or an astra-identifier. +% proj_id: identifier of the projector as it is stored in the astra-library +% vol_id: identifier of the volume data object as it is now stored in the astra-library. +% vol: MATLAB data version of the volume +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% get projection geometry +proj_geom = astra_mex_projector('projection_geometry', proj_id); +vol_geom = astra_mex_projector('volume_geometry', proj_id); + +% store sinogram +if (numel(data) > 1) + sino_id = astra_mex_data2d('create','-sino', proj_geom, data); +else + sino_id = data; +end + +% store volume +vol_id = astra_mex_data2d('create','-vol', vol_geom, 0); + +if astra_mex_projector('is_cuda', proj_id) + cfg = astra_struct('BP_CUDA'); +else + cfg = astra_struct('BP'); +end + +cfg.ProjectorId = proj_id; +cfg.ProjectionDataId = sino_id; +cfg.ReconstructionDataId = vol_id; + +% create backprojection +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data2d('delete', sino_id); +end + +if nargout >= 2 + vol = astra_mex_data2d('get',vol_id); +end + + + diff --git a/matlab/tools/astra_create_backprojection3d_cuda.m b/matlab/tools/astra_create_backprojection3d_cuda.m new file mode 100644 index 0000000..afa41db --- /dev/null +++ b/matlab/tools/astra_create_backprojection3d_cuda.m @@ -0,0 +1,54 @@ +function [vol_id, vol] = astra_create_backprojection3d_cuda(data, proj_geom, vol_geom) + +%-------------------------------------------------------------------------- +% [vol_id, vol] = astra_create_backprojection3d_cuda(data, proj_geom, vol_geom) +% +% Create a GPU based backprojection. +% +% data: input projection data, can be either MATLAB-data or an astra-identifier. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% vol_id: identifier of the volume data object as it is now stored in +% the astra-library. +% vol: MATLAB data version of the volume. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% store projection data +if (numel(data) > 1) + sino_id = astra_mex_data3d('create','-proj3d', proj_geom, data); +else + sino_id = data; +end + +% store volume +vol_id = astra_mex_data3d('create','-vol', vol_geom, 0); + +% create sinogram +cfg = astra_struct('BP3D_CUDA'); +cfg.ProjectionDataId = sino_id; +cfg.ReconstructionDataId = vol_id; +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data3d('delete', sino_id); +end + +if nargout >= 2 + vol = astra_mex_data3d('get',vol_id); +end + + + diff --git a/matlab/tools/astra_create_backprojection_cuda.m b/matlab/tools/astra_create_backprojection_cuda.m new file mode 100644 index 0000000..cef7864 --- /dev/null +++ b/matlab/tools/astra_create_backprojection_cuda.m @@ -0,0 +1,39 @@ +function backProj = astra_create_backprojection_cuda(sinogramData, proj_geom, vol_geom) + %-------------------------------------------------------------------------- + % backProj = astra_create_backprojection_cuda(sinogramData, proj_geom, vol_geom) + % + % Creates a CUDA-based simple backprojection + % + % sinogramData: 2D matrix with projections stored row-based + % theta: projection angles, length should be equal to the number of rows in + % sinogramData + % reconstructionSize: vector with length 2 with the row and column count of + % the reconstruction image + % backProj: 2D back projection from sinogram data + %-------------------------------------------------------------------------- + %------------------------------------------------------------------------ + % This file is part of the + % All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") + % + % Copyright: iMinds-Vision Lab, University of Antwerp + % License: Open Source under GPLv3 + % Contact: mailto:astra@ua.ac.be + % Website: http://astra.ua.ac.be + %------------------------------------------------------------------------ + % $Id$ + + recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogramData); + + cfg = astra_struct('BP_CUDA'); + cfg.ProjectionDataId = sinogram_id; + cfg.ReconstructionDataId = recon_id; + + alg_id = astra_mex_algorithm('create', cfg); + astra_mex_algorithm('run', alg_id); + backProj = astra_mex_data2d('get', recon_id); + + astra_mex_data2d('delete', sinogram_id); + astra_mex_data2d('delete', recon_id); + astra_mex_algorithm('delete', alg_id); +end diff --git a/matlab/tools/astra_create_fbp_reconstruction.m b/matlab/tools/astra_create_fbp_reconstruction.m new file mode 100644 index 0000000..4456f9c --- /dev/null +++ b/matlab/tools/astra_create_fbp_reconstruction.m @@ -0,0 +1,23 @@ +function [FBP_id, FBP] = astra_create_fbp_reconstruction(sinogram, proj_id) + +proj_geom = astra_mex_projector('projection_geometry', proj_id); +vol_geom = astra_mex_projector('volume_geometry', proj_id); + +if numel(sinogram) == 1 + sinogram_id = sinogram; +else + sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram); +end + +FBP_id = astra_mex_data2d('create','-vol',vol_geom, 0); + +cfg = astra_struct('FBP_CUDA'); +cfg.ProjectionDataId = sinogram_id; +cfg.ReconstructionDataId = FBP_id; +cfg.FilterType = 'Ram-Lak'; +cfg.ProjectorId = proj_id; +cfg.Options.GPUindex = 0; +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('run', alg_id); + +FBP = astra_mex_data2d('get', FBP_id); diff --git a/matlab/tools/astra_create_proj_geom.m b/matlab/tools/astra_create_proj_geom.m new file mode 100644 index 0000000..dbf0464 --- /dev/null +++ b/matlab/tools/astra_create_proj_geom.m @@ -0,0 +1,204 @@ +function proj_geom = astra_create_proj_geom(type, varargin) + +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('parallel', det_width, det_count, angles) +% +% Create a 2D parallel beam geometry. See the API for more information. +% det_width: distance between two adjacent detectors +% det_count: number of detectors in a single projection +% angles: projection angles in radians, should be between -pi/4 and 7pi/4 +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('parallel3d', det_spacing_x, det_spacing_y, det_row_count, det_col_count, angles) +% +% Create a 3D parallel beam geometry. See the API for more information. +% det_spacing_x: distance between two horizontally adjacent detectors +% det_spacing_y: distance between two vertically adjacent detectors +% det_row_count: number of detector rows in a single projection +% det_col_count: number of detector columns in a single projection +% angles: projection angles in radians, should be between -pi/4 and 7pi/4 +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('fanflat', det_width, det_count, angles, source_origin, origin_det) +% +% Create a 2D flat fan beam geometry. See the API for more information. +% det_width: distance between two adjacent detectors +% det_count: number of detectors in a single projection +% angles: projection angles in radians, should be between -pi/4 and 7pi/4 +% source_origin: distance between the source and the center of rotation +% origin_det: distance between the center of rotation and the detector array +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('fanflat_vec', det_count, vectors) +% +% Create a 2D flat fan beam geometry specified by 2D vectors. +% See the API for more information. +% det_count: number of detectors in a single projection +% vectors: a matrix containing the actual geometry. Each row corresponds +% to a single projection, and consists of: +% ( srcX, srcY, dX, dY, uX, uY ) +% src: the ray source +% d : the center of the detector +% u : the vector from detector pixel 0 to 1 +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('cone', det_spacing_x, det_spacing_y, det_row_count, det_col_count, angles, source_origin, origin_det) +% +% Create a 3D cone beam geometry. See the API for more information. +% det_spacing_x: distance between two horizontally adjacent detectors +% det_spacing_y: distance between two vertically adjacent detectors +% det_row_count: number of detector rows in a single projection +% det_col_count: number of detector columns in a single projection +% angles: projection angles in radians, should be between -pi/4 and 7pi/4 +% source_origin: distance between the source and the center of rotation +% origin_det: distance between the center of rotation and the detector array +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('cone_vec', det_row_count, det_col_count, vectors) +% +% Create a 3D cone beam geometry specified by 3D vectors. +% See the API for more information. +% det_row_count: number of detector rows in a single projection +% det_col_count: number of detector columns in a single projection +% vectors: a matrix containing the actual geometry. Each row corresponds +% to a single projection, and consists of: +% ( srcX, srcY, srcZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ ) +% src: the ray source +% d : the center of the detector +% u : the vector from detector pixel (0,0) to (0,1) +% v : the vector from detector pixel (0,0) to (1,0) +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +% proj_geom = astra_create_proj_geom('parallel3d_vec', det_row_count, det_col_count, vectors) +% +% Create a 3D parallel beam geometry specified by 3D vectors. +% See the API for more information. +% det_row_count: number of detector rows in a single projection +% det_col_count: number of detector columns in a single projection +% vectors: a matrix containing the actual geometry. Each row corresponds +% to a single projection, and consists of: +% ( rayX, rayY, rayZ, dX, dY, dZ, uX, uY, uZ, vX, vY, vZ ) +% ray: the ray direction +% d : the center of the detector +% u : the vector from detector pixel (0,0) to (0,1) +% v : the vector from detector pixel (0,0) to (1,0) +% proj_geom: MATLAB struct containing all information of the geometry +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +if strcmp(type,'parallel') + if numel(varargin) < 3 + error('not enough variables: astra_create_proj_geom(parallel, detector_spacing, det_count, angles)'); + end + proj_geom = struct( ... + 'type', 'parallel', ... + 'DetectorWidth', varargin{1}, ... + 'DetectorCount', varargin{2}, ... + 'ProjectionAngles', varargin{3} ... + ); + +elseif strcmp(type,'fanflat') + if numel(varargin) < 5 + error('not enough variables: astra_create_proj_geom(fanflat, det_width, det_count, angles, source_origin, source_det)'); + end + proj_geom = struct( ... + 'type', 'fanflat', ... + 'DetectorWidth', varargin{1}, ... + 'DetectorCount', varargin{2}, ... + 'ProjectionAngles', varargin{3}, ... + 'DistanceOriginSource', varargin{4}, ... + 'DistanceOriginDetector', varargin{5} ... + ); + +elseif strcmp(type,'fanflat_vec') + if numel(varargin) < 2 + error('not enough variables: astra_create_proj_geom(fanflat_vec, det_count, V') + end + if size(varargin{2}, 2) ~= 6 + error('V should be a Nx6 matrix, with N the number of projections') + end + proj_geom = struct( ... + 'type', 'fanflat_vec', ... + 'DetectorCount', varargin{1}, ... + 'Vectors', varargin{2} ... + ); + +elseif strcmp(type,'parallel3d') + if numel(varargin) < 5 + error('not enough variables: astra_create_proj_geom(parallel3d, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles)'); + end + proj_geom = struct( ... + 'type', 'parallel3d', ... + 'DetectorSpacingX', varargin{1}, ... + 'DetectorSpacingY', varargin{2}, ... + 'DetectorRowCount', varargin{3}, ... + 'DetectorColCount', varargin{4}, ... + 'ProjectionAngles', varargin{5} ... + ); +elseif strcmp(type,'cone') + if numel(varargin) < 7 + error('not enough variables: astra_create_proj_geom(cone, detector_spacing_x, detector_spacing_y, det_row_count, det_col_count, angles, source_origin, source_det)'); + end + proj_geom = struct( ... + 'type', 'cone', ... + 'DetectorSpacingX', varargin{1}, ... + 'DetectorSpacingY', varargin{2}, ... + 'DetectorRowCount', varargin{3}, ... + 'DetectorColCount', varargin{4}, ... + 'ProjectionAngles', varargin{5}, ... + 'DistanceOriginSource', varargin{6}, ... + 'DistanceOriginDetector',varargin{7} ... + ); +elseif strcmp(type,'cone_vec') + if numel(varargin) < 3 + error('not enough variables: astra_create_proj_geom(cone_vec, det_row_count, det_col_count, V') + end + if size(varargin{3}, 2) ~= 12 + error('V should be a Nx12 matrix, with N the number of projections') + end + proj_geom = struct( ... + 'type', 'cone_vec', ... + 'DetectorRowCount', varargin{1}, ... + 'DetectorColCount', varargin{2}, ... + 'Vectors', varargin{3} ... + ); +elseif strcmp(type,'parallel3d_vec') + if numel(varargin) < 3 + error('not enough variables: astra_create_proj_geom(parallel3d_vec, det_row_count, det_col_count, V') + end + if size(varargin{3}, 2) ~= 12 + error('V should be a Nx12 matrix, with N the number of projections') + end + proj_geom = struct( ... + 'type', 'parallel3d_vec', ... + 'DetectorRowCount', varargin{1}, ... + 'DetectorColCount', varargin{2}, ... + 'Vectors', varargin{3} ... + ); +elseif strcmp(type,'sparse_matrix') + if numel(varargin) < 3 + error('not enough variables: astra_create_proj_geom(sparse_matrix, det_width, det_count, angles, matrix_id)') + end + proj_geom = struct( ... + 'type', 'sparse_matrix', ... + 'DetectorWidth', varargin{1}, ... + 'DetectorCount', varargin{2}, ... + 'ProjectionAngles', varargin{3}, ... + 'MatrixID', varargin{4} ... + ); + +else + disp(['Error: unknown type ' type]); + proj_geom = struct(); +end + diff --git a/matlab/tools/astra_create_projector.m b/matlab/tools/astra_create_projector.m new file mode 100644 index 0000000..f773d0d --- /dev/null +++ b/matlab/tools/astra_create_projector.m @@ -0,0 +1,50 @@ +function proj_id = astra_create_projector(type, proj_geom, vol_geom) + +%-------------------------------------------------------------------------- +% proj_id = astra_create_projector(type, proj_geom, vol_geom) +% +% Create a new projector object based on projection and volume geometry. +% Used when the default values of each projector are sufficient. +% +% type: type of the projector. 'blob', 'line', 'linear' 'strip', ... See API for more information. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% proj_id: identifier of the projector as it is now stored in the astra-library. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +cfg_proj = astra_struct(type); +cfg_proj.ProjectionGeometry = proj_geom; +cfg_proj.VolumeGeometry = vol_geom; + +if strcmp(type,'blob') + % Blob options + blob_size = 2; + blob_sample_rate = 0.01; + blob_values = kaiserBessel(2, 10.4, blob_size, 0:blob_sample_rate:blob_size); + cfg_proj.Kernel.KernelSize = blob_size; + cfg_proj.Kernel.SampleRate = blob_sample_rate; + cfg_proj.Kernel.SampleCount = length(blob_values); + cfg_proj.Kernel.KernelValues = blob_values; +end + +if strcmp(type,'linear3d') || strcmp(type,'linearcone') || strcmp(type,'cuda3d') + proj_id = astra_mex_projector3d('create', cfg_proj); +else + proj_id = astra_mex_projector('create', cfg_proj); +end + + + + + diff --git a/matlab/tools/astra_create_reconstruction.m b/matlab/tools/astra_create_reconstruction.m new file mode 100644 index 0000000..15e452c --- /dev/null +++ b/matlab/tools/astra_create_reconstruction.m @@ -0,0 +1,97 @@ +function [recon_id, recon] = astra_create_reconstruction(rec_type, proj_id, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc) + +%-------------------------------------------------------------------------- +% [recon_id, recon] = astra_create_reconstruction(rec_type, proj_id, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc) +% +% Create a CPU based iterative reconstruction. +% +% rec_type: reconstruction type, 'ART', 'SART' 'SIRT' or 'CGLS', not all options are adjustable +% proj_id: identifier of the projector as it is stored in the astra-library +% sinogram: sinogram data OR sinogram identifier +% iterations: number of iterations to perform +% use_mask: use a reconstrucionmask? 'yes' or 'no' +% mask: mask data OR mask identifier. +% use_minc: use a minimum constraint? 'yes' or 'no' +% minc: minimum constraint value +% use_maxc: use a maximum constraint? 'yes' or 'no' +% maxc: maximum constraint value +% recon_id: identifier of the reconstruction data object as it is now stored in the astra-library +% recon: MATLAB data version of the reconstruction +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +if nargin <= 4 + use_mask = 'no'; + mask = []; + use_minc = 'no'; + minc = 0; + use_maxc = 'no'; + maxc = 255; +end + +if nargin <= 6 + use_minc = 'no'; + minc = 0; + use_maxc = 'no'; + maxc = 255; +end + +if numel(sinogram) == 1 + sinogram_id = sinogram; +else + proj_geom = astra_mex_projector('projection_geometry', proj_id); + sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram); +end + +% create reconstruction object +vol_geom = astra_mex_projector('volume_geometry', proj_id); +recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + +% configure +cfg = astra_struct(rec_type); +cfg.ProjectorId = proj_id; +cfg.ProjectionDataId = sinogram_id; +cfg.ReconstructionDataId = recon_id; +if strcmp(use_mask,'yes') + if numel(mask) == 1 + mask_id = mask; + else + mask_id = astra_mex_data2d('create', '-vol', vol_geom, mask); + end + cfg.options.ReconstructionMaskId = mask_id; +end +cfg.options.UseMinConstraint = use_minc; +cfg.options.MinConstraintValue = minc; +cfg.options.UseMaxConstraint = use_maxc; +cfg.options.MaxConstraintValue = maxc; +cfg.options.ProjectionOrder = 'random'; +alg_id = astra_mex_algorithm('create', cfg); + +% iterate +astra_mex_algorithm('iterate', alg_id, iterations); + +% return object +recon = astra_mex_data2d('get', recon_id); + +% garbage collection +astra_mex_algorithm('delete', alg_id); +if numel(sinogram) ~= 1 + astra_mex_data2d('delete', sinogram_id); +end + +if strcmp(use_mask,'yes') + if numel(mask) ~= 1 + astra_mex_data2d('delete', mask_id); + end +end + diff --git a/matlab/tools/astra_create_reconstruction_cuda.m b/matlab/tools/astra_create_reconstruction_cuda.m new file mode 100644 index 0000000..b428eb5 --- /dev/null +++ b/matlab/tools/astra_create_reconstruction_cuda.m @@ -0,0 +1,80 @@ +function [recon_id, recon] = astra_create_reconstruction_cuda(rec_type, proj_geom, vol_geom, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc) + +%-------------------------------------------------------------------------- +% [recon_id, recon] = astra_create_reconstruction_cuda(rec_type, proj_geom, vol_geom, sinogram, iterations, use_mask, mask, use_minc, minc, use_maxc, maxc) +% +% Create a GPU based iterative reconstruction. +% +% rec_type: reconstruction type, only 'SIRT_CUDA' for now +% proj_geom: projection geometry struct +% vol_geom: volume geometry struct +% sinogram: sinogram data OR sinogram identifier +% iterations: number of iterations to perform +% use_mask: use a reconstrucionmask? 'yes' or 'no' +% mask: mask data OR mask identifier. +% use_minc: use a minimum constraint? 'yes' or 'no' +% minc: minimum constraint value +% use_maxc: use a maximum constraint? 'yes' or 'no' +% maxc: maximum constraint value +% recon_id: identifier of the reconstruction data object as it is now stored in the astra-library +% recon: MATLAB data version of the reconstruction +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +if numel(sinogram) == 1 + sinogram_id = sinogram; +else + sinogram_id = astra_mex_data2d('create', '-sino', proj_geom, sinogram); +end + +% create reconstruction object +recon_id = astra_mex_data2d('create', '-vol', vol_geom, 0); + +% configure +cfg = astra_struct('SIRT_CUDA'); +cfg.ProjectionGeometry = proj_geom; +cfg.ReconstructionGeometry = vol_geom; +cfg.ProjectionDataId = sinogram_id; +cfg.ReconstructionDataId = recon_id; +if strcmp(use_mask,'yes') + if numel(mask) == 1 + mask_id = mask; + else + mask_id = astra_mex_data2d('create', '-vol', vol_geom, mask); + end + cfg.options.ReconstructionMaskId = mask_id; +end +cfg.options.UseMinConstraint = use_minc; +cfg.options.MinConstraintValue = minc; +cfg.options.UseMaxConstraint = use_maxc; +cfg.options.MaxConstraintValue = maxc; +alg_id = astra_mex_algorithm('create', cfg); + +% iterate +astra_mex_algorithm('iterate', alg_id, iterations); + +% return object +recon = astra_mex_data2d('get', recon_id); + +% garbage collection +astra_mex_algorithm('delete', alg_id); +if numel(sinogram) ~= 1 + astra_mex_data2d('delete', sinogram_id); +end + +if strcmp(use_mask,'yes') + if numel(mask) ~= 1 + astra_mex_data2d('delete', mask_id); + end +end + diff --git a/matlab/tools/astra_create_sino.m b/matlab/tools/astra_create_sino.m new file mode 100644 index 0000000..4771bd6 --- /dev/null +++ b/matlab/tools/astra_create_sino.m @@ -0,0 +1,63 @@ +function [sino_id, sino] = astra_create_sino(data, proj_id) + +%-------------------------------------------------------------------------- +% [sino_id, sino] = astra_create_sino(data, proj_id) +% +% Create a CPU based forward projection. +% +% data: input volume, can be either MATLAB-data or an astra-identifier. +% proj_id: identifier of the projector as it is stored in the astra-library +% sino_id: identifier of the sinogram data object as it is now stored in the astra-library. +% sino: MATLAB data version of the sinogram +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% get projection geometry +proj_geom = astra_mex_projector('projection_geometry', proj_id); +vol_geom = astra_mex_projector('volume_geometry', proj_id); + +% store volume +if (numel(data) > 1) + volume_id = astra_mex_data2d('create','-vol', vol_geom, data); +else + volume_id = data; +end + +% store sino +sino_id = astra_mex_data2d('create','-sino', proj_geom, 0); + +if astra_mex_projector('is_cuda', proj_id) + cfg = astra_struct('FP_CUDA'); +else + cfg = astra_struct('FP'); +end + +cfg.ProjectorId = proj_id; +cfg.ProjectionDataId = sino_id; +cfg.VolumeDataId = volume_id; + +% create sinogram +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data2d('delete', volume_id); +end + +if nargout >= 2 + sino = astra_mex_data2d('get',sino_id); +end + + + diff --git a/matlab/tools/astra_create_sino3d_cuda.m b/matlab/tools/astra_create_sino3d_cuda.m new file mode 100644 index 0000000..ef22ebe --- /dev/null +++ b/matlab/tools/astra_create_sino3d_cuda.m @@ -0,0 +1,54 @@ +function [sino_id, sino] = astra_create_sino3d_cuda(data, proj_geom, vol_geom) + +%-------------------------------------------------------------------------- +% [sino_id, sino] = astra_create_sino3d_cuda(data, proj_geom, vol_geom) +% +% Create a GPU based forward projection. +% +% data: input volume, can be either MATLAB-data or an astra-identifier. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% sino_id: identifier of the sinogram data object as it is now stored in +% the astra-library. +% sino: MATLAB data version of the sinogram. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% store volume +if (numel(data) > 1) + volume_id = astra_mex_data3d('create','-vol', vol_geom, data); +else + volume_id = data; +end + +% store sino +sino_id = astra_mex_data3d('create','-sino', proj_geom, 0); + +% create sinogram +cfg = astra_struct('FP3D_CUDA'); +cfg.ProjectionDataId = sino_id; +cfg.VolumeDataId = volume_id; +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data3d('delete', volume_id); +end + +if nargout >= 2 + sino = astra_mex_data3d('get',sino_id); +end + + + diff --git a/matlab/tools/astra_create_sino_cuda.m b/matlab/tools/astra_create_sino_cuda.m new file mode 100644 index 0000000..82bda7c --- /dev/null +++ b/matlab/tools/astra_create_sino_cuda.m @@ -0,0 +1,58 @@ +function [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index) + +%-------------------------------------------------------------------------- +% [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index) +% +% Create a GPU based forward projection. +% +% data: input volume, can be either MATLAB-data or an astra-identifier. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% gpu_index: the index of the GPU to use (optional). +% sino_id: identifier of the sinogram data object as it is now stored in +% the astra-library. +% sino: MATLAB data version of the sinogram. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% store volume +if (numel(data) > 1) + volume_id = astra_mex_data2d('create','-vol', vol_geom, data); +else + volume_id = data; +end + +% store sino +sino_id = astra_mex_data2d('create','-sino', proj_geom, 0); + +% create sinogram +cfg = astra_struct('FP_CUDA'); +cfg.ProjectionDataId = sino_id; +cfg.VolumeDataId = volume_id; +if nargin > 3 + cfg.option.GPUindex = gpu_index; +end +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data2d('delete', volume_id); +end + +if nargout >= 2 + sino = astra_mex_data2d('get',sino_id); +end + + + diff --git a/matlab/tools/astra_create_sino_gpu.m b/matlab/tools/astra_create_sino_gpu.m new file mode 100644 index 0000000..95a3b09 --- /dev/null +++ b/matlab/tools/astra_create_sino_gpu.m @@ -0,0 +1,58 @@ +function [sino_id, sino] = astra_create_sino_gpu(data, proj_geom, vol_geom, gpu_index) + +%-------------------------------------------------------------------------- +% [sino_id, sino] = astra_create_sino_gpu(data, proj_geom, vol_geom, gpu_index) +% +% Create a GPU based forward projection. +% +% data: input volume, can be either MATLAB-data or an astra-identifier. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% gpu_index: the index of the GPU to use (optional). +% sino_id: identifier of the sinogram data object as it is now stored in +% the astra-library. +% sino: MATLAB data version of the sinogram. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% store volume +if (numel(data) > 1) + volume_id = astra_mex_data2d('create','-vol', vol_geom, data); +else + volume_id = data; +end + +% store sino +sino_id = astra_mex_data2d('create','-sino', proj_geom, 0); + +% create sinogram +cfg = astra_struct('FP_CUDA'); +cfg.ProjectionDataId = sino_id; +cfg.VolumeDataId = volume_id; +if nargin > 3 + cfg.option.GPUindex = gpu_index; +end +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data2d('delete', volume_id); +end + +if nargout >= 2 + sino = astra_mex_data2d('get',sino_id); +end + + + diff --git a/matlab/tools/astra_create_sino_sampling.m b/matlab/tools/astra_create_sino_sampling.m new file mode 100644 index 0000000..6b86d61 --- /dev/null +++ b/matlab/tools/astra_create_sino_sampling.m @@ -0,0 +1,59 @@ +function [sino_id, sino] = astra_create_sino_sampling(data, proj_geom, vol_geom, gpu_index, sampling) + +%-------------------------------------------------------------------------- +% [sino_id, sino] = astra_create_sino_cuda(data, proj_geom, vol_geom, gpu_index) +% +% Create a GPU based forward projection. +% +% data: input volume, can be either MATLAB-data or an astra-identifier. +% proj_geom: MATLAB struct containing the projection geometry. +% vol_geom: MATLAB struct containing the volume geometry. +% gpu_index: the index of the GPU to use (optional). +% sino_id: identifier of the sinogram data object as it is now stored in +% the astra-library. +% sino: MATLAB data version of the sinogram. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + + +% store volume +if (numel(data) > 1) + volume_id = astra_mex_data2d('create','-vol', vol_geom, data); +else + volume_id = data; +end + +% store sino +sino_id = astra_mex_data2d('create','-sino', proj_geom, 0); + +% create sinogram +cfg = astra_struct('FP_CUDA'); +cfg.ProjectionDataId = sino_id; +cfg.VolumeDataId = volume_id; +cfg.option.DetectorSuperSampling = sampling; +if nargin > 3 + cfg.option.GPUindex = gpu_index; +end +alg_id = astra_mex_algorithm('create', cfg); +astra_mex_algorithm('iterate', alg_id); +astra_mex_algorithm('delete', alg_id); + +if (numel(data) > 1) + astra_mex_data2d('delete', volume_id); +end + +if nargout >= 2 + sino = astra_mex_data2d('get',sino_id); +end + + + diff --git a/matlab/tools/astra_create_vol_geom.m b/matlab/tools/astra_create_vol_geom.m new file mode 100644 index 0000000..61db8fb --- /dev/null +++ b/matlab/tools/astra_create_vol_geom.m @@ -0,0 +1,96 @@ +function vol_geom = astra_create_vol_geom(varargin) + +%-------------------------------------------------------------------------- +% vol_geom = astra_create_vol_geom([row_count col_count]); +% vol_geom = astra_create_vol_geom(row_count, col_count); +% vol_geom = astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y); +% +% Create a 2D volume geometry. See the API for more information. +% row_count: number of rows. +% col_count: number of columns. +% min_x: minimum value on the x-axis. +% max_x: maximum value on the x-axis. +% min_y: minimum value on the y-axis. +% max_y: maximum value on the y-axis. +% vol_geom: MATLAB struct containing all information of the geometry. +%-------------------------------------------------------------------------- +% vol_geom = astra_create_vol_geom(row_count, col_count, slice_count); +% +% Create a 3D volume geometry. See the API for more information. +% row_count: number of rows. +% col_count: number of columns. +% slice_count: number of slices. +% vol_geom: MATLAB struct containing all information of the geometry. +%-------------------------------------------------------------------------- +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +% astra_create_vol_geom([row_and_col_count ]) +if numel(varargin) == 1 && numel(varargin{1}) == 1 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}(1); + vol_geom.GridColCount = varargin{1}(1); + vol_geom.option.WindowMinX = -varargin{1}(1) / 2; + vol_geom.option.WindowMaxX = varargin{1}(1) / 2; + vol_geom.option.WindowMinY = -varargin{1}(1) / 2; + vol_geom.option.WindowMaxY = varargin{1}(1) / 2; + + +% astra_create_vol_geom([row_count col_count]) +elseif numel(varargin) == 1 && numel(varargin{1}) == 2 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}(1); + vol_geom.GridColCount = varargin{1}(2); + vol_geom.option.WindowMinX = -varargin{1}(2) / 2; + vol_geom.option.WindowMaxX = varargin{1}(2) / 2; + vol_geom.option.WindowMinY = -varargin{1}(1) / 2; + vol_geom.option.WindowMaxY = varargin{1}(1) / 2; + +% astra_create_vol_geom([row_count col_count slice_count]) +elseif numel(varargin) == 1 && numel(varargin{1}) == 3 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}(1); + vol_geom.GridColCount = varargin{1}(2); + vol_geom.GridSliceCount = varargin{1}(3); + vol_geom.option.WindowMinX = -varargin{1}(2) / 2; + vol_geom.option.WindowMaxX = varargin{1}(2) / 2; + vol_geom.option.WindowMinY = -varargin{1}(1) / 2; + vol_geom.option.WindowMaxY = varargin{1}(1) / 2; + vol_geom.option.WindowMinZ = -varargin{1}(3) / 2; + vol_geom.option.WindowMaxZ = varargin{1}(3) / 2; + +% astra_create_vol_geom(row_count, col_count) +elseif numel(varargin) == 2 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}; + vol_geom.GridColCount = varargin{2}; + vol_geom.option.WindowMinX = -varargin{2} / 2; + vol_geom.option.WindowMaxX = varargin{2} / 2; + vol_geom.option.WindowMinY = -varargin{1} / 2; + vol_geom.option.WindowMaxY = varargin{1} / 2; + +% astra_create_vol_geom(row_count, col_count, min_x, max_x, min_y, max_y) +elseif numel(varargin) == 6 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}; + vol_geom.GridColCount = varargin{2}; + vol_geom.option.WindowMinX = varargin{3}; + vol_geom.option.WindowMaxX = varargin{4}; + vol_geom.option.WindowMinY = varargin{5}; + vol_geom.option.WindowMaxY = varargin{6}; + +% astra_create_vol_geom(row_count, col_count, slice_count) +elseif numel(varargin) == 3 + vol_geom = struct(); + vol_geom.GridRowCount = varargin{1}; + vol_geom.GridColCount = varargin{2}; + vol_geom.GridSliceCount = varargin{3}; +end diff --git a/matlab/tools/astra_data_gui.fig b/matlab/tools/astra_data_gui.fig Binary files differnew file mode 100644 index 0000000..d73e430 --- /dev/null +++ b/matlab/tools/astra_data_gui.fig diff --git a/matlab/tools/astra_data_gui.m b/matlab/tools/astra_data_gui.m new file mode 100644 index 0000000..337a5d4 --- /dev/null +++ b/matlab/tools/astra_data_gui.m @@ -0,0 +1,396 @@ +function varargout = astra_data_gui(varargin) +% ASTRA_DATA_GUI M-file for ASTRA_DATA_GUI.fig +% ASTRA_DATA_GUI, by itself, creates a new ASTRA_DATA_GUI or raises the existing +% singleton*. +% +% H = ASTRA_DATA_GUI returns the handle to a new ASTRA_DATA_GUI or the handle to +% the existing singleton*. +% +% ASTRA_DATA_GUI('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in ASTRA_DATA_GUI.M with the given input arguments. +% +% ASTRA_DATA_GUI('Property','Value',...) creates a new ASTRA_DATA_GUI or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before ASTRA_DATA_GUI_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to ASTRA_DATA_GUI_OpeningFcn via varargin. +% +% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one +% instance to run (singleton)". +% +% See also: GUIDE, GUIDATA, GUIHANDLES + +% Edit the above text to modify the response to help ASTRA_DATA_GUI + +% Last Modified by GUIDE v2.5 05-Mar-2012 14:34:03 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @astra_data_gui_OpeningFcn, ... + 'gui_OutputFcn', @astra_data_gui_OutputFcn, ... + 'gui_LayoutFcn', [] , ... + 'gui_Callback', []); +if nargin && ischar(varargin{1}) + gui_State.gui_Callback = str2func(varargin{1}); +end + +if nargout + [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); +else + gui_mainfcn(gui_State, varargin{:}); +end +% End initialization code - DO NOT EDIT + + +% --- Executes just before astra_data_gui is made visible. +function astra_data_gui_OpeningFcn(hObject, eventdata, handles, varargin) +% This function has no output args, see OutputFcn. +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% varargin command line arguments to astra_data_gui (see VARARGIN) + +% Choose default command line output for astra_data_gui +handles.output = hObject; +handles.data = []; + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes astra_data_gui wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = astra_data_gui_OutputFcn(hObject, eventdata, handles) +% varargout cell array for returning output args (see VARARGOUT); +% hObject handle to figure +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Get default command line output from handles structure +varargout{1} = handles.output; + + +% Use this function to display a figure using the gui from any m-file +% example: +% Handle = astra_data_gui(); +% astra_data_gui('loadVolume',guihandles(Handle),'rand(30,30,30)',15); +function loadVolume(handles,name,figure_number) +set(handles.txt_var, 'String', name); +set(handles.figure_number, 'String', num2str(figure_number)); +btn_load_Callback(handles.txt_var, [], handles); + + + + + +function txt_var_Callback(hObject, eventdata, handles) %#ok<*DEFNU> +% hObject handle to txt_var (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'String') returns contents of txt_var as text +% str2double(get(hObject,'String')) returns contents of txt_var as a double + + +% --- Executes during object creation, after setting all properties. +function txt_var_CreateFcn(hObject, eventdata, handles) +% hObject handle to txt_var (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + + +% --- Executes on button press in btn_load. +function btn_load_Callback(hObject, eventdata, handles) +% hObject handle to btn_load (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +s = get(handles.txt_var, 'String'); +data = evalin('base', s); +handles.data = data; +guidata(hObject, handles); + +% Set Default Stuff +set(handles.sld_slice, 'Min',1); +set(handles.sld_slice, 'Max', size(data,3)); +set(handles.sld_slice, 'SliderStep', [1/(size(data,3)-2) 1/(size(data,3)-2)]); +set(handles.sld_slice, 'Value', size(data,3)/2); + +sliderValue = floor(get(handles.sld_slice, 'Value')); +set(handles.txt_slice, 'String', num2str(sliderValue)); +set(handles.txt_min, 'String', num2str(1)); +set(handles.txt_max, 'String', num2str(size(data,3))); + +set(handles.sld_magnification, 'Min',1); +set(handles.sld_magnification, 'Max', 400); +set(handles.sld_magnification, 'SliderStep', [1/(400-2) 1/(400-2)]); +set(handles.sld_magnification, 'Value', 100); + +sliderValue3 = floor(get(handles.sld_magnification, 'Value')); +set(handles.txt_mag, 'String', num2str(sliderValue3)); + + +figure_number = floor(str2double(get(handles.figure_number, 'String'))); +if(isnan(figure_number) || figure_number < 1) + set(handles.figure_number, 'String', num2str(10)); +end + +showimage(handles); + +% --- SHOW IMAGE +function showimage(handles) + sliderValue = floor(get(handles.sld_slice, 'Value')); + magnification = floor(get(handles.sld_magnification, 'Value')); + figure_number = floor(str2double(get(handles.figure_number, 'String'))); + image_matrix = handles.data; + if get(handles.btn_x, 'Value') == 1 + figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'y', sliderValue),[],'InitialMagnification', magnification); + ylabel('y') + xlabel('z') + set(gcf,'Name','ASTRA DATA GUI') + elseif get(handles.btn_y, 'Value') == 1 + figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'x', sliderValue),[],'InitialMagnification', magnification); + ylabel('x') + xlabel('z') + set(gcf,'Name','ASTRA DATA GUI') + else + figure(figure_number), imshow(sliceExtractor((image_matrix(:,:,:)), 'z', sliderValue),[],'InitialMagnification', magnification); + ylabel('x') + xlabel('y') + set(gcf,'Name','ASTRA DATA GUI') + end + + +% --- Executes on slider movement. +function sld_slice_Callback(hObject, eventdata, handles) +% hObject handle to sld_slice (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +sliderValue = floor(get(handles.sld_slice, 'Value')); +set(handles.txt_slice, 'String', num2str(sliderValue)); +showimage(handles); + +% --- Executes during object creation, after setting all properties. +function sld_slice_CreateFcn(hObject, eventdata, handles) +% hObject handle to sld_slice (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: slider controls usually have a light gray background. +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + + +% --- Executes on button press in pushbutton2. +function pushbutton2_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton3. +function pushbutton3_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pushbutton4. +function pushbutton4_Callback(hObject, eventdata, handles) +% hObject handle to pushbutton4 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +function txt_slice_Callback(hObject, eventdata, handles) +% hObject handle to txt_slice (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +slice = str2double(get(handles.txt_slice, 'String')); +max = str2num(get(handles.txt_max,'String')); +min = str2num(get(handles.txt_min,'String')); +if(slice > max) + set(handles.txt_slice, 'String', num2str(max)); + set(handles.sld_slice, 'Value', max); +elseif(slice < min) + set(handles.txt_slice, 'String', num2str(min)); + set(handles.sld_slice, 'Value', min); +else + set(handles.sld_slice, 'Value', slice); +end +showimage(handles); + +% --- Executes during object creation, after setting all properties. +function txt_slice_CreateFcn(hObject, eventdata, handles) +% hObject handle to txt_slice (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes on slider movement. +function sld_magnification_Callback(hObject, eventdata, handles) +% hObject handle to sld_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'Value') returns position of slider +% get(hObject,'Min') and get(hObject,'Max') to determine range of slider +sliderValue3 = floor(get(handles.sld_magnification, 'Value')); +set(handles.txt_mag, 'String', num2str(sliderValue3)); + +if(~isempty(handles.data)) + showimage(handles); +end + + + +% --- Executes during object creation, after setting all properties. +function sld_magnification_CreateFcn(hObject, eventdata, handles) +% hObject handle to sld_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called +% Hint: slider controls usually have a light gray background. +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + + +function txt_mag_Callback(hObject, eventdata, handles) +% hObject handle to txt_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +magnification = str2double(get(handles.txt_mag, 'String')); +if(magnification > 400) + set(handles.txt_mag, 'String', num2str(400)); + set(handles.sld_magnification, 'Value', 400); +elseif(magnification < 1) + set(handles.txt_mag, 'String', num2str(1)); + set(handles.sld_magnification, 'Value', 1); +else + set(handles.sld_magnification, 'Value', magnification); +end + +if(~isempty(handles.data)) + showimage(handles); +end + +% --- Executes during object creation, after setting all properties. +function txt_mag_CreateFcn(hObject, eventdata, handles) +% hObject handle to txt_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: edit controls usually have a white background on Windows. +% See ISPC and COMPUTER. +if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor','white'); +end + +% --- Executes on slider movement. +function figure_number_Callback(hObject, eventdata, handles) +% hObject handle to sld_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: get(hObject,'Value') returns position of slider +% get(hObject,'Min') and get(hObject,'Max') to determine range of slider +number = floor(str2double(get(handles.figure_number, 'String'))); +if(number < 1) + set(handles.figure_number, 'String', num2str(1)); +else + set(handles.figure_number, 'String', num2str(number)); +end + +if(~isempty(handles.data)) + showimage(handles); +end + + +% --- Executes during object creation, after setting all properties. +function figure_number_CreateFcn(hObject, eventdata, handles) +% hObject handle to sld_slice2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called +% Hint: slider controls usually have a light gray background. +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + + + +% --- Executes when selected object is changed in btn_dir. +function btn_dir_SelectionChangeFcn(hObject, eventdata, handles) +% hObject handle to the selected object in btn_dir +% eventdata structure with the following fields (see UIBUTTONGROUP) +% EventName: string 'SelectionChanged' (read only) +% OldValue: handle of the previously selected object or empty if none was selected +% NewValue: handle of the currently selected object +% handles structure with handles and user data (see GUIDATA) + +data = handles.data; + +if(hObject == handles.btn_x) + set(handles.btn_x, 'Value', 1); + set(handles.btn_y, 'Value', 0); + set(handles.btn_z, 'Value', 0); +elseif(hObject == handles.btn_y) + set(handles.btn_x, 'Value', 0); + set(handles.btn_y, 'Value', 1); + set(handles.btn_z, 'Value', 0); +elseif(hObject == handles.btn_z) + set(handles.btn_x, 'Value', 0); + set(handles.btn_y, 'Value', 0); + set(handles.btn_z, 'Value', 1); +end + +if get(handles.btn_x, 'Value') == 1 + set(handles.sld_slice, 'Min',1); + set(handles.sld_slice, 'Max', size(data,1)); + set(handles.sld_slice, 'SliderStep', [1/(size(data,1)-2) 1/(size(data,1)-2)]); + set(handles.sld_slice, 'Value', size(data,1)/2); + + sliderValue = get(handles.sld_slice, 'Value'); + set(handles.txt_slice, 'String', num2str(sliderValue)); + set(handles.txt_min, 'String', num2str(1)); + set(handles.txt_max, 'String', num2str(size(data,1))); + +elseif get(handles.btn_y, 'Value') == 1 + set(handles.sld_slice, 'Min',1); + set(handles.sld_slice, 'Max', size(data,2)); + set(handles.sld_slice, 'SliderStep', [1/(size(data,2)-2) 1/(size(data,2)-2)]); + set(handles.sld_slice, 'Value', size(data,2)/2); + + sliderValue = get(handles.sld_slice, 'Value'); + set(handles.txt_slice, 'String', num2str(sliderValue)); + set(handles.txt_min, 'String', num2str(1)); + set(handles.txt_max, 'String', num2str(size(data,2))); +else + set(handles.sld_slice, 'Min',1); + set(handles.sld_slice, 'Max', size(data,3)); + set(handles.sld_slice, 'SliderStep', [1/(size(data,3)-2) 1/(size(data,3)-2)]); + set(handles.sld_slice, 'Value', size(data,3)/2); + + sliderValue = get(handles.sld_slice, 'Value'); + set(handles.txt_slice, 'String', num2str(sliderValue)); + set(handles.txt_min, 'String', num2str(1)); + set(handles.txt_max, 'String', num2str(size(data,3))); +end + +showimage(handles); diff --git a/matlab/tools/astra_data_op.m b/matlab/tools/astra_data_op.m new file mode 100644 index 0000000..b6ef0e2 --- /dev/null +++ b/matlab/tools/astra_data_op.m @@ -0,0 +1,11 @@ +function astra_data_op(op, data, scalar, gpu_core) + +cfg = astra_struct('DataOperation_CUDA'); +cfg.Operation = op; +cfg.Scalar = scalar; +cfg.DataId = data; +cfg.option.GPUindex = gpu_core; + +alg_id = astra_mex_algorithm('create',cfg); +astra_mex_algorithm('run',alg_id); +astra_mex_algorithm('delete',alg_id);
\ No newline at end of file diff --git a/matlab/tools/astra_data_op_mask.m b/matlab/tools/astra_data_op_mask.m new file mode 100644 index 0000000..d46c925 --- /dev/null +++ b/matlab/tools/astra_data_op_mask.m @@ -0,0 +1,12 @@ +function astra_data_op_mask(op, data, scalar, mask, gpu_core) + +cfg = astra_struct('DataOperation_CUDA'); +cfg.Operation = op; +cfg.Scalar = scalar; +cfg.DataId = data; +cfg.option.GPUindex = gpu_core; +cfg.option.MaskId = mask; + +alg_id = astra_mex_algorithm('create',cfg); +astra_mex_algorithm('run',alg_id); +astra_mex_algorithm('delete',alg_id);
\ No newline at end of file diff --git a/matlab/tools/astra_downsample_sinogram.m b/matlab/tools/astra_downsample_sinogram.m new file mode 100644 index 0000000..30c1cdd --- /dev/null +++ b/matlab/tools/astra_downsample_sinogram.m @@ -0,0 +1,36 @@ +function [sinogram_new, proj_geom_new] = astra_downsample_sinogram(sinogram, proj_geom, factor) + +%------------------------------------------------------------------------ +% [sinogram_new, proj_geom_new] = astra_downsample_sinogram(sinogram, proj_geom, factor) +% +% Downsample the sinogram with some factor and adjust projection geometry +% accordingly +% +% sinogram: MATLAB data version of the sinogram. +% proj_geom: MATLAB struct containing the projection geometry. +% factor: the factor by which the number of detectors is divided. +% sinogram_new: MATLAB data version of the resampled sinogram. +% proj_geom_new: MATLAB struct containing the new projection geometry. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +if mod(size(sinogram,2),factor) ~= 0 + disp('size of the sinogram must be a divisor of the factor'); +end + +sinogram_new = zeros(size(sinogram,1),size(sinogram,2)/factor); +for i = 1:size(sinogram,2)/factor + sinogram_new(:,i) = sum(sinogram(:,(factor*(i-1)+1):factor*i),2); +end + +proj_geom_new = proj_geom; +proj_geom_new.DetectorCount = proj_geom_new.DetectorCount / factor; diff --git a/matlab/tools/astra_geom_2vec.m b/matlab/tools/astra_geom_2vec.m new file mode 100644 index 0000000..0abd07c --- /dev/null +++ b/matlab/tools/astra_geom_2vec.m @@ -0,0 +1,84 @@ +function proj_geom_out = astra_geom_2vec(proj_geom) + + % FANFLAT + if strcmp(proj_geom.type,'fanflat') + + vectors = zeros(numel(proj_geom.ProjectionAngles), 6); + for i = 1:numel(proj_geom.ProjectionAngles) + + % source + vectors(i,1) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource; + vectors(i,2) = -cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource; + + % center of detector + vectors(i,3) = -sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector; + vectors(i,4) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector; + + % vector from detector pixel 0 to 1 + vectors(i,5) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorWidth; + vectors(i,6) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorWidth; + end + + proj_geom_out = astra_create_proj_geom('fanflat_vec', proj_geom.DetectorCount, vectors); + + % CONE + elseif strcmp(proj_geom.type,'cone') + + vectors = zeros(numel(proj_geom.ProjectionAngles), 12); + for i = 1:numel(proj_geom.ProjectionAngles) + + % source + vectors(i,1) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource; + vectors(i,2) = -cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginSource; + vectors(i,3) = 0; + + % center of detector + vectors(i,4) = -sin(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector; + vectors(i,5) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DistanceOriginDetector; + vectors(i,6) = 0; + + % vector from detector pixel (0,0) to (0,1) + vectors(i,7) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX; + vectors(i,8) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX; + vectors(i,9) = 0; + + % vector from detector pixel (0,0) to (1,0) + vectors(i,10) = 0; + vectors(i,11) = 0; + vectors(i,12) = proj_geom.DetectorSpacingY; + end + + proj_geom_out = astra_create_proj_geom('cone_vec', proj_geom.DetectorRowCount, proj_geom.DetectorColCount, vectors); + + % PARALLEL + elseif strcmp(proj_geom.type,'parallel3d') + + vectors = zeros(numel(proj_geom.ProjectionAngles), 12); + for i = 1:numel(proj_geom.ProjectionAngles) + + % ray direction + vectors(i,1) = sin(proj_geom.ProjectionAngles(i)); + vectors(i,2) = -cos(proj_geom.ProjectionAngles(i)); + vectors(i,3) = 0; + + % center of detector + vectors(i,4) = 0; + vectors(i,5) = 0; + vectors(i,6) = 0; + + % vector from detector pixel (0,0) to (0,1) + vectors(i,7) = cos(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX; + vectors(i,8) = sin(proj_geom.ProjectionAngles(i)) * proj_geom.DetectorSpacingX; + vectors(i,9) = 0; + + % vector from detector pixel (0,0) to (1,0) + vectors(i,10) = 0; + vectors(i,11) = 0; + vectors(i,12) = proj_geom.DetectorSpacingY; + end + + proj_geom_out = astra_create_proj_geom('parallel3d_vec', proj_geom.DetectorRowCount, proj_geom.DetectorColCount, vectors); + + else + error(['No suitable vector geometry found for type: ' proj_geom.type]) + end diff --git a/matlab/tools/astra_geom_postalignment.m b/matlab/tools/astra_geom_postalignment.m new file mode 100644 index 0000000..4115af2 --- /dev/null +++ b/matlab/tools/astra_geom_postalignment.m @@ -0,0 +1,11 @@ +function proj_geom = astra_geom_postalignment(proj_geom, factor) + + if strcmp(proj_geom.type,'fanflat_vec') + proj_geom.Vectors(:,3:4) = proj_geom.Vectors(:,3:4) + factor * proj_geom.Vectors(:,5:6); + + elseif strcmp(proj_geom.type,'cone_vec') || strcmp(proj_geom.type,'parallel3d_vec') + proj_geom.Vectors(:,4:6) = proj_geom.Vectors(:,4:6) + factor * proj_geom.Vectors(:,7:9); + + else + error('Projection geometry not suited for postalignment correction.') + end diff --git a/matlab/tools/astra_geom_size.m b/matlab/tools/astra_geom_size.m new file mode 100644 index 0000000..c4956f5 --- /dev/null +++ b/matlab/tools/astra_geom_size.m @@ -0,0 +1,28 @@ +function s = astra_geom_size(geom, dim) + + if isfield(geom, 'GridSliceCount') + % 3D Volume geometry? + s = [ geom.GridColCount, geom.GridRowCount, geom.GridSliceCount ]; + elseif isfield(geom, 'GridColCount') + % 2D Volume geometry? + s = [ geom.GridRowCount, geom.GridColCount ]; + elseif strcmp(geom.type,'parallel') || strcmp(geom.type,'fanflat') + s = [numel(geom.ProjectionAngles), geom.DetectorCount]; + + elseif strcmp(geom.type,'parallel3d') || strcmp(geom.type,'cone') + s = [geom.DetectorRowCount, numel(geom.ProjectionAngles), geom.DetectorColCount]; + + elseif strcmp(geom.type,'fanflat_vec') + s = [size(geom.Vectors,1), geom.DetectorCount]; + + elseif strcmp(geom.type,'parallel3d_vec') || strcmp(geom.type,'cone_vec') + s = [geom.DetectorColCount, size(geom.Vectors,1), geom.DetectorRowCount]; + + end + + if nargin == 2 + s = s(dim); + end + +end + diff --git a/matlab/tools/astra_geom_superresolution.m b/matlab/tools/astra_geom_superresolution.m new file mode 100644 index 0000000..b2b0ebf --- /dev/null +++ b/matlab/tools/astra_geom_superresolution.m @@ -0,0 +1,14 @@ +function proj_geom = astra_geom_superresolution(proj_geom, factor) + + if strcmp(proj_geom.type,'parallel') + proj_geom.DetectorWidth = proj_geom.DetectorWidth/factor; + proj_geom.DetectorCount = proj_geom.DetectorCount * factor; + elseif strcmp(proj_geom.type,'fanflat') + proj_geom.DetectorWidth = proj_geom.DetectorWidth/factor; + proj_geom.DetectorCount = proj_geom.DetectorCount * factor; + elseif strcmp(proj_geom.type,'fanflat_vec') + proj_geom.Vectors(:,5:6) = proj_geom.Vectors(:,5:6) / factor; % DetectorSize + proj_geom.DetectorCount = proj_geom.DetectorCount * factor; + else + error('Projection geometry not suited for super-resolution (or not implemented).') + end diff --git a/matlab/tools/astra_imshow.m b/matlab/tools/astra_imshow.m new file mode 100644 index 0000000..6069674 --- /dev/null +++ b/matlab/tools/astra_imshow.m @@ -0,0 +1,10 @@ +function V = astra_imshow(data, range) + +if numel(data) == 1 + data = astra_mex_data2d('get', data); +end +imshow(data,range); + +if nargout >= 1 + V = data; +end
\ No newline at end of file diff --git a/matlab/tools/astra_mex.m b/matlab/tools/astra_mex.m new file mode 100644 index 0000000..e04cfea --- /dev/null +++ b/matlab/tools/astra_mex.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex' )">astra_mex</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_algorithm.m b/matlab/tools/astra_mex_algorithm.m new file mode 100644 index 0000000..138a43c --- /dev/null +++ b/matlab/tools/astra_mex_algorithm.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_algorithm(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_algorithm' )">astra_mex_algorithm</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_algorithm_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_algorithm_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_data2d.m b/matlab/tools/astra_mex_data2d.m new file mode 100644 index 0000000..eacbcb9 --- /dev/null +++ b/matlab/tools/astra_mex_data2d.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_data2d(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_data2d' )">astra_mex_data2d</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_data2d_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_data2d_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_data3d.m b/matlab/tools/astra_mex_data3d.m new file mode 100644 index 0000000..3bbbd68 --- /dev/null +++ b/matlab/tools/astra_mex_data3d.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_data3d(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_data3d' )">astra_mex_data3d</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_data3d_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_data3d_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_matrix.m b/matlab/tools/astra_mex_matrix.m new file mode 100644 index 0000000..182ab1e --- /dev/null +++ b/matlab/tools/astra_mex_matrix.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_matrix(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_matrix' )">astra_mex_matrix</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_matrix_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_matrix_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_projector.m b/matlab/tools/astra_mex_projector.m new file mode 100644 index 0000000..487da06 --- /dev/null +++ b/matlab/tools/astra_mex_projector.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_projector(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_projector' )">astra_mex_projector</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_projector_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_projector_c(varargin{:}); +end diff --git a/matlab/tools/astra_mex_projector3d.m b/matlab/tools/astra_mex_projector3d.m new file mode 100644 index 0000000..3d21ce9 --- /dev/null +++ b/matlab/tools/astra_mex_projector3d.m @@ -0,0 +1,24 @@ +function [varargout] = astra_mex_projector3d(varargin) +%------------------------------------------------------------------------ +% Reference page in Help browser +% <a href="matlab:docsearch('astra_mex_projector3d' )">astra_mex_projector3d</a>. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +if nargout == 0 + astra_mex_projector3d_c(varargin{:}); + if exist('ans','var') + varargout{1} = ans; + end +else + varargout = cell(1,nargout); + [varargout{:}] = astra_mex_projector3d_c(varargin{:}); +end diff --git a/matlab/tools/astra_projector_handle.m b/matlab/tools/astra_projector_handle.m new file mode 100644 index 0000000..72d4c73 --- /dev/null +++ b/matlab/tools/astra_projector_handle.m @@ -0,0 +1,29 @@ +classdef astra_projector_handle < handle + %ASTRA_PROJECTOR_HANDLE Handle class around an astra_mex_projector id + % Automatically deletes the projector when deleted. + + %------------------------------------------------------------------------ + % This file is part of the + % All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") + % + % Copyright: iMinds-Vision Lab, University of Antwerp + % License: Open Source under GPLv3 + % Contact: mailto:astra@ua.ac.be + % Website: http://astra.ua.ac.be + %------------------------------------------------------------------------ + + properties + id + end + + methods + function obj = astra_projector_handle(proj_id) + obj.id = proj_id; + end + function delete(obj) + astra_mex_projector('delete', obj.id); + end + end + +end + diff --git a/matlab/tools/astra_set_directory.m b/matlab/tools/astra_set_directory.m new file mode 100644 index 0000000..1d5a368 --- /dev/null +++ b/matlab/tools/astra_set_directory.m @@ -0,0 +1,27 @@ +function in = astra_set_directory(in) + +%------------------------------------------------------------------------ +% in = astra_set_directory(in) +% +% Creates the directories present in the input path if they do not exist +% already +% +% in: input path. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +a = find(in == '/' | in == '\'); +for i = 1:numel(a) + if ~isdir(in(1:a(i))) + mkdir(in(1:a(i))); + end +end diff --git a/matlab/tools/astra_struct.m b/matlab/tools/astra_struct.m new file mode 100644 index 0000000..f65b2ec --- /dev/null +++ b/matlab/tools/astra_struct.m @@ -0,0 +1,37 @@ +function res = astra_struct(type) + +%------------------------------------------------------------------------ +% res = astra_struct(type) +% +% Create an ASTRA struct +% +% type: type of the struct to be generated. +% res: the generated matlab struct. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ +res = struct(); +res.options = struct(); + + +if nargin >= 1 + % For backward compatibility, transparently accept SIRT_CUDA2 + % for SIRT_CUDA, and FP_CUDA2 for FP_CUDA. + if strcmp(type, 'SIRT_CUDA2') + type = 'SIRT_CUDA'; + warning('SIRT_CUDA2 has been deprecated. Use SIRT_CUDA instead.'); + end + if strcmp(type, 'FP_CUDA2') + type = 'FP_CUDA'; + warning('FP_CUDA2 has been deprecated. Use FP_CUDA instead.'); + end + res.type = type; +end diff --git a/matlab/tools/compute_rnmp.m b/matlab/tools/compute_rnmp.m new file mode 100644 index 0000000..6c00a01 --- /dev/null +++ b/matlab/tools/compute_rnmp.m @@ -0,0 +1,29 @@ +function [rnmp, nmp] = compute_rnmp(phantom, S) + + phantom = double(phantom == max(phantom(:))); + S = double(S == max(S(:))); + + %u1 = sort(unique(phantom)); + %u2 = sort(unique(S)); + %for i = 1:numel(u1) + % phantom_(phantom == u1(i)) = i; + % S_(S == u2(i)) = i; + %end + %phantom = phantom_; + %S = S_; + + if numel(size(phantom)) == 2 + S = imresize(S, size(phantom), 'nearest'); + elseif numel(size(phantom)) == 3 + S2 = zeros(size(phantom)); + for slice = 1:size(phantom,3) + S2(:,:,slice) = imresize(S(:,:,slice), [size(phantom,1) size(phantom,2)], 'nearest'); + end + S = S2; + end + + nmp = sum(abs(phantom(:) ~= S(:))); + rnmp = nmp / sum(phantom(:)); + +end + diff --git a/matlab/tools/createOrderART.m b/matlab/tools/createOrderART.m new file mode 100644 index 0000000..a469d8a --- /dev/null +++ b/matlab/tools/createOrderART.m @@ -0,0 +1,66 @@ +function rayOrder = createOrderART(proj_geom, mode) + +%------------------------------------------------------------------------ +% rayOrder = createOrderART(proj_geom, mode) +% +% Creates an array defining the order in which ART will iterate over the +% projections and projection rays +% +% proj_geom: MATLAB struct containing the projection geometry. +% mode: string defining the wanted ray order, can be either 'sequential', +% 'randomray' or 'randomproj'. +% rayOrder: array of two columns of length angle_count * det_count, with +% the first column being the index of the projection and the second column +% the index of the ray. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +angle_count = length(proj_geom.projection_angles); +det_count = proj_geom.detector_count; + +% create order +rayOrder = zeros(angle_count * det_count, 2); +if strcmp(mode,'sequential') == 1 + index = 1; + for i = 1:angle_count + for j = 1:det_count + rayOrder(index,1) = i; + rayOrder(index,2) = j; + index = index + 1; + end + end +elseif strcmp(mode,'randomray') == 1 + index = 1; + for i = 1:angle_count + for j = 1:det_count + rayOrder(index,1) = i; + rayOrder(index,2) = j; + index = index + 1; + end + end + r = randperm(angle_count * det_count); + rayOrder(:,1) = rayOrder(r,1); + rayOrder(:,2) = rayOrder(r,2); +elseif strcmp(mode,'randomproj') == 1 + index = 1; + r = randperm(angle_count); + for i = 1:angle_count + for j = 1:det_count + rayOrder(index,1) = r(i); + rayOrder(index,2) = j; + index = index + 1; + end + end +else + disp('mode not known'); +end + diff --git a/matlab/tools/downsample_sinogram.m b/matlab/tools/downsample_sinogram.m new file mode 100644 index 0000000..1fb4ec8 --- /dev/null +++ b/matlab/tools/downsample_sinogram.m @@ -0,0 +1,12 @@ +function sinogram_out = downsample_sinogram(sinogram, ds) + + if ds == 1 + sinogram_out = sinogram; + return; + end + + sinogram_out = sinogram(:,1:ds:end,:); + for i = 2:ds + sinogram_out = sinogram_out + sinogram(:,i:ds:end,:); + end + sinogram_out = sinogram_out / (ds*ds);
\ No newline at end of file diff --git a/matlab/tools/imreadgs.m b/matlab/tools/imreadgs.m new file mode 100644 index 0000000..9c27eb4 --- /dev/null +++ b/matlab/tools/imreadgs.m @@ -0,0 +1,26 @@ +function Im = imreadgs(filename) + +%------------------------------------------------------------------------ +% Im = imreadgs(filename) +% +% Reads an image and transforms it into a grayscale image consisting of +% doubles. +% +% filename: name of the image file. +% Im: a grayscale image in double. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +Im = double(imread(filename)); +if size(Im,3) > 1 + Im = Im(:,:,1); +end diff --git a/matlab/tools/imresize3D.m b/matlab/tools/imresize3D.m new file mode 100644 index 0000000..9032cc3 --- /dev/null +++ b/matlab/tools/imresize3D.m @@ -0,0 +1,26 @@ +function out = imresize3D(in, s_out, method) + +%------------------------------------------------------------------------ +% out = imresize3D(in, s_out, method) +% +% Resizes a 3-component image +% +% in: input image. +% s_out: 2 element array with the wanted image size, [rows columns]. +% out: the resized 3-component image. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +out = zeros(s_out); +for i = 1:size(in,3) + out(:,:,i) = imresize(in(:,:,i), s_out(1:2), method); +end diff --git a/matlab/tools/imscale.m b/matlab/tools/imscale.m new file mode 100644 index 0000000..957f11f --- /dev/null +++ b/matlab/tools/imscale.m @@ -0,0 +1,28 @@ +function out = imscale(in) + +%------------------------------------------------------------------------ +% out = imscale(in) +% +% Rescales the image values between zero and one. +% +% in: input image. +% out: scaled output image. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +mi = min(in(:)); +ma = max(in(:)); +if (ma-mi) == 0 + out = zeros(size(in)); +else + out = (in - mi) / (ma - mi); +end diff --git a/matlab/tools/imwritesc.m b/matlab/tools/imwritesc.m new file mode 100644 index 0000000..2f81dc8 --- /dev/null +++ b/matlab/tools/imwritesc.m @@ -0,0 +1,22 @@ +function imwritesc(in, filename) + +%------------------------------------------------------------------------ +% imwritesc(in, filename) +% +% Rescale between zero and one and write image +% +% in: input image. +% filename: name of output image file. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +imwrite(imscale(in),filename); diff --git a/matlab/tools/kaiserBessel.m b/matlab/tools/kaiserBessel.m new file mode 100644 index 0000000..aef7b9d --- /dev/null +++ b/matlab/tools/kaiserBessel.m @@ -0,0 +1,31 @@ +function res = kaiserBessel(m,alpha,a,r) + +%------------------------------------------------------------------------ +% res = kaiserBessel(m,alpha,a,r) +% +% Calculates the Kaiser windowing function +% +% a: length of the sequence. +% m: order. +% alpha: determines shape of window. +% r: input values for which to compute window value. +% res: the window values. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +sq = sqrt(1 - (r./a).^2); + +res1 = 1 ./ besseli(m, alpha); +res2 = sq .^ m; +res3 = besseli(m, alpha .* sq); + +res = res1 .* res2 .* res3; diff --git a/matlab/tools/linspace2.m b/matlab/tools/linspace2.m new file mode 100644 index 0000000..2787fd9 --- /dev/null +++ b/matlab/tools/linspace2.m @@ -0,0 +1,25 @@ +function out = linspace2(a,b,c) + +%------------------------------------------------------------------------ +% out = linspace2(a,b,c) +% +% Generates linearly spaced vectors +% +% a: lower limit. +% b: upper limit (exclusive). +% c: number of elements. +% out: linearly spaced vector. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +out = linspace(a,b,c+1); +out = out(1:end-1); diff --git a/matlab/tools/overlayImage.m b/matlab/tools/overlayImage.m new file mode 100644 index 0000000..7c81e55 --- /dev/null +++ b/matlab/tools/overlayImage.m @@ -0,0 +1,24 @@ +function im = overlayImage(reconstruction, ground_truth) +%------------------------------------------------------------------------ +% im = overlayImage(reconstruction, ground_truth) +% +% Produces an overlay image of two images, useful for image comparison. +% +% reconstruction: first input image matrix. +% ground_truth: second input image matrix. +% im: output 3-component image, third channel is 0. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +im(:,:,1) = reconstruction ./ max(reconstruction(:)); +im(:,:,2) = ground_truth ./ max(ground_truth(:)); +im(:,:,3) = zeros(size(reconstruction)); diff --git a/matlab/tools/rebin_fan2par.m b/matlab/tools/rebin_fan2par.m new file mode 100644 index 0000000..da20932 --- /dev/null +++ b/matlab/tools/rebin_fan2par.m @@ -0,0 +1,82 @@ +function F = rebin_fan2par(RadonData, BetaDeg, D, thetaDeg) + +%------------------------------------------------------------------------ +% F = rebin_fan2par(RadonData, BetaDeg, D, thetaDeg) +% +% Deze functie zet fan beam data om naar parallelle data, door interpolatie +% (fast resorting algorithm, zie Kak en Slaney) +% Radondata zoals altijd: eerste coord gamma , de rijen +% tweede coord beta, de kolommen, beide hoeken in +% radialen +% PixPProj: aantal pixels per projectie (voor skyscan data typisch 1000) +% BetaDeg: vector met alle draaihoeken in graden +% D: afstand bron - rotatiecentrum in pixels, dus afstand +% bron-rotatiecentrum(um) gedeeld door image pixel size (um). +% thetaDeg: vector met gewenste sinogramwaarden voor theta in graden +% de range van thetaDeg moet steeds kleiner zijn dan die van betadeg +% D,gamma,beta, theta zoals gebruikt in Kak & Slaney +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +NpixPProj = size(RadonData,1); % aantal pixels per projectie +%if mod(size(Radondata,1),2)==0 +% NpixPProjNew=NpixPProj+1; +%else + NpixPProjNew = NpixPProj; +%end + +%% FAN-BEAM RAYS + +% flip sinogram, why? +RadonData = flipdim(RadonData,2); % matlab gebruikt tegengestelde draairichting (denkik) als skyscan, of er is een of andere flipdim geweest die gecorrigeerd moet worden)) + +% DetPixPos: distance of each detector to the ray through the origin (theta) +DetPixPos = -(NpixPProj-1)/2:(NpixPProj-1)/2; % posities detectorpixels + +% GammaStralen: alpha's? (result in radians!!) +GammaStralen = atan(DetPixPos/D); % alle met de detectorpixelposities overeenkomstige gammahoeken + +% put beta (theta) and gamma (alpha) for each ray in 2D matrices +[beta gamma] = meshgrid(BetaDeg,GammaStralen); + +% t: minimal distance between each ray and the ray through the origin +t = D*sin(gamma); % t-waarden overeenkomstig met de verschillende gamma's + +theta = gamma*180/pi + beta; % theta-waarden in graden overeenkomstig met verschillende gamma en beta waarden + +%% PARALLEL BEAM RAYS + +% DetPixPos: distance of each detector to the ray through the origin (theta) +DetPixPos = -(NpixPProjNew-1)/2:(NpixPProjNew-1)/2; % posities detectorpixels + +% GammaStralen: alpha's? (result in radians!!) +GammaStralenNew = atan(DetPixPos/D); % alle met de detectorpixelposities overeenkomstige gammahoeken + +% put beta (theta) and gamma (alpha) for each ray in 2D matrices +[~, gamma] = meshgrid(BetaDeg,GammaStralenNew); + +% t: minimal distance between each ray and the ray through the origin +tnew = D * sin(gamma); % t-waarden overeenkomstig met de verschillende gamma's + +% calculate new t +step = (max(tnew)-min(tnew)) / (NpixPProjNew-1); +t_para = min(tnew):step:max(tnew); + +[thetaNewCoord tNewCoord] = meshgrid(thetaDeg, t_para); + +%% Interpolate +Interpolant = TriScatteredInterp(theta(:), t(:), RadonData(:),'nearest'); +F = Interpolant(thetaNewCoord,tNewCoord); + + + + diff --git a/matlab/tools/sliceExtractor.m b/matlab/tools/sliceExtractor.m new file mode 100644 index 0000000..dfc87ee --- /dev/null +++ b/matlab/tools/sliceExtractor.m @@ -0,0 +1,34 @@ +function slice = sliceExtractor(data, dir, slicenr) + +%------------------------------------------------------------------------ +% slice = sliceExtractor(data, dir, slicenr) +% +% Outputs a specified slice from a three dimensional matrix/volume +% +% data: the 3D volume. +% dir: the direction in which the volume is sliced. +% slicenr: the index of the slice to retrieve. +% slice: 2D image matrix containing the slice. +%------------------------------------------------------------------------ +%------------------------------------------------------------------------ +% This file is part of the +% All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA-Toolbox") +% +% Copyright: iMinds-Vision Lab, University of Antwerp +% License: Open Source under GPLv3 +% Contact: mailto:astra@ua.ac.be +% Website: http://astra.ua.ac.be +%------------------------------------------------------------------------ +% $Id$ + +slicenr = round(slicenr); + +if strcmp(dir,'z') + slice = squeeze(data(:,:,slicenr)); +end +if strcmp(dir,'x') + slice = squeeze(data(:,slicenr,:)); +end +if strcmp(dir,'y') + slice = squeeze(data(slicenr,:,:)); +end |