Giter Site home page Giter Site logo

daviddmc / nesvor Goto Github PK

View Code? Open in Web Editor NEW
67.0 3.0 14.0 3.54 MB

NeSVoR is a package for GPU-accelerated slice-to-volume reconstruction.

License: MIT License

Python 81.37% C++ 1.74% Cuda 16.41% Dockerfile 0.48%
3d-reconstruction deep-learning image-reconstruction image-registration medical-imaging implicit-neural-representation neural-network transformers mri pytorch

nesvor's Introduction

NeSVoR: Neural Slice-to-Volume Reconstruction

Documentation Status

NeSVoR is a package for GPU-accelerated slice-to-volume reconstruction (both rigid and deformable).

This package is the accumulation of the following works:

[1] SVoRT: Iterative Transformer for Slice-to-Volume Registration in Fetal Brain MRI (Springer | Arxiv)

[2] NeSVoR: Implicit Neural Representation for Slice-to-Volume Reconstruction in MRI (IEEE | TechRxiv)

Overview

Methods

NeSVoR is a deep learning package for solving slice-to-volume reconstruction problems (i.e., reconstructing a 3D isotropic high-resolution volume from a set of motion-corrupted low-resolution slices) with application to fetal/neonatal MRI, which provides

Figure 1. SVoRT: an iterative Transformer for slice-to-volume registration. (a) The k-th iteration of SVoRT. (b) The detailed network architecture of the SVT module.

Figure 2. NeSVoR: A) The forward imaging model in NeSVoR. B) The architecture of the implicit neural network in NeSVoR.

Pipeline

To make our reconstruction tools more handy, we incorporate several preprocessing and downstream analysis tools in this package. The next figure shows our overall reconstruction pipeline.

Figure 3. The reconstruction pipeline.

Documentation

The full documentation is available at Read the Docs.

Installation

Docker Image

We recommend to use our docker image to run nesvor.

Install Docker and NVIDIA Container Toolkit

You may follow this guide to install Docker and NVIDIA Container Toolkit

Download NeSVoR Image

docker pull junshenxu/nesvor

Note: our latest image was built with CUDA 11.7.

Run NeSVoR with Docker

You may run a container in an interactive way.

docker run -it --gpus all --ipc=host junshenxu/nesvor
nesvor -h

You may also run the nesvor command directly as follows.

docker run --rm --gpus all --ipc=host \
    -v <path-to-inputs>:/incoming:ro -v <path-to-outputs>:/outgoing:rw \
    junshenxu/nesvor \
    nesvor reconstruct \
    --input-stacks /incoming/stack-1.nii.gz ... /incoming/stack-N.nii.gz \
    --thicknesses <thick-1> ... <thick-N> \
    --output-volume /outgoing/volume.nii.gz

From Source

Check out our documentation if you want to install NeSVoR from source.

Quick Start

Fetal Brain Reconstruction

This example reconstruct a 3D fetal brain from mutiple stacks of 2D images in the following steps:

  1. Segment fetal brain from each image using a CNN (--segmentation).
  2. Correct bias field in each stack using the N4 algorithm (--bias-field-correction).
  3. Register slices using SVoRT (--registration svort).
  4. Reconstruct a 3D volume using NeSVoR.
nesvor reconstruct \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --thicknesses <thick-1> ... <thick-N> \
    --output-volume volume.nii.gz \
    --output-resolution 0.8 \
    --registration svort \
    --segmentation \
    --bias-field-correction

Neonatal Brain Reconstruction

This example reconstruct a 3D neonatal brain from mutiple stacks of 2D images in the following steps:

  1. Removal background (air) with Otsu thresholding (--otsu-thresholding).
  2. Correct bias field in each stack using the N4 algorithm (--bias-field-correction).
  3. Register slices using SVoRT (--registration svort).
  4. Reconstruct a 3D volume using NeSVoR.
nesvor reconstruct \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --thicknesses <thick-1> ... <thick-N> \
    --output-volume volume.nii.gz \
    --output-resolution 0.8 \
    --registration svort \
    --otsu-thresholding \
    --bias-field-correction

