JacobBumgarner / VesselVio

An open-source application for the analysis and visualization of segmented vasculature datasets
https://jacobbumgarner.github.io/VesselVio/
GNU General Public License v3.0
100 stars 22 forks source link

VesselVio crashing on loading a .tif stack #16

Closed EdwinHernandezG closed 2 years ago

EdwinHernandezG commented 2 years ago

First of all, thanks for this piece of software. Looks amazing.

Describe the bug After starting the analysis in one 881 MB binary image, VesselVio crash

To Reproduce Just start the analysis in a tif image

Screenshots The following error appears in the prompt: File "C:\Users\Linux\Documents\GitHub\VesselVio\Library\QtThreading.py", line 101, in run volume, image_shape = ImProc.load_volume(volume_file) TypeError: cannot unpack non-iterable NoneType object

Desktop (please complete the following information):

Additional context We find no issues with smaller datasets VesselVio_Env.txt

JacobBumgarner commented 2 years ago

Thanks for sharing this bug report - let's see if we can get this figured out!

Would you be willing to share the binary volume that you're trying to analyze with me?

JacobBumgarner commented 2 years ago

I have a hunch that this might be related to #13

EdwinHernandezG commented 2 years ago

Sure, I send you the download link to your email.

JacobBumgarner commented 2 years ago

Ok Edwin, I've figured out what's going on here. This is related to #13, and will be fixed in the next release in the coming days (v1.1.2).

In the meantime - here's what's going on. There's two issues.

  1. The load_volume() function from the image_processing.py module uses ReadImage and GetArrayFromImage from SimpleITK. These functions aren't able to interpret your image correctly. This is because your image has a peculiar image shape of (2160, 1, 2560, 1334). Typically when volumes are 4D, the first or last index indicates the position of the volume in the volume stack. Instead, your volume uses the 2nd index to indicate volume position. I'm quite interested - how was this volume created?

  2. Typically, segmented/binarized volumes use 0 to represent background and 1 to represent the foreground. When I load this volume using FIJI or SimpleITK, this ordering is reversed: 1 represents background and 0 represents foreground. This is problematic. However skimage.io.imread() is able to resolve this, and that's what I'm going to be implementing in v1.1.2, so I'm not too worried about it at the moment. Again - I'm quite curious how this volume was created? Have you also considered saving the volume in a different file format than .tif? Perhaps a .nii NIfTI file instead?

JacobBumgarner commented 2 years ago

Until this release is pushed out in the next day or two, here's what you can do to fix this problem. Very straight forward : )

Because your dataset is quite large (~7.5 GB w/ uint8 data type), I'm going to have you save your file into a NIfTI file format. In addition to the NIfTI file format being a bit more generally compatible and predictable, NIfTI file loading is dramatically faster in VesselVio in comparison other filetypes.

Here's what you should run to convert your file. Just update the filename!

import os
from skimage.io import imread
import numpy as np
import nibabel
from time import perf_counter as pf

t = pf() # Track save speed
# Load the volume using skimage.io.imread()
filename = "FILE_PATH_HERE.tif"
volume = imread(filename).astype(np.uint8)

# Save the volume as NIfTI file using nibabel
save_path = os.path.splitext(filename)[0] + '.nii'

# Transpose the volume so the shape matches the original when saving w/ nibabel
image = nibabel.Nifti1Image(volume.transpose(), np.eye(4))
nibabel.save(image, save_path)

print (f"Save time: {pf() - t:0.2f} seconds.")

And here's your dataset visualized in VesselVio using the newly saved .nii file.

https://user-images.githubusercontent.com/70919881/160904998-c52589f8-0c1e-42b5-9fa1-78fcaacee560.mp4

Here's a quick YouTube demonstration as well! Hernandez Vasculature Demo

Please don't hesitate to reach out if you need more help! You can track the resolution of this issue by following #13 and looking out for the v1.1.2 release.

EdwinHernandezG commented 2 years ago

To add a bit of info about this issue. I saw that it depends on which library you parse the tif file to a NumPy array. Initially, tifffile changes the order of the dimensions, it means from an XYZT, it changes to a ZXYT, and then if you re-write it to a tif file, the dimension orders can be changed.

This happens with tifffile, but it seems that Skimage is not changing the dimension order.