Skip to content
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

Marching Cubes: invalid triangle #12

Closed
abhishekpatil32 opened this issue Sep 3, 2024 · 13 comments
Closed

Marching Cubes: invalid triangle #12

abhishekpatil32 opened this issue Sep 3, 2024 · 13 comments

Comments

@abhishekpatil32
Copy link

Hello experts,

This is a very cool tool to convert the nifti (.nii) files to mesh (.obj).

But I am encountering an error like below:

load from disk: 154 ms
pre-smooth: 1604 ms
intensity range 0..1, isolevel 0.25098
voxel clustering (largest cluster, bubbles): 2578 ms
Marching Cubes: invalid triangle 15733
-0.250980 -0.250980 -0.250980 -0.250980 -0.250980 -nan 131071.750000 21941997487060864704716311175242973184.000000

When I try to run the file using the online web server it works fine..
But with the code there is an error. What am I doing wrong??
Can anyone help me resolve this??

@neurolabusc
Copy link
Owner

I am unable to replicate. Perhaps you can share a dataset and specific method to troubleshoot. Here is a recipe that worked for me using the mni152.nii.gz image from NiiVue:

$ git clone [email protected]:neurolabusc/nii2mesh.git
$ cd nii2mesh/src 
$ make
$ ./nii2mesh -v
nii2mesh v1.0.20211220  Clang14.0.3  ARM
...
$ ./nii2mesh ../../mni152.nii.gz -r 0.1 -v 2 mni152.mz3
load from disk: 36 ms
pre-smooth: 57 ms
intensity range 0..88.8585, isolevel 31.5005
voxel clustering (largest cluster, bubbles): 253 ms
marching cubes (207x256x215): 112 ms
Unify vertices found no shared vertices
remove degenerate triangles 580258 -> 580211: 4 ms
 iteration 0 - triangles 580211 threshold 2.187e-06
 iteration 5 - triangles 288579 threshold 0.00209715
 iteration 10 - triangles 95748 threshold 0.0627485
simplify vertices 290191->29039 triangles 580211->58020 (r = 0.0999981): 217 ms
save to disk: 61 ms

If your NIfTI file is a T1-weighted image of the human head, you can try brain2print.org. Alternatively, for CT and other MRI scans, you can try ct2print.org

@abhishekpatil32
Copy link
Author

abhishekpatil32 commented Sep 4, 2024

Hello Chris,

Thank you for your quick reply. I am using the segmentations of a model (in .nii format, with intensity values between 0 and 1) for converting them into .obj files. The previous model input is a CT scan (in dicom).

I tried to do the following command
nii2mesh input.nii output.obj

I get an error that is given above. I tried using the options commands but that did not affect much I believe.

Please find a sample files attached here which do not work with the code version of nii2mesh but work with the web based nii2mesh given in the link: https://rordenlab.github.io/nii2meshWeb/.
segmentations.zip

Am I missing something here in the code?

Thank you

@neurolabusc
Copy link
Owner

I am unable to replicate. Everything runs fine on my machine.

./nii2mesh ~/Downloads/segmentations/segmentation_1.nii output1.obj
./nii2mesh ~/Downloads/segmentations/segmentation_2.nii output2.obj
./nii2mesh ~/Downloads/segmentations/segmentation_2.nii output3.obj

nii2mesh

