Skip to content

Commit

Permalink
Update repo to version 2 (according to published paper)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathé Zeegers committed Sep 28, 2022
1 parent 58e242a commit 02944e2
Show file tree
Hide file tree
Showing 25 changed files with 1,539 additions and 1,111 deletions.
60 changes: 46 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,45 @@ https://www.cs.ubc.ca/~schmidtm/Software/minConf.html
https://www.mathworks.com/matlabcentral/fileexchange/9416-3d-shepp-logan-phantom


## Examples:
## Scripts:

Seven examples are provided with the code. Before running any example, please run the startup.m script first. Each example uses a different phantom:
1. example_SheppLogan:
Eight examples are provided with the code. Before running any example, please run the startup.m script first.
1. example1_SheppLogan:
The classic Shepp-Logan phantom with variable size
2. example_Disk:
2. example2_Disk:
A custom-made disk example with variable size and number of disks
3. example_Thorax:
3. example3_Thorax:
The synthetic phantom mimics internal body structure in an abstract fashion (taken from the CONRAD software framework: https://git5.cs.fau.de/PyConrad/pyCONRAD)
4. example_SheppLogan_SparseAngle:
4. example4_SheppLogan_SparseAngle:
The Shepp-Logan phantom with only 10 projection angles (adjustable)
5. example_SheppLogan_LimitedView:
5. example5_SheppLogan_LimitedView:
The Shepp-Logan phantom with a missing wedge of 60 degrees (adjustable)
6. example_MixedDisk:
6. example6_MixedDisk:
A custom-made disk example with variable size and number of disks, where the disks consists of multiple materials
7. example_SheppLogan3D:
7. example7_SheppLogan3D:
3D version of the Shepp-Logan phnatom with adjustable size
8. example8_microCTData.m:
A demonstration of the approach on real micro-CT data from a natural rock sample. The source of the data can be found further below.

On each phantom the four implemented algorithms (UR, RU, cJoint and ADJUST) are performed. The perfomance of these algorithms are captured by computing and presenting the MSE, PSNR, and the SSIM between the reconstructed material maps and the ground truth. Below are results for a numerical study on the Shepp-Logan phantom:
On each case the four implemented algorithms (UR, RU, cJoint and ADJUST) can be tested. The perfomance of these algorithms are captured by computing and presenting the MSE, PSNR, and the SSIM between the reconstructed material spatial maps and the ground truth.


## Example results:

As an example, below are results for a numerical study on the Shepp-Logan phantom:
<p align="center">
<img src="./images/comparison.png">
</p>
<p align="center">
<img src="./images/comparison-maps.png">
</p>

For the micro-CT dataset, four different materials (lead, tungsten, quartz and gold) can be reconstructed. An example reconstruction is shown below:

<p align="center">
<img src="./images/micro_ct_dataset_result.png">
</p>


## Generation of spectral data

Expand All @@ -77,17 +91,35 @@ These scripts are written in Python (version 3.7 or higher). Apart from this, ph

## References

The algorithms implemented in this MATLAB package are described in following paper:
The algorithms implemented in this MATLAB package are described in following [paper](https://iopscience.iop.org/article/10.1088/1361-6420/ac932e):

```
@article{
title={ADJUST: A Dictionary-Based Joint Reconstruction and Unmixing Method for Spectral Tomography},
author={Zeegers, Math{\'e} T and Kadu, Ajinkya and van Leeuwen, Tristan and Batenburg, Kees Joost},
journal={arXiv preprint arXiv:2112.11406},
year={2021}
journal={Inverse Problems},
year={2022},
publisher={IOP Publishing},
doi={10.1088/1361-6420/ac932e}
}
```
The preprint can be found [here](https://arxiv.org/abs/2112.11406)

The micro-CT dataset required to run the eighth script is introduced in the paper below:

```
@article{sittner2021spectral,
title={Spectral X-ray computed micro tomography: 3-dimensional chemical imaging},
author={Sittner, Jonathan and Godinho, Jose RA and Renno, Axel D and Cnudde, Veerle and Boone, Marijn and De Schryver, Thomas and Van Loo, Denis and Merkulova, Margarita and Roine, Antti and Liipo, Jussi},
journal={X-Ray Spectrometry},
volume={50},
number={2},
pages={92--105},
year={2021},
publisher={Wiley Online Library}
}
```
The preprint can be found [here](https://arxiv.org/pdf/2112.11406.pdf).
The dataset can be found [here](https://rodare.hzdr.de/record/1627).


## Authors
Expand Down

Large diffs are not rendered by default.

93 changes: 0 additions & 93 deletions data/MatrixTXray100chan_93mat_20MinEn_119MaxEn.csv

This file was deleted.

42 changes: 0 additions & 42 deletions data/MatrixTXrayHard100chan_93mat_20MinEn_119MaxEn.csv

This file was deleted.

Large diffs are not rendered by default.

118 changes: 118 additions & 0 deletions examples/example1_SheppLogan.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
%%% Spectral Tomography
%%% Shepp Logan phantom of size 512 x 512
%%% 5 materials
%%% 100 channels
%%% Full-view setting: 60 angles from 0 to 180 degrees
%%% Non-inverse crime configuration: measurements are simulated on 2x
%%% high-resolution grid and corrupted with mild Poisson noise.
%
% Authors:
% Ajinkya Kadu,
% Centrum Wiskunde & Informatica, Amsterdam ([email protected])
% Mathé Zeegers,
% Centrum Wiskunde & Informatica, Amsterdam ([email protected])

clc; clearvars; close all;

% setting random stream
myStream = RandStream('mt19937ar','Seed',10);
RandStream.setGlobalStream(myStream)

% directory for saving results
saveDir = [pwd '\results\'];
if ~exist(saveDir,'dir'), mkdir(saveDir); end

%% settings

n = 512; % spatial resolution of phantom
phantom = 'SheppLogan'; % phantom name

%% load phantom (for measurement and inversion)

% load matrices for measurements (phantom discretized on 2x resolution grid)
[Am,Fm,Tm,Qm] = loadSpectralPhantom(phantom,2*n);

% load matrices for inversion
[A,F,T,Q] = loadSpectralPhantom(phantom,n);

% number of materials (in phantom)
k = size(A,2);

% problem structure
strProb.A = A;
strProb.F = F;
strProb.k = k;
strProb.T = T;
strProb.n = [n n];

%% generate spectral measurements (on 2x resolution grid)

% spectral volume
Um = Am*Fm;

% tomography operator
n_ang = 180;
theta = linspace(0,pi,n_ang);

volGeo = astra_create_vol_geom(2*n, 2*n);
projGeo= astra_create_proj_geom('parallel', 2, n,theta);
Wm = opTomo('cuda', projGeo, volGeo);

% spectral tomographic measurements with noise
Y0 = (Wm*Um)/2; % the factor of 2 division required for 2x grid
Y = 0*Y0;
for i=1:size(Y0,2)
Y(:,i) = astra_add_noise_to_sino(Y0(:,i), Qm(i));
end

%% (non-inverse-crime) forward operator to be used for inversion

volGeo = astra_create_vol_geom(n, n);
projGeo= astra_create_proj_geom('parallel', 1, n,theta);
W = opTomo('cuda', projGeo, volGeo);

% (only for checking) measurments with forward operator
U = A*F;
Y1 = W*U;

strProb.angles = theta;
strProb.Y = Y;
strProb.Yclean = Y1;

%% Spectral Tomography algorithms

%%% Reconstruction and then Unmixing
[Aru,Fru] = RU(Y,W,k);

strRU.A = Aru;
strRU.F = Fru;

%%% Unmixing then Reconstruction
[Aur,Fur] = UR(Y,W,k);

strUR.A = Aur;
strUR.F = Fur;

%%% cJoint
Jopt.rho = 1e-2;
Jopt.iterMax = 1000;
[Aj,Fj,histJ] = cJoint(Y,W,k,Jopt);

strJ.A = Aj;
strJ.F = Fj;

%%% ADJUST
Dopt.rho = 1e-2;
Dopt.iterMax = 1000;
[Ad,Fd,Rd,hist] = ADJUST(Y,W,k,T,Dopt);

strD.A = Ad;
strD.F = Fd;

%% plots and tables

strOut = computeResults(strProb,strRU,strUR,strJ,strD);

%% save results

save([saveDir 'example_SheppLogan.mat'],'strOut');
118 changes: 118 additions & 0 deletions examples/example2_Disk.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
%%% Spectral Tomography
%%% Disk phantom of size 512 x 512
%%% 8 materials
%%% 100 channels
%%% Full-view setting: 180 angles from 0 to 180 degrees
%%% Non-inverse crime configuration: measurements are simulated on 2x
%%% high-resolution grid and corrupted with mild Poisson noise.
%
% Authors:
% Ajinkya Kadu,
% Centrum Wiskunde & Informatica, Amsterdam ([email protected])
% Mathé Zeegers,
% Centrum Wiskunde & Informatica, Amsterdam ([email protected])

clc; clearvars; close all;

% setting random stream
myStream = RandStream('mt19937ar','Seed',10);
RandStream.setGlobalStream(myStream)

% directory for saving results
saveDir = [pwd '\results\'];
if ~exist(saveDir,'dir'), mkdir(saveDir); end

%% settings

n = 512; % spatial resolution of phantom
phantom = 'Disks'; % phantom name

%% load phantom (for measurement and inversion)

% load matrices for measurements (phantom discretized on 2x resolution grid)
[Am,Fm,Tm,Qm] = loadSpectralPhantom(phantom,2*n);

% load matrices for inversion
[A,F,T,Q] = loadSpectralPhantom(phantom,n);

% number of materials (in phantom)
k = size(A,2);

% problem structure
strProb.A = A;
strProb.F = F;
strProb.k = k;
strProb.T = T;
strProb.n = [n n];

%% generate spectral measurements (on 2x resolution grid)

% spectral volume
Um = Am*Fm;

% tomography operator
n_ang = 180;
theta = linspace(0,pi,n_ang);

volGeo = astra_create_vol_geom(2*n, 2*n);
projGeo= astra_create_proj_geom('parallel', 2, n,theta);
Wm = opTomo('cuda', projGeo, volGeo);

% spectral tomographic measurements with noise
Y0 = (Wm*Um)/2; % the factor of 2 division required for 2x grid
Y = 0*Y0;
for i=1:size(Y0,2)
Y(:,i) = astra_add_noise_to_sino(Y0(:,i), Qm(i));
end

%% (non-inverse-crime) forward operator to be used for inversion

volGeo = astra_create_vol_geom(n, n);
projGeo= astra_create_proj_geom('parallel', 1, n,theta);
W = opTomo('cuda', projGeo, volGeo);

% (only for checking) measurments with forward operator
U = A*F;
Y1 = W*U;

strProb.angles = theta;
strProb.Y = Y;
strProb.Yclean = Y1;

%% Spectral Tomography algorithms

%%% Reconstruction and then Unmixing
[Aru,Fru] = RU(Y,W,k);

strRU.A = Aru;
strRU.F = Fru;

%%% Unmixing then Reconstruction
[Aur,Fur] = UR(Y,W,k);

strUR.A = Aur;
strUR.F = Fur;

%%% cJoint
Jopt.rho = 1e-2;
Jopt.iterMax = 1000;
[Aj,Fj,histJ] = cJoint(Y,W,k,Jopt);

strJ.A = Aj;
strJ.F = Fj;

%%% ADJUST
Dopt.rho = 1e-2;
Dopt.iterMax = 1000;
[Ad,Fd,Rd,hist] = ADJUST(Y,W,k,T,Dopt);

strD.A = Ad;
strD.F = Fd;

%% plots and tables

strOut = computeResults(strProb,strRU,strUR,strJ,strD);

%% save results

save([saveDir 'example_Disk.mat'],'strOut');
Loading

0 comments on commit 02944e2

Please sign in to comment.