pyushkevich/itksnap

Nii segmentation z-flip in certain circumstances (4.0.0)

KrisThielemans opened this issue · 15 comments

I have a CT in DICOM and a segmentation in Nifti (obtained by someone else in a previous version of itk-snap). When first loading the CT as main image and then the segmentation, there is a SI flip in how the segmentation is displayed. I can confirm that by loading the segmentation as additional image, which displays correctly.

DICOM with segmentation as layer
image

segmentation loaded as additional image and segmentation as layer
image

I have checked that if I convert the CT to Nifti using an external tool, load that as main image, and then load the segmentation, ITK-snap displays it alright.

Unfortunately I cannot share the CT, but could share the segmented nii (although that's unlikely to be any use).

(Maybe some flag that doesn't get re-initialised?)

Hi Kris, thanks for reporting the issue! Can you share the segmentation nii?

I suspect it's something related to the dicom main image. Have you tried saving the main image as nii, and open the nii main image and segmentation?

here's the segmentation segmentation.nii.gz

Contrary to my expectations, exporting the DICOM to Nifti via ITKsnap, and then loading the output Nii in a new window showed the same erroneous behaviour

Here's the header output from one of our tools (from https://github.com/SyneRBI/SIRF/)

sirf_print_nifti_info.exe .\segmentation4d.nii .\CT2.nii
                  0              -3023
Printing info for 2 nifti image(s):
        analyze_75_orient: 0                  0
        analyze75_orient:  0                  0
        byteorder:         1                  1
        cal_max:           0                  0
        cal_min:           0                  0
        datatype:          16                 16
        dt:                1                  0
        du:                0                  0
        dv:                0                  0
        dw:                0                  0
        dx:                0.976562           0.976562
        dy:                0.976562           0.976562
        dz:                0.625              0.625
        ext_list:          0000000000000000   0000000000000000
        freq_dim:          0                  0
        iname_offset:      352                352
        intent_code:       0                  0
        intent_p1:         0                  0
        intent_p2:         0                  0
        intent_p3:         0                  0
        nbyper:            4                  4
        ndim:              4                  3
        nifti_type:        1                  1
        num_ext:           0                  0
        nvox:              282066944          70516736
        nx:                512                512
        ny:                512                512
        nz:                269                269
        nt:                4                  1
        nu:                1                  1
        nv:                1                  1
        nw:                1                  1
        phase_dim:         0                  0
        qfac:              1                  -1
        qform_code:        1                  1
        qoffset_x:         250                250
        qoffset_y:         250                250
        qoffset_z:         -288.75            -121.25
        quatern_b:         0                  0
        quatern_c:         0                  0
        quatern_d:         1                  1
        scl_inter:         0                  0
        scl_slope:         1                  1
        sform_code:        1                  1
        slice_code:        0                  0
        slice_dim:         0                  0
        slice_duration:    0                  0
        slice_end:         0                  0
        slice_start:       0                  0
        swapsize:          4                  4
        time_units:        0                  0
        toffset:           0                  0
        xyz_units:         2                  2
        dim[0]:            4                  3
        dim[1]:            512                512
        dim[2]:            512                512
        dim[3]:            269                269
        dim[4]:            4                  1
        dim[5]:            1                  1
        dim[6]:            1                  1
        dim[7]:            1                  1
        pixdim[0]:         0                  0
        pixdim[1]:         0.976562           0.976562
        pixdim[2]:         0.976562           0.976562
        pixdim[3]:         0.625              0.625
        pixdim[4]:         1                  0
        pixdim[5]:         0                  0
        pixdim[6]:         0                  0
        pixdim[7]:         0                  0
        qto_ijk:
                           [-1.02,0,0,256]    [-1.02,-0,0,256]
                           [0,-1.02,0,256]    [-0,-1.02,0,256]
                           [0,0,1.6,462]      [-0,-0,-1.6,-194]
                           [0,0,0,1]          [0,0,0,1]
        qto_xyz:
                           [-0.977,0,0,250]   [-0.977,0,-0,250]
                           [0,-0.977,0,250]   [0,-0.977,-0,250]
                           [0,0,0.625,-289]   [0,0,-0.625,-121]
                           [0,0,0,1]          [0,0,0,1]
        sto_ijk:
                           [-1.02,0,0,256]    [-1.02,-0,0,256]
                           [0,-1.02,0,256]    [-0,-1.02,0,256]
                           [0,0,1.6,462]      [-0,-0,-1.6,-194]
                           [0,0,0,1]          [0,0,0,1]
        sto_xyz:
                           [-0.977,0,0,250]   [-0.977,0,-0,250]
                           [0,-0.977,0,250]   [0,-0.977,-0,250]
                           [0,0,0.625,-289]   [0,0,-0.625,-121]
                           [0,0,0,1]          [0,0,0,1]
        orig_datatype:     4                  4
        min:
        max:               1                  3071
        mean:              0.25               -1296.97
        contains nans?:    0                  0

showing that the 2 files have different slice order.

Note that DICOM and exported nii and "segmentation as additional image" all look fine. It is the "segmentation as segmentation" that is displayed incorrectly as stated above

Thanks for the extra info! It's very helpful.

Did the ITK-SNAP-Converted Nifti render differently than the External-Converted Nifti? Did the image orient correctly when directly loaded as DICOM?

Images all load correct and are always displayed the same. It's only the segmentation that isn't (presumably only when its slice orientation doesn't match the one of the main image)

  1. first load DICOM

DICOM:
image
segmentation loaded as additional image
image
segmentation loaded as segmentation
image
Note that the origin z is different from the one above

  1. don't load DICOM but load segmentation as main image
    matrix info of both "segmentation as image" and "segmentation as segmentation" is the same
    image

I haven't included any DICOM info as I don't know which fields you're interested in. Also, as I can reproduce the problem with the DICOM exported via itksnap as nifti, I guess the actual dicom fields don't matter too much?

This issue does not occur with ITK-snap 3.8.0. Segmentation loads fine.

screenshots with 3.8.0:

  1. DICOM
    image
  2. segmentation as additional image and segmentation are identical
    image

i see that 3.8.0 says that orientation is RAI for the DICOM but 4.0.0 RAS.

You should be able to reproduce this with the following files:
segmentation.nii.gz
segmentationstir.zip

load segmentationstir.nii as main image and segmentation.nii.gz as segmentation. The files are "identical" in a geometric sense, but have different slice order. Obviuosly, you might not believe me, but with 3.8.0 it works fine.

Correction. In ITKsnap 3.8.0, loading the DICOM and segmentation.nii works fine, but using segmentationstir.nii shows the flip. This exactly opposed from 4.0.0

Hi Jilei

in my opinion, ITKsnap should either cope with different orientations or tell the user that the orientations don't match and refuse to load the segmentation. Doing the incorrect thing silently is quite dangerous. Of course, the images all load ok (when loaded as mean or additional image), so it seems that the relevant mechanism already exist somewhere in the code in ITKsnap. Therefore maybe the first option isn't too hard to implement, but I have no idea obviously. Putting a safeguard might be the easiest way out.