Fetal Body/Uterus Reconstruction

This is an example for deformable NeSVoR which consists of the following steps:

  1. Create an ROI based on the intersection of all input stacks (--stacks-intersection).
  2. Perform stack-to-stack registration (--registration stack).
  3. Reconstruct a 3D volume using Deformable NeSVoR (--deformable).
nesvor reconstruct \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --thicknesses <thick-1> ... <thick-N> \
    --output-volume volume.nii.gz \
    --output-resolution 1.0 \
    --stacks-intersection \
    --registration stack \
    --deformable \
    --weight-transformation 1 \
    --weight-deform 0.1 \
    --weight-image 0.1 \
    --single-precision \
    --log2-hashmap-size 22 \
    --batch-size 8192

Usage

This section provides the basic usage of the commands in NeSVoR. Please refer to our document for details. NeSVoR currently supports the following commands:

  • nesvor reconstruct: reconstruct a 3D volume (i.e., train a NeSVoR model) from either multiple stacks of slices (NIfTI) or a set of motion-corrected slices (the output of register). It can also perform multiple preprocessing steps, including brain segmentation, bias field correction, and registration.
  • nesvor register: register stacks of slices using a pretrained SVoRT model or stack-to-stack registration.
  • svr: a classical slice-to-volume registration/reconstruciton method.
  • nesvor sample-volume: sample a volume from a trained NeSVoR model.
  • nesvor sample-slices: simulate slices from a trained NeSVoR model.
  • nesvor segment-stack: 2D fetal brain segmentation/masking in input stacks.
  • nesvor correct-bias-field: bias field correction using the N4 algorihtm.
  • nesvor assess: quality and motion assessment of input stacks.

run nesvor <command> -h for a full list of parameters of a command.

Reconstruction

Reconstruct from Mutiple Stacks of Slices

The reconstruct command can be used to reconstruct a 3D volume from N stacks of 2D slices (in NIfTI format, i.e. .nii or .nii.gz). A basic usage of reconstruct is as follows, where mask-i.nii.gz is the ROI mask of the i-th input stack.

nesvor reconstruct \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --stack-masks mask-1.nii.gz ... mask-N.nii.gz \
    --output-volume volume.nii.gz

A more elaborate example could be

nesvor reconstruct \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --stack-masks mask-1.nii.gz ... mask-N.nii.gz \
    --thicknesses <thick-1> ... <thick-N> \
    --output-volume volume.nii.gz \
    --output-resolution 0.8 \
    --output-model model.pt \
    --weight-image 1.0 \
    --image-regularization edge \
    --delta 0.2 \
    --n-iter 5000 \
    --level-scale 1.38 \
    --coarsest-resolution 16.0 \
    --finest-resolution 0.5 \
    --n-levels-bias 0 \
    --n-samples 128

Run nesvor reconstruct --h to see the meaning of each parameter.

Given multiple stacks at inputs, reconstruct first corrects the motion in the input stacks using SVoRT (the same as what register did), and then trains a NeSVoR model that implicitly represent the underlying 3D volume, from which a discretized volume (i.e., a 3D tensor) can be sampled.

Reconstruct from Motion-Corrected Slices

reconstruct can also take a folder of motion-corrected slices as inputs.

nesvor reconstruct \
    --input-slices <path-to-slices-folder> \
    --output-volume volume.nii.gz

This enables the separation of registration and reconstruction. That is, you may first run register to perform motion correction, and then use reconstruct to reconstruct a volume from a set of motion-corrected slices.

Deformable NeSVoR

NeSVoR can now reconstruct data with deformable (non-rigid) motion! To enable deformable motion, use the flag --deformable.

nesvor reconstruct \
    --deformable \
    ......

This feature is still experimental.

Registration (Motion Correction)

register takes mutiple stacks of slices as inputs, performs motion correction, and then saves the motion-corrected slices to a folder.

nesvor register \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --stack-masks mask-1.nii.gz ... mask-N.nii.gz \
    --registration <method> \
    --output-slices <path-to-save-output-slices>

