Skip to content

Added the feature to read DICOM images into a 4D Nifti image #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4bc40f2
Added the feature to read DICOM images into a 4D Nifti image utilizin…
jph6366 Apr 20, 2025
1e060cd
Update README.md
jph6366 Apr 21, 2025
a4ce220
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 21, 2025
e331dfc
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 Apr 21, 2025
1247c2c
Update README.md
jph6366 Apr 21, 2025
a5f63e6
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 21, 2025
0e496b6
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 22, 2025
ae56831
Update README.md
jph6366 Apr 22, 2025
317d72d
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 22, 2025
783e2f3
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 Apr 22, 2025
5347a31
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 22, 2025
22df73a
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 22, 2025
d18c2e6
Update README.md
jph6366 Apr 23, 2025
3dbb64c
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 25, 2025
606b667
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 Apr 25, 2025
9a17fb1
Update README.md
jph6366 Apr 25, 2025
614c8f8
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 28, 2025
dda0e88
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 Apr 28, 2025
ac752cb
Update pyproject.toml
jph6366 Apr 28, 2025
92abf87
Update generate_signal_docker_test.py
jph6366 Apr 28, 2025
201f495
[Feature] <Allow reading of DICOM images> #68
jph6366 Apr 30, 2025
d32460b
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 Apr 30, 2025
9cd090f
Update pyproject.toml
jph6366 Apr 30, 2025
30a0603
Update README.md
jph6366 May 9, 2025
64dc1bc
updated job to be fixed or otherwise log error to help fix
jph6366 May 9, 2025
682d655
Merge branch 'dicom2niix' of https://github.com/jph6366/TF2.4_IVIM-MR…
jph6366 May 9, 2025
814cdc9
#68
jph6366 May 24, 2025
015f7dc
tested locally successfully
jph6366 May 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ RUN pip install --no-cache-dir -r requirements.txt

COPY .. .

ENTRYPOINT ["python3", "-m", "WrapImage.nifti_wrapper"]
ENTRYPOINT ["python3", "-m", "WrapImage.nifti_wrapper"]
71 changes: 71 additions & 0 deletions Docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ This project is designed to run the `nifti_wrapper` script using a Docker contai
├── Docker/
│ └── Dockerfile
│ └── dicom2nifti/
│ └── Dockerfile
├── WrapImage/
│ └── nifti_wrapper.py
│ └── dicom2niix_wrapper.py
└── requirements.txt
```
Expand Down Expand Up @@ -44,6 +47,10 @@ Before running the Docker container, here are the available options for the `Doc
```sh
sudo docker build -t tf2.4_ivim-mri_codecollection -f Docker/Dockerfile .
```
OR (If you need to convert your data from DICOM TO NIfTI images)
```sh
sudo docker build -t tf2.4_ivim-mri_codecollection -f Docker/dicom2nifti/Dockerfile .
```

## Running the Docker Container

