|
a |
|
b/README.md |
|
|
1 |
# DOSMA: Deep Open-Source Medical Image Analysis |
|
|
2 |
[](https://www.gnu.org/licenses/gpl-3.0) |
|
|
3 |
 |
|
|
4 |
[](https://codecov.io/gh/ad12/DOSMA) |
|
|
5 |
[](https://dosma.readthedocs.io/en/latest/?badge=latest) |
|
|
6 |
|
|
|
7 |
[Documentation](http://dosma.readthedocs.io/) | [Questionnaire](https://forms.gle/sprthTC2swyt8dDb6) | [DOSMA Basics Tutorial](https://colab.research.google.com/drive/1zY5-3ZyTBrn7hoGE5lH0IoQqBzumzP1i?usp=sharing) |
|
|
8 |
|
|
|
9 |
DOSMA is an AI-powered Python library for medical image analysis. This includes, but is not limited to: |
|
|
10 |
- image processing (denoising, super-resolution, registration, segmentation, etc.) |
|
|
11 |
- quantitative fitting and image analysis |
|
|
12 |
- anatomical visualization and analysis (patellar tilt, femoral cartilage thickness, etc.) |
|
|
13 |
|
|
|
14 |
We hope that this open-source pipeline will be useful for quick anatomy/pathology analysis and will serve as a hub for adding support for analyzing different anatomies and scan sequences. |
|
|
15 |
|
|
|
16 |
## Installation |
|
|
17 |
DOSMA requires Python 3.6+. The core module depends on numpy, nibabel, nipype, |
|
|
18 |
pandas, pydicom, scikit-image, scipy, PyYAML, and tqdm. |
|
|
19 |
|
|
|
20 |
Additional AI features can be unlocked by installing tensorflow and keras. To |
|
|
21 |
enable built-in registration functionality, download [elastix](https://elastix.lumc.nl/download.php). |
|
|
22 |
Details can be found in the [setup documentation](https://dosma.readthedocs.io/en/latest/general/installation.html#setup). |
|
|
23 |
|
|
|
24 |
To install DOSMA, run: |
|
|
25 |
|
|
|
26 |
```bash |
|
|
27 |
pip install dosma |
|
|
28 |
|
|
|
29 |
# To install with AI support |
|
|
30 |
pip install dosma[ai] |
|
|
31 |
``` |
|
|
32 |
|
|
|
33 |
If you would like to contribute to DOSMA, we recommend you clone the repository and |
|
|
34 |
install DOSMA with `pip` in editable mode. |
|
|
35 |
|
|
|
36 |
```bash |
|
|
37 |
git clone git@github.com:ad12/DOSMA.git |
|
|
38 |
cd DOSMA |
|
|
39 |
pip install -e '.[dev,docs]' |
|
|
40 |
make dev |
|
|
41 |
``` |
|
|
42 |
|
|
|
43 |
To run tests, build documentation and contribute, run |
|
|
44 |
```bash |
|
|
45 |
make autoformat test build-docs |
|
|
46 |
``` |
|
|
47 |
|
|
|
48 |
## Features |
|
|
49 |
### Simplified, Efficient I/O |
|
|
50 |
DOSMA provides efficient readers for DICOM and NIfTI formats built on nibabel and pydicom. Multi-slice DICOM data can be loaded in |
|
|
51 |
parallel with multiple workers and structured into the appropriate 3D volume(s). For example, multi-echo and dynamic contrast-enhanced (DCE) MRI scans have multiple volumes acquired at different echo times and trigger times, respectively. These can be loaded into multiple volumes with ease: |
|
|
52 |
|
|
|
53 |
```python |
|
|
54 |
import dosma as dm |
|
|
55 |
|
|
|
56 |
multi_echo_scan = dm.load("/path/to/multi-echo/scan", group_by="EchoNumbers", num_workers=8, verbose=True) |
|
|
57 |
dce_scan = dm.load("/path/to/dce/scan", group_by="TriggerTime") |
|
|
58 |
``` |
|
|
59 |
|
|
|
60 |
### Data-Embedded Medical Images |
|
|
61 |
DOSMA's [MedicalVolume](https://dosma.readthedocs.io/en/latest/generated/dosma.MedicalVolume.html#dosma.MedicalVolume) data structure supports array-like operations (arithmetic, slicing, etc.) on medical images while preserving spatial attributes and accompanying metadata. This structure supports NumPy interoperability, intelligent reformatting, fast low-level computations, and native GPU support. For example, given MedicalVolumes `mvA` and `mvB` we can do the following: |
|
|
62 |
|
|
|
63 |
```python |
|
|
64 |
# Reformat image into Superior->Inferior, Anterior->Posterior, Left->Right directions. |
|
|
65 |
mvA = mvA.reformat(("SI", "AP", "LR")) |
|
|
66 |
|
|
|
67 |
# Get and set metadata |
|
|
68 |
study_description = mvA.get_metadata("StudyDescription") |
|
|
69 |
mvA.set_metadata("StudyDescription", "A sample study") |
|
|
70 |
|
|
|
71 |
# Perform NumPy operations like you would on image data. |
|
|
72 |
rss = np.sqrt(mvA**2 + mvB**2) |
|
|
73 |
|
|
|
74 |
# Move to GPU 0 for CuPy operations |
|
|
75 |
mv_gpu = mvA.to(dosma.Device(0)) |
|
|
76 |
|
|
|
77 |
# Take slices. Metadata will be sliced appropriately. |
|
|
78 |
mv_subvolume = mvA[10:20, 10:20, 4:6] |
|
|
79 |
``` |
|
|
80 |
|
|
|
81 |
### Built-in AI Models |
|
|
82 |
DOSMA is built to be a hub for machine/deep learning models. A complete list of models and corresponding publications can be found [here](https://dosma.readthedocs.io/en/latest/models.html). |
|
|
83 |
We can use one of the knee segmentation models to segment a MedicalVolume `mv` and model |
|
|
84 |
`weights` [downloaded locally](https://dosma.readthedocs.io/en/latest/installation.html#segmentation): |
|
|
85 |
|
|
|
86 |
```python |
|
|
87 |
from dosma.models import IWOAIOAIUnet2DNormalized |
|
|
88 |
|
|
|
89 |
# Reformat such that sagittal plane is last dimension. |
|
|
90 |
mv = mv.reformat(("SI", "AP", "LR")) |
|
|
91 |
|
|
|
92 |
# Do segmentation |
|
|
93 |
model = IWOAIOAIUnet2DNormalized(input_shape=mv.shape[:2] + (1,), weights_path=weights) |
|
|
94 |
masks = model.generate_mask(mv) |
|
|
95 |
``` |
|
|
96 |
|
|
|
97 |
### Parallelizable Operations |
|
|
98 |
DOSMA supports parallelization for compute-heavy operations, like curve fitting and image registration. |
|
|
99 |
Image registration is supported thru the [elastix/transformix](https://elastix.lumc.nl/download.php) libraries. For example we can use multiple workers to register volumes to a target, and use the registered outputs for per-voxel monoexponential fitting: |
|
|
100 |
|
|
|
101 |
```python |
|
|
102 |
# Register images mvA, mvB, mvC to target image mv_tgt in parallel |
|
|
103 |
_, (mvA_reg, mvB_reg, mvC_reg) = dosma.register( |
|
|
104 |
mv_tgt, |
|
|
105 |
moving=[mvA, mvB, mvC], |
|
|
106 |
parameters="/path/to/elastix/registration/file", |
|
|
107 |
num_workers=3, |
|
|
108 |
return_volumes=True, |
|
|
109 |
show_pbar=True, |
|
|
110 |
) |
|
|
111 |
|
|
|
112 |
# Perform monoexponential fitting. |
|
|
113 |
def monoexponential(x, a, b): |
|
|
114 |
return a * np.exp(b*x) |
|
|
115 |
|
|
|
116 |
fitter = dosma.CurveFitter( |
|
|
117 |
monoexponential, |
|
|
118 |
num_workers=4, |
|
|
119 |
p0={"a": 1.0, "b": -1/30}, |
|
|
120 |
) |
|
|
121 |
popt, r2 = fitter.fit(x=[1, 2, 3, 4], [mv_tgt, mvA_reg, mvB_reg, mvC_reg]) |
|
|
122 |
a_fit, b_fit = popt[..., 0], popt[..., 1] |
|
|
123 |
``` |
|
|
124 |
|
|
|
125 |
## Citation |
|
|
126 |
``` |
|
|
127 |
@inproceedings{desai2019dosma, |
|
|
128 |
title={DOSMA: A deep-learning, open-source framework for musculoskeletal MRI analysis}, |
|
|
129 |
author={Desai, Arjun D and Barbieri, Marco and Mazzoli, Valentina and Rubin, Elka and Black, Marianne S and Watkins, Lauren E and Gold, Garry E and Hargreaves, Brian A and Chaudhari, Akshay S}, |
|
|
130 |
booktitle={Proc 27th Annual Meeting ISMRM, Montreal}, |
|
|
131 |
pages={1135}, |
|
|
132 |
year={2019} |
|
|
133 |
} |
|
|
134 |
``` |
|
|
135 |
|
|
|
136 |
In addition to DOSMA, please also consider citing the work that introduced the method used for analysis. |