run nesvor register -h to see a full list of supported registration methods.

SVR

svr implements a classical slice-to-volume registration/reconstruction method combined with SVoRT motion correction. The usage of svr is similar to reconstruct. svr currently only supports rigid motion.

Sampling

Sample Volume

Upon training a NeSVoR model with the reconstruct command, you can sample a volume at arbitrary resolutions with the sample-volume command.

nesvor sample-volume \
    --output-volume volume.nii.gz \
    --input-model model.pt \
    --output-resolution 0.5

Sample Slices

You may sample slices from the model using the sample-slices command. For each slice in <path-to-slices-folder>, the command simulates a slice from the NeSVoR model at the corresponding slice location.

nesvor sample-slices \
    --input-slices <path-to-slices-folder> \
    --input-model model.pt \
    --simulated-slices <path-to-save-simulated-slices>

For example, after running reconstruct, you can use sample-slices to simulate slices at the motion-corrected locations and evaluate the reconstruction results by comparing the input slices and the simulated slices.

Preprocessing

Brain Masking

We integrate a deep learning based fetal brain segmentation model (MONAIfbs) into our pipeline to extract the fetal brain ROI from each input image. Check out their repo and paper for details. The segment-stack command generates brain mask for each input stack as follows.

nesvor segment-stack \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --output-stack-masks mask-1.nii.gz ... mask-N.nii.gz \

You may also perform brain segmentation in the reconstruct command by setting --segmentation.

Bias Field Correction

We also provide a wrapper of the N4 algorithm in SimpleITK for bias field correction. The correct-bias-field command correct the bias field in each input stack and output the corrected stacks.

nesvor correct-bias-field \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --stack-masks mask-1.nii.gz ... mask-N.nii.gz \
    --output-corrected-stacks corrected-stack-1.nii.gz ... corrected-stack-N.nii.gz

You may perform bias field correction in the reconstruct command by setting --bias-field-correction

Stack Quality Assessment

The assess command evalutes the image quality/motion of input stacks. This information can be used to find a template stack with the best quality or filter out low-quality data. An example is as follows.

nesvor assess \
    --input-stacks stack-1.nii.gz ... stack-N.nii.gz \
    --stack-masks mask-1.nii.gz ... mask-N.nii.gz \
    --metric <metric> \
    --output-json result.json 

run nesvor assess -h to see a full list of supported metrics.

Cite Our Work

SVoRT

@inproceedings{xu2022svort,
  title={SVoRT: Iterative Transformer for Slice-to-Volume Registration in Fetal Brain MRI},
  author={Xu, Junshen and Moyer, Daniel and Grant, P Ellen and Golland, Polina and Iglesias, Juan Eugenio and Adalsteinsson, Elfar},
  booktitle={International Conference on Medical Image Computing and Computer-Assisted Intervention},
  pages={3--13},
  year={2022},
  organization={Springer}
}

NeSVoR

@article{10015091,
  author={Xu, Junshen and Moyer, Daniel and Gagoski, Borjan and Iglesias, Juan Eugenio and Ellen Grant, P. and Golland, Polina and Adalsteinsson, Elfar},
  journal={IEEE Transactions on Medical Imaging}, 
  title={NeSVoR: Implicit Neural Representation for Slice-to-Volume Reconstruction in MRI}, 
  year={2023},
  volume={},
  number={},
  pages={1-1},
  doi={10.1109/TMI.2023.3236216}
}

Fetal IQA

@inproceedings{xu2020semi,
  title={Semi-supervised learning for fetal brain MRI quality assessment with ROI consistency},
  author={Xu, Junshen and Lala, Sayeri and Gagoski, Borjan and Abaci Turk, Esra and Grant, P Ellen and Golland, Polina and Adalsteinsson, Elfar},
  booktitle={International Conference on Medical Image Computing and Computer-Assisted Intervention},
  pages={386--395},
  year={2020},
  organization={Springer}
}

Resources

This project has been greatly inspired by the following list of fantastic works.

nesvor's People

Contributors

daviddmc avatar jennydaman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nesvor's Issues

"SVD did not converge" error when using nesvor segment-stack

I have an issue when using nesvor segment-stack. It fails, giving a SVD error when trying to save the . I have tried with different images, so it is not related to the input. I am using the docker image, version 0.5.0. I have also tried it in a HPC environment (converting the image to a singularity container), getting the same error.

This is the full error stack:

WARNING:root:Fail to load tinycudann. Will use pytorch implementation.
/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py:1088: RuntimeWarning: invalid value encountered in divide
  R = RZS / zooms
/usr/local/lib/python3.10/dist-packages/numpy/linalg/linalg.py:2139: RuntimeWarning: invalid value encountered in det
  r = _umath_linalg.det(a, signature=signature)
ERROR:root:Unhandled exception:
Traceback (most recent call last):
  File "/usr/local/bin/nesvor", line 33, in <module>
    sys.exit(load_entry_point('nesvor', 'console_scripts', 'nesvor')())
  File "/usr/local/NeSVoR/nesvor/cli/main.py", line 23, in main
    run(args)
  File "/usr/local/NeSVoR/nesvor/cli/main.py", line 48, in run
    getattr(commands, command_class)(args).main()
  File "/usr/local/NeSVoR/nesvor/cli/commands.py", line 75, in main
    self.exec()
  File "/usr/local/NeSVoR/nesvor/cli/commands.py", line 257, in exec
    outputs(
  File "/usr/local/NeSVoR/nesvor/cli/io.py", line 93, in outputs
    m.save(p)
  File "/usr/local/NeSVoR/nesvor/image/image.py", line 187, in save
    save_nii_volume(path, output_volume, affine)
  File "/usr/local/NeSVoR/nesvor/image/image_utils.py", line 110, in save_nii_volume
    img = nib.nifti1.Nifti1Image(volume, affine)
  File "/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py", line 1848, in __init__
    super().__init__(dataobj, affine, header, extra, file_map, dtype)
  File "/usr/local/lib/python3.10/dist-packages/nibabel/analyze.py", line 909, in __init__
    super().__init__(dataobj, affine, header, extra, file_map)
  File "/usr/local/lib/python3.10/dist-packages/nibabel/spatialimages.py", line 531, in __init__
    self.update_header()
  File "/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py", line 2273, in update_header
    super().update_header()
  File "/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py", line 1884, in update_header
    super().update_header()
  File "/usr/local/lib/python3.10/dist-packages/nibabel/spatialimages.py", line 565, in update_header
    self._affine2header()
  File "/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py", line 1894, in _affine2header
    hdr.set_qform(self._affine, code='unknown')
  File "/usr/local/lib/python3.10/dist-packages/nibabel/nifti1.py", line 1100, in set_qform
    P, S, Qs = npl.svd(R)
  File "<__array_function__ internals>", line 200, in svd
  File "/usr/local/lib/python3.10/dist-packages/numpy/linalg/linalg.py", line 1642, in svd
    u, s, vh = gufunc(a, signature=signature, extobj=extobj)
  File "/usr/local/lib/python3.10/dist-packages/numpy/linalg/linalg.py", line 98, in _raise_linalgerror_svd_nonconvergence
    raise LinAlgError("SVD did not converge")
numpy.linalg.LinAlgError: SVD did not converge

Note that the rest of the tool works great: when using Monaifbs separately and providing NeSVoR with the masks, everything works smoothly. So a workaround right now is to compute the masks outside of the docker.

It is not a memory issue, and I have manually checked the images and they have no issues (Monaifbs works well with the same images when used in my own installation).

Three facets of data

Dear @daviddmc,

I have information on three facets of a site with specific location coordinates. I was wondering, can we try the program directly with data from other organs.

Thanks!

Can't get the full volume using actual thickness.

Hi NeSVoR team,

Thank you so much for making the code public! I tried to reproduce your results using the CRL atlas dataset. But found that I need to enter a larger parameter than the actual thickness to get the full volume.

I used the following code to get to the thickness of the data as [0.8,0.8,0.8].
img = nib.load(nii_file)
#turn into numpy
data = img.get_fdata()
affine = img.affine
resolution = affine.diagonal()[:3]

I used the following command for SVR:

nesvor reconstruct
--input-stacks .../STA33.nii.gz .../STA33.nii.gz .../STA33.nii.gz
--thicknesses 0.8 0.8 0.8
--output-volume .../3316.nii.gz
--bias-field-correction
--output-resolution 0.8

However, I got an incomplete volume:

image

If I change the command to
--thicknesses 1.4 1.4 1.4
I can then get the full volume:

image

nesvor segment-stack issue when using it standalone

Using "nesvor segment-stack" standalone command (https://nesvor.readthedocs.io/en/latest/commands/segment-stack.html) generates masks with different sform/qform and origin, which, in turn, makes the "nesvor reconstruct" fail with the error:

	2024-03-13 15:55:26 [INFO] Data loading starts ...
	2024-03-13 15:55:26 [INFO] loading stacks
	2024-03-13 15:55:26 [ERROR] Unhandled exception:
	Traceback (most recent call last):
	  File "/usr/local/bin/nesvor", line 33, in <module>
	    sys.exit(load_entry_point('nesvor', 'console_scripts', 'nesvor')())
	  File "/usr/local/NeSVoR/nesvor/cli/main.py", line 23, in main
	    run(args)
	  File "/usr/local/NeSVoR/nesvor/cli/main.py", line 48, in run
	    getattr(commands, command_class)(args).main()
	  File "/usr/local/NeSVoR/nesvor/cli/commands.py", line 75, in main
	    self.exec()
	  File "/usr/local/NeSVoR/nesvor/cli/commands.py", line 160, in exec
	    input_dict = self.preprocess()
	  File "/usr/local/NeSVoR/nesvor/cli/commands.py", line 132, in preprocess
	    input_dict, self.args = inputs(self.args)
	  File "/usr/local/NeSVoR/nesvor/cli/io.py", line 24, in inputs
	    stack = load_stack(
	  File "/usr/local/NeSVoR/nesvor/image/image.py", line 651, in load_stack
	    raise Exception(
	Exception: Error: the sizes/resolutions/affine transformations of the input stack and stack mask do not match!

Note that this does not happen when using just "nesvor reconstruct" without the previously computed masks. The error only happens when: 1) using nesvor segment-stack to generate masks and 2) using those masks as input to nesvor reconstruct.

I have replicated this with various stacks, but unsure if this is a problem in the qform/sform configuration of this specific data or a general thing. This is the header information and the origin of the original stack:

image
And this is the one from the corresponding mask generated by nesvor segment-stack:

image
This is bothersome if we want to use the various functions included in the library to run every step at a time.

A quick fix that work for me is just to copy the header from the mask to the original stack, and invert the x axis. This seems to make everything work, but it is dirty.

I believe the problem comes from the transformations on the affine matrix that nesvor performs when loading/saving a nifti file, so if you can take a look at it, that would be great. Thanks!

Wrong checkpoint for DynUNet

I ran nesvor segment-stack --input-stacks volumes/case2_day1_stack.nii.gz --output-stack-masks volumes/case2_day1_mask.nii.gz but the downloaded checkpoint (nesvor/preprocessing/masking/brain_segmentation.py) is completely wrong and all keys are unexpected.

image

ROI in the data is too large for SVoRT

Dear @daviddmc,

Thanks for making this code public!
I am currently trying to reconstruct an adult brain from HCP using nesvor. However, I get the warning "[WARNING] ROI in the data is too large for SVoRT" when I want to pre-register the slices via SVoRT. The model then skips SVoRT and resorts to regular stack registration. I'm using 3 Stacks with spacing[1.25, 1.25, 3.3], resulting in a rough dimension of [170, 150, 55]. Would you happen to know how to handle this problem?

Thanks!

--device option not passed down to tiny-cuda-nn

nesvor has the option --device to specify which GPU is to be used by nesvor. However, the GPU selection is not passed down to the tiny-cuda-nn functions, which will always attempt to use GPU#0.

We have a machine with 2 GPUs. GPU#0 is currently being used, so we try to run nesvor --device 1. However, the following exception occurs:

Traceback (most recent call last):
  File "/opt/conda/bin/nesvor", line 8, in <module>
    sys.exit(main())
  File "/opt/conda/lib/python3.10/site-packages/nesvor/cli/main.py", line 23, in main
    run(args)
  File "/opt/conda/lib/python3.10/site-packages/nesvor/cli/main.py", line 48, in run
    getattr(commands, command_class)(args).main()
  File "/opt/conda/lib/python3.10/site-packages/nesvor/cli/commands.py", line 75, in main
    self.exec()
  File "/opt/conda/lib/python3.10/site-packages/nesvor/cli/commands.py", line 162, in exec
    model, output_slices, mask = train(input_dict["input_slices"], self.args)
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/train.py", line 36, in train
    model = NeSVoR(
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/models.py", line 309, in __init__
    self.build_network(bounding_box)
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/models.py", line 350, in build_network
    self.inr = INR(bounding_box, self.args, self.spatial_scaling)
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/models.py", line 147, in __init__
    self.encoding = build_encoding(
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/models.py", line 48, in build_encoding
    raise e
  File "/opt/conda/lib/python3.10/site-packages/nesvor/inr/models.py", line 39, in build_encoding
    encoding = tcnn.Encoding(
  File "/opt/conda/lib/python3.10/site-packages/tinycudann/modules.py", line 315, in __init__
    super(Encoding, self).__init__(seed=seed)
  File "/opt/conda/lib/python3.10/site-packages/tinycudann/modules.py", line 161, in __init__
    initial_params = self.native_tcnn_module.initial_params(seed)
RuntimeError: CUDA error: out of memory
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.

I used nvtop to monitor GPU usage during the runtime of NeSVoR.

Screenshot 2023-06-29 at 14 36 31

  • nesvor started around -110s
  • nesvor crashed around -60s
  • we can observe a bump in GPU0 memory consumption right before nesvor crashes

TypeError: 'ABCMeta' object is not subscriptable

TypeError: 'ABCMeta' object is not subscriptable

torch 1.10.0+cu113
cuda 11.2
python 3.8.10

nesvor reconstruct --input-slices ../nesvor/casenii
--output-slices ../nesvor/outnii
--output-resolution 0.8
--registration svort
--segmentation
--bias-field-correction

seems like a ez question..

Cannot reproduce results on FeTA using your slicing strategy.

Hi,
I tried using nesvor to reconstruct volume with stacks of slices sampled from the FeTA dataset. Stack assessment gave high ncc ( > 0.92).
I enabled registration and bias field correction and sampled 3 orthogonal stacks with gaps over the whole volume using modified code from you slice_acquistion tests, but the results are terrible. Even worse, if I enable segmentation the whole stack is masked out.
It's hard to infer how else stacks could be extracted from the paper. Here's my code and results:

nesvor reconstruct \
--input-stacks stacks/feta_stack1_gap=3.nii.gz stacks/feta_stack2_gap=3.nii.gz stacks/feta_stack3_gap=3.nii.gz \
--output-volume volumes/feta_rec_nesvor_gap=3.nii.gz \
--bias-field-correction \
--registration svort
 def get_cg_recon_test_data(self, angles, volume: torch.Tensor=None, return_stack_as_list=True):
        

        vs = 240 if volume is None else max(volume.shape) # z axis

        gap = s_thick = 3#not the slice thickness
        res = 1
        res_s = 1.5
        n_slice = int((np.sqrt(3) * vs) / gap) + 4
        ss = int((np.sqrt(3) * vs) / res_s) + 4
        
        if volume is None:
            print(f"Creating a Phantom of {(vs, vs, vs)} with resolution {res}")
            if self.phantom == "default":
                volume = phantom3d(n=vs, phantom="shepp_logan")
            else:
                volume = shepp_logan((vs, vs, vs))
        else:
            print('Using provided volume')
            
        volume = torch.tensor(volume, dtype=torch.float32).cuda().contiguous()
        volume = pad_to_length(volume, vs)
        volume = volume.unsqueeze(0).unsqueeze(0) #preprocess for svort
        
        psf = get_PSF(res_ratio=(res_s / res, res_s / res, s_thick / res)).cuda()

        stacks = []
        transforms = []
        
        #get slices for each triplet of angles
        for i in range(len(angles)):
            angle = (
                torch.tensor([angles[i]], dtype=torch.float32)
                .cuda()
                .expand(n_slice, -1)
            )
            tz = (
                torch.arange(0, n_slice, dtype=torch.float32).cuda()
                - (n_slice - 1) / 2.0
            ) * gap
            tx = ty = torch.ones_like(tz) * 0.5 #pick middle coordinates? but why 0.5 not 0.5 * dim
            t = torch.stack((tx, ty, tz), -1)
            transform = RigidTransform(torch.cat((angle, t), -1), trans_first=True)
            # sample slices
            mat = mat_update_resolution(transform.matrix(), 1, res)
            slices = slice_acquisition(
                mat, volume, None, None, psf, (ss, ss), res_s / res, False, False
            )
            if return_stack_as_list:
                slices = slices.squeeze()
            stacks.append(slices) #shape: (h, 1, w, l)
            transforms.append(transform)

        params = {
            "psf": psf,
            "slice_shape": (ss, ss),
            "res_s": res_s,
            "res_r": res,
            "interp_psf": False,
            "volume_shape": (vs, vs, vs),
        }
        
        #save stacks to test Nesvor
        if len(stacks) == 3:
            self._save_stacks(stacks, gap=gap)
image

Understanding n-level-bias parameter defaults value

Hello,

thanks for developing and making available nesvor. I had a question regarding the n-level-bias parameter of the reconstruct command

  • what was the exact meaning of the n-level-bias ?
  • its default value is set to 0: does this mean bias field is not corrected by default ? Or does it mean only level 0 of the hasgrid is used to estimate the bias ?

image

Best,
Alex

What parameters I should set to improve the separation of the fetal brain regions and eliminate the unwanted areas?

Thank you for your fantastic work! I've successfully run your open-source code for 3D reconstruction. However, after the reconstruction of the fetal brain, there are always some regions that are not of interest, while others are well-separated. Currently, I'm using the following parameters with nesvor reconstruct:
nesvor reconstruct
--input-stacks stack-1.nii.gz ... stack-N.nii.gz
--thicknesses ...
--output-volume volume.nii.gz
--output-resolution 0.8
--segmentation
--bias-field-correction
Could you please advise on what parameters I should set to improve the separation of the fetal brain regions and eliminate the unwanted areas?
image
image

Visualizing learnt hash grid at different level

Dear @daviddmc,
I was trying to reproduce the visualization you made Fig.13 in the nesvor paper, i.e. the different levels of the learnt hashgrid. However I have not managed so far to obtain similar visualization. Is there some piece of code included in nesvor I could use to do that. If not, may you indicate me how to proceed ? So far I obtained patterns that are replicated, i.e. one brain then half a brain superimposed in the same figure, which seems weird.
Best,
Alex

Wrong Phantom in tests/slice_acquisition

Hi,
I tested both versions of Phantom in the code "modified-shepp-logan" and "shepp_logan" generated by phantom3d.py, and the outputs are completely off. Please consider replacing it with the correct Phantom.
image

Computation of PSNR score : Low values

Dear @daviddmc,
Thank you for this open source code!
I try to reproduce your experiments by computing the PSNR score between the reconstructed volume from NeSVoR and the original high resolution data that I sub-sampled.
I get surprisingly low PSNR value, that seem to be due to a shift in the intensity distributions between the two images.
By searching in the code, I did identify the line 525 in svort/inference.py , (function run_svort) which looks like a normalization of the intensities and could thus induce the shift in the distribution.
Could you please explain me why the normalization at line 525 is needed, and how you did handle the problem of shift in the distribution for computing the PSNR in your paper?
Thanks very much for your help
Best,
Steven

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.