Expand All @@ -58,4 +65,68 @@ Before running the Docker container, here are the available options for the `Doc

Replace `brain.nii.gz`, `brain.bvec`, and `brain.bval` with the actual file names you want to use.

## Running the Docker container for reading in DICOM Images

- You can run the dicom2nifti Docker container using the `docker run` command. This command runs the Docker image with the specified input files:

```sh
sudo docker run -it --rm --name TF2.4_IVIM-MRI_CodeCollection \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/src/app \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/app/output \
tf2.4_ivim-mri_codecollection \
/usr/src/app/dicom_folder
```

- You can run the dicom2niix_wrapper.py script either directly or from inside a Docker container (non-interactive only). Here are the available options:

## Options
Before running the Docker container, here are the available options for the `Docker image` script:

- `input`: Path to the input DICOM directory. Some scanners store images in nested subfolders, so a single session might be stored in the folders "/usr/subj22/111", "/usr/subj22/112" and "/usr/subj22/123". In this case you should simply provide the parent directly ("/usr/subj22") and dcm2niix will recursively search the sub directories and organize all your images for you.
- `output`: Path to the output directory for the converted NIfTI files and sidecar BIDS JSON.
- ` -m, --merge-2d`: Merge 2D slices into a 3D or 4D NIfTI image regardless of study time, echo, coil, orientation, etc. Depending on your vendor, you may want to keep images segmented based on these attributes or merge/combine them.
- ` -s, --single-file`: Use single file mode (convert only one series per folder). For example, if the input path "~/dir/001.dcm" will only convert the file 001.dcm.
- ` -pu, --prompt-user`: Run the tool in interactive mode. This launches a terminal-based wizard where you can select DICOM folders and configure conversion interactively.



### Example usage

```sh
sudo docker run -it --rm --name TF2.4_IVIM-MRI_CodeCollection \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/src/app \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/app/output \
tf2.4_ivim-mri_codecollection \
/usr/src/app/dicom_folder -o /usr/app/output
```

```sh
sudo docker run -it --rm --name TF2.4_IVIM-MRI_CodeCollection \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/src/app \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/app/output \
tf2.4_ivim-mri_codecollection \
/usr/src/app/dicom_folder -o /usr/app/output -m
```

```sh
sudo docker run -it --rm --name TF2.4_IVIM-MRI_CodeCollection \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/src/app \
-v ~/TF2.4_IVIM-MRI_CodeCollection:/usr/app/output \
tf2.4_ivim-mri_codecollection \
/usr/src/app/dicom_file -o /usr/app/output -s
```

[Note that NIfTI and DICOM encode space differently](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Spatial_Coordinates)

![image](https://www.nitrc.org/plugins/mwiki/images/thumb/8/8e/Dcm2nii%3AMni_v_dicom.jpg/300px-Dcm2nii%3AMni_v_dicom.jpg)

##### The goal of dcm2niix is to create FSL format bvec/bval files for processing. A crucial concern is ensuring that the gradient directions are reported in the frame of reference expected by the software you use to fit your tractography. [dicom2niix should generate a ".bvec" file that reports the tensors as expected](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Diffusion_Tensor_Imaging) by FSL's dtifit, where vectors are reported relative to image frame of reference (rather than relative to the scanner bore)

#### It is strongly recommend that users check validate the b-vector directions for their hardware and sequence as [described in a dedicated document](https://www.nitrc.org/docman/?group_id=880)

![DICOM2NiFTI](dicom2nifti/DICOM2NiFTI.png)

#### Output of NIFTI and DICOM objects generated from signal generation test

- NIfTI follows the Talairach/MNI coordinate system where the X value increases as we move toward the participant's right, the Y increases as we move anteriorly. In contrast, for bipeds DICOM specifies the the X increases as we more toward the participant's left, while the Y increases as we move posteriorly. Both agree that the Z coordinate increases as we move superiorly.
---
Binary file added Docker/dicom2nifti/DICOM2NiFTI.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions Docker/dicom2nifti/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
FROM debian:stable-slim AS build

ARG DCM2NIIX_VERSION=v1.0.20241211

RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
libssl-dev \
wget \
pigz \
ca-certificates \
&& update-ca-certificates \
&& wget https://github.com/rordenlab/dcm2niix/archive/refs/tags/${DCM2NIIX_VERSION}.tar.gz -O /tmp/dcm2niix.tar.gz \
&& mkdir -p /tmp/dcm2niix && tar -xzf /tmp/dcm2niix.tar.gz -C /tmp/dcm2niix --strip-components=1 \
&& mkdir /tmp/dcm2niix/build && cd /tmp/dcm2niix/build \
&& cmake -DBATCH_VERSION=ON -DZLIB_IMPLEMENTATION=Cloudflare -DUSE_JPEGLS=ON -DUSE_OPENJPEG=ON .. \
&& make && make install \
&& rm -rf /tmp/dcm2niix* \
&& apt-get remove -y wget git cmake \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

FROM python:3.11-slim

WORKDIR /usr/src/app

RUN apt-get update && apt-get install -y --no-install-recommends \
pigz \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY --from=build /usr/local/bin/dcm2niix /usr/local/bin/dcm2niix

COPY ../../requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY ../.. .

ENTRYPOINT ["python3", "-m", "WrapImage.dicom2niix_wrapper"]
22 changes: 21 additions & 1 deletion Docker/generate_signal_docker_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from pathlib import Path
import numpy as np
import nibabel as nib
from utilities.data_simulation.GenerateData import GenerateData
from WrapImage.nifti_wrapper import save_nifti_file

from WrapImage.dicom2niix_wrapper import save_dicom_objects

def save_bval_bvec(filename, values):
if filename.endswith('.bval'):
Expand Down Expand Up @@ -34,9 +35,28 @@ def save_bval_bvec(filename, values):
# Generate IVIM signal
signals = gd.ivim_signal(D_in, Dp_in, f_in, S0, bvals_reshaped)


# Generate 4D signal by stacking volumes for each bval
signals_4d = np.stack([
gd.ivim_signal(D_in, Dp_in, f_in, S0, np.full(shape, bval))
for bval in bvals
], axis=-1)

# Save the generated image as a NIfTI file
save_nifti_file(signals, "ivim_simulation.nii.gz")
# Save the bval in a file
save_bval_bvec("ivim_simulation.bval", [0, 50, 100, 500, 1000])
# Save the bvec value
save_bval_bvec("ivim_simulation.bvec", [[1, 0, 0], [0, 1, 0], [0, 0, 1]])

bvecs = [[1, 0, 0]] * len(bvals) # Assuming all x-direction

save_dicom_objects(
volume_4d=signals_4d,
bvals=bvals.tolist(),
bvecs=bvecs,
out_dir=Path("ivim_simulation_dicom"),
f_vals=f_in,
D_vals=D_in,
Dp_vals=Dp_in
)
Loading