I can not help you if I can not replicate. Can I suggest you follow the recipe in my previous post, where I compile from source and run the program twice:

  1. once with no arguments (so it will give me some idea about your compiler and architecture as well as the software version, e.g. nii2mesh v1.0.20211220 Clang14.0.3 ARM and also tell me your operating system (MacOS, Linux or Windows).
  2. Run the code a second time with the verbosity set (e.g. add -v 1) so you see details of the processing stages to isolate the failure.
  3. You can also use make sanitize to compile a debug version that will provide a line number for any error.

@abhishekpatil32
Copy link
Author

abhishekpatil32 commented Sep 4, 2024

Hello Chris,

I am using Linux (Google Colab) to run the code.

Here is the code that I have used for the same

Code starts here

import os
!apt-get install git build-essential -y

if not os.path.exists('nii2mesh'):
!git clone https://github.com/neurolabusc/nii2mesh.git

%cd nii2mesh/src
!make
%cd /content

input_nifti = '/content/segmentation_3.nii'
output_mesh = '/content/try.obj'

output_directory = os.path.dirname(output_mesh)
if not os.path.exists(output_directory):
os.makedirs(output_directory)

command = f'./nii2mesh/src/nii2mesh {input_nifti} {output_mesh}'
exit_code = os.system(command)

if exit_code != 0 or not os.path.exists(output_mesh):
print(f"Mesh generation failed for {input_nifti}.")
else:
print(f"Mesh generated successfully for {input_nifti}.")

Code ends here

I get the following error:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
build-essential is already the newest version (12.9ubuntu3).
git is already the newest version (1:2.34.1-1ubuntu1.11).
0 upgraded, 0 newly installed, 0 to remove and 45 not upgraded.
/content/nii2mesh/src
gcc slow marching cubes (to compile with clang/llvm 'make CXX=clang')
gcc -O3 -DNII2MESH isolevel.c meshify.c quadric.c bwlabel.c radixsort.c nii2mesh.c -DHAVE_FORMATS base64.c MarchingCubes.c -lm -lz -DHAVE_ZLIB -o nii2mesh
/content
Mesh generation failed for /content/segmentation_3.nii.

Is there anything wrong I am trying to do?? I get a similar output for each of the files.

@neurolabusc
Copy link
Owner

I am not familiar with this tool chain - you may want to consult someone with Google colab expertise. Can you please see if the code below works. Also, are you sure that the input file exists and has read permissions, and the output location has write permissions with sufficient space.

$ git clone [email protected]:neurolabusc/nii2mesh.git
$ cd nii2mesh/src 
$ make
$ ./nii2mesh -v
nii2mesh v1.0.20211220  Clang14.0.3  ARM
...
$ ./nii2mesh ../../mni152.nii.gz -r 0.1 -v 2 mni152.mz3

@abhishekpatil32
Copy link
Author

abhishekpatil32 commented Sep 4, 2024

Yes I am sure the input file exists and has read permissions as well as there is sufficient space for the file to store...
As I have mentioned the code above doesn't work for only a few nii files. Rest of the files provide the correct obj files.

I initially thought there is an error with the dataset but if its running well at your end and hence it should run on my end as well...

The above code gave me the following output:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
make is already the newest version (4.3-4.1build1).
clang is already the newest version (1:14.0-55~exp2).
git is already the newest version (1:2.34.1-1ubuntu1.11).
0 upgraded, 0 newly installed, 0 to remove and 49 not upgraded.
fatal: destination path 'nii2mesh' already exists and is not an empty directory.
[Errno 20] Not a directory: 'nii2mesh/src'
/content/nii2mesh/src
gcc slow marching cubes (to compile with clang/llvm 'make CXX=clang')
gcc -O3 -DNII2MESH isolevel.c meshify.c quadric.c bwlabel.c radixsort.c nii2mesh.c -DHAVE_FORMATS base64.c MarchingCubes.c -lm -lz -DHAVE_ZLIB -o nii2mesh

nii2mesh v1.0.20211220 GCC11.4.0 x86-64
Converts a NIfTI voxelwise volume to triangulated mesh.
Usage: ./nii2mesh inputNIfTI [options] outputMesh
Options
-a s atlas text file (e.g. '-a D99_v2.0_labels_semicolon.txt')
-b v bubble fill (0=bubbles included, 1=bubbles filled, default 0)
-i v isosurface intensity (d=dark, m=mid, b=bright, number for custom, default medium)
-l v only keep largest cluster (0=all, 1=largest, default 1)
-o v Original marching cubes (0=Improved Lewiner, 1=Original, default 0)
-p v pre-smoothing (0=skip, 1=smooth, default 1)
-r v reduction factor (default 0.25)
-q v quality (0=fast, 1= balanced, 2=best, default 1)
-s v post-smoothing iterations (default 0)
-v v verbose (0=silent, 1=verbose, default 0)
mesh extension sets format (.gii, .json, .mz3, .obj, .ply, .pial, .stl, .vtk)
Example: './nii2mesh voxels.nii mesh.obj'
Example: './nii2mesh bet.nii.gz -i 22 myOutput.obj'
Example: './nii2mesh bet.nii.gz -v 1 -i b bright.obj'
Example: './nii2mesh img.nii -p 0 -r 1 large.ply'
Example: './nii2mesh img.nii -r 0.1 small.gii'
Example: './nii2mesh bet.nii -r 0.2 mesh.mz3'
Example: './nii2mesh mesh.mz3 -r 0.1 small.mz3'

load from disk: 18 ms
pre-smooth: 32 ms
intensity range 0..8235.73, isolevel 2982.52
voxel clustering (largest cluster, bubbles): 94 ms
marching cubes (91x109x91): 46 ms
Unify vertices found no shared vertices
remove degenerate triangles 66744 -> 66736: 5 ms
iteration 0 - triangles 66736 threshold 2.187e-06
iteration 5 - triangles 50430 threshold 0.00209715
iteration 10 - triangles 26880 threshold 0.0627485
iteration 15 - triangles 12876 threshold 0.61222
iteration 20 - triangles 6754 threshold 3.40483
simplify vertices 33382->3347 triangles 66736->6674 (r = 0.100006): 196 ms
save to disk: 12 ms

@abhishekpatil32
Copy link
Author

abhishekpatil32 commented Sep 4, 2024

For the segmentation file that I have sent you gives me the following error:

load from disk: 190 ms
pre-smooth: 2071 ms
intensity range 0..1, isolevel 0.25098
voxel clustering (largest cluster, bubbles): 2924 ms
Marching Cubes: invalid triangle 15733
-0.250980 -0.250980 -0.250980 -0.250980 -0.250980 -nan 131071.750000 21941997487060864704716311175242973184.000000
...
...
...
marching cubes (512x512x191): 91 ms
vertex welding 11381 -> 10955: 1 ms
remove degenerate triangles 19253 -> 18962: 1 ms
double free or corruption (out)

@neurolabusc
Copy link
Owner

Can you recompile the latest commit (it will report nii2mesh v1.0.20240904 and see if this resolves your issue.

@abhishekpatil32
Copy link
Author

Hii Chris,

Thank you for your help.
The latest git has improved a lot.

Previously I had many files which did not convert to .obj, it has reduced significantly.
But I now face another issue with 1-2 odd files.
When I run the following:

./nii2mesh segmentation1.nii -r 0.25 -v 1 segmentation_1.obj

The run stops at something like:

nii2mesh v1.0.20240904  GCC11.4.0  x86-64
load from disk: 157 ms
pre-smooth: 1787 ms
intensity range 0..0.675, isolevel 0.25098
voxel clustering (largest cluster, bubbles): 2641 ms

The issue is I believe for some files the operation does not save the files.

@neurolabusc
Copy link
Owner

I am unable to replicate. Can you share a file that exhibits this behavior?

@abhishekpatil32
Copy link
Author

abhishekpatil32 commented Sep 5, 2024

I used the script

./nii2mesh segment.nii -r 0.25 -v 2 segment.obj

which gives the output

nii2mesh v1.0.20240904  GCC11.4.0  x86-64
load from disk: 153 ms
pre-smooth: 1533 ms
intensity range 0..0.773125, isolevel 0.25098
voxel clustering (largest cluster, bubbles): 2562 ms

Please find the attached nifit file that exhibits this behavior.
segmentation.zip

@neurolabusc
Copy link
Owner

This is a limitation with your segmentation, not the software. nii2mesh returns an error code that you can detect, for example from the command line with $?:

$ ./nii2mesh segment.nii -r 0.25 -v 2 segment.obj
nii2mesh v1.0.20240904  Clang14.0.3  ARM
load from disk: 46 ms
pre-smooth: 1521 ms
intensity range 0..0.773125, isolevel 0.25098
voxel clustering (largest cluster, bubbles): 616 ms25098
$ echo $?
1

I have made a commit that now explicitly provides text describing the error:

marching cubes failed to identify triangles with an isolevel of 0.25098

The only non-zero images in this image are in the very top slice. Marching cubes expects voxels above the isosurface value to be surrounded by voxels below this threshold.

Screenshot 2024-09-05 at 8 35 27 AM

@abhishekpatil32
Copy link
Author

Okay. I understand now..

Thank you for your help..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants