Example #1
0
def test_mesh_to_image():
    # Import succeeds
    from hasi.align import mesh_to_image

    # Mesh-to-image executes without error
    images = mesh_to_image([template_mesh, target_mesh])

    # Images were generated
    assert (all([
        type(image) == itk.Image[mesh_pixel_type, dimension]
        for image in images
    ]))

    # Images occupy the same physical space
    assert (all(
        [itk.spacing(image) == itk.spacing(images[0]) for image in images]))
    assert (all([itk.size(image) == itk.size(images[0]) for image in images]))
    assert (all(
        [itk.origin(image) == itk.origin(images[0]) for image in images]))

    # Mesh-to-image can run with reference image
    image_from_reference = mesh_to_image(target_mesh,
                                         reference_image=images[0])

    # Type and image attributes match previous output
    assert (type(image_from_reference) == type(images[0]))
    assert (itk.spacing(image_from_reference) == itk.spacing(images[0]))
    assert (itk.size(image_from_reference) == itk.size(images[0]))
    assert (itk.origin(image_from_reference) == itk.origin(images[0]))
Example #2
0
def enclosing_geometry(img1, img2):
    """
    Does img1 enclose img2?

    This function could be used to test whether img2 can be used as a reference image for resampling img1.
    """
    if equal_geometry(img1, img2):
        return True
    o1 = np.array(itk.origin(img1))
    o2 = np.array(itk.origin(img2))
    s1 = np.array(itk.spacing(img1))
    s2 = np.array(itk.spacing(img2))
    n1 = np.array(itk.size(img1))
    n2 = np.array(itk.size(img2))
    # compute corners
    lower1 = o1 - 0.5 * s1
    lower2 = o2 - 0.5 * s2
    upper1 = o1 + (n1 - 0.5) * s1
    upper2 = o2 + (n2 - 0.5) * s2
    #######################################################################
    # for debugging: percentages of img2 that are inside/outside of img1. #
    #######################################################################
    bb1 = bounding_box(img=img1)
    vol1 = bb1.volume
    bb2 = bounding_box(img=img2)
    vol2 = bb2.volume
    assert (vol2 > 0)
    bb2.intersect(bb1)
    overlap = bb2.volume
    outside = vol2 - bb2.volume
    overlap_percent = overlap * 100. / vol2
    outside_percent = outside * 100. / vol2
    logger.debug(f"vol img2={vol1} vol img2={vol2}")
    logger.debug(
        f"part of img2 that overlaps with img1: {overlap} or {overlap_percent} percent"
    )
    logger.debug(
        f"part of img2 that is outside img1: {outside} or {outside_percent} percent"
    )
    #######################################################################
    # end debugging section                                               #
    #######################################################################
    # now check the lower corner
    if (np.logical_not(np.isclose(lower1, lower2)) * (lower1 > lower2)).any():
        return False
    # now check the upper corner
    if (np.logical_not(np.isclose(upper1, upper2)) * (upper1 < upper2)).any():
        return False
    return True
Example #3
0
def interpolate_secondaries(input_folder, output_folder, factor,
                            target_numprojs):
    sec_numprojs = len(glob.glob(f'./{input_folder}/secondary????.mha'))

    img0 = itk.imread(f'./{input_folder}/secondary0000.mha')
    img_origin = itk.origin(img0)
    img_spacing = itk.spacing(img0)

    image_ind = 0
    for projnum in range(sec_numprojs - 1):
        # get
        image1 = f'./{input_folder}/secondary{projnum:04d}.mha'
        image2 = f'./{input_folder}/secondary{projnum+1:04d}.mha'

        img1_array = itk.GetArrayFromImage(itk.imread(image1))
        img2_array = itk.GetArrayFromImage(itk.imread(image2))

        # save the first image
        itk.imwrite(itk.imread(image1),
                    f'./{output_folder}/secondary{image_ind:04d}.mha')

        # interpolate xfactor images between those 2 images
        image_interpolate_recurrence(img1_array, img2_array, image_ind,
                                     image_ind + factor, output_folder,
                                     img_origin, img_spacing)
        image_ind = image_ind + factor

    # read the last image and save it until the target_numprojs is reached
    lastimage = itk.imread(
        f'./{input_folder}/secondary{sec_numprojs-1:04d}.mha')
    while image_ind < target_numprojs:
        itk.imwrite(lastimage,
                    f'./{output_folder}/secondary{image_ind:04d}.mha')
        image_ind = image_ind + 1
Example #4
0
def compareImageHeaders(img1, img2, tolerance=0.00001):
    print("Comparing headers")
    sp1 = itk.GetArrayFromVnlVector(itk.spacing(img1).GetVnlVector())
    sp2 = itk.GetArrayFromVnlVector(itk.spacing(img2).GetVnlVector())
    spVar = np.sum(np.abs(sp2 - sp1))

    if (spVar > tolerance):
        return (False)

    or1 = itk.GetArrayFromVnlVector(itk.origin(img1).GetVnlVector())
    or2 = itk.GetArrayFromVnlVector(itk.origin(img2).GetVnlVector())
    orVar = np.sum(np.abs(or2 - or1))

    if (orVar > tolerance):
        return (False)

    return (True)
Example #5
0
def attenuation_local(prim_per_proj, proj_path):
    if not os.path.exists(proj_path):
        os.makedirs(proj_path)
    interp_secfolder = 'interpolated_secondaries'
    if not os.path.exists(interp_secfolder):
        os.makedirs(interp_secfolder)

    #IMC=PMC×#primaries_per_projection×(512/128)^2+SMC
    size_primary = 512
    size_scatter = 64
    factor = prim_per_proj * pow(size_primary / size_scatter, 2)

    # get all the primary projections
    primary_files = sorted(glob.glob('./output/primary*.mha'))
    interpolate_secondaries(secondary_folder, interp_secfolder, 4,
                            len(primary_files))

    for projnum, primary_filename in enumerate(primary_files):
        # load the primary, secondary, and flatfield
        primary = itk.imread(primary_filename)
        flatfield = itk.imread(primary_filename.replace(
            "primary", "flatfield"))

        #not needed anymore - secondaries only have half the projections, so the secondary projection number = projnum/2
        #second_projnum = projnum // 4
        #secondary = itk.imread(f'./output/secondary{second_projnum:04d}.mha')
        secondary = itk.imread(
            f'{interp_secfolder}/secondary{projnum:04d}.mha')
        resizedsecondary = gt.applyTransformation(
            input=secondary,
            newsize=itk.size(primary),
            neworigin=itk.origin(primary),
            adaptive=True,
            force_resample=True)

        flatfield = itk.MultiplyImageFilter(flatfield, factor)

        prim_second = itk.AddImageFilter(
            itk.MultiplyImageFilter(primary, factor), resizedsecondary)
        #flatfield_sq = itk.MultiplyImageFilter(flatfield,flatfield)

        S = itk.DivideImageFilter(prim_second, flatfield)
        S = itk.MultiplyImageFilter(S, itk.MedianImageFilter(flatfield))
        attenuation = itk.LogImageFilter(S)
        #attenuation = itk.LogImageFilter(itk.DivideImageFilter(prim_second,flatfield))

        attenuation = itk.MultiplyImageFilter(attenuation, -1)

        itk.imwrite(
            attenuation,
            primary_filename.replace('./output/primary',
                                     f'{proj_path}/attenuation_sec'))
Example #6
0
def downsample_images(images:list, ratio:float) -> list:
    assert(ratio > 1.0)

    downsampled_image_list = list()
    for image in images:
        new_spacing = [spacing * ratio for spacing in itk.spacing(image)]
        new_size = [int(size / ratio) for size in itk.size(image)]
        downsampled_image = itk.resample_image_filter(image,
                                                      size=new_size,
                                                      output_origin=itk.origin(image),
                                                      output_spacing=new_spacing)
        downsampled_image_list.append(downsampled_image)
    return downsampled_image_list
Example #7
0
def xarray_from_image(l_image):
    """Convert an itk.Image to an xarray.DataArray.

    Origin and spacing metadata is preserved in the xarray's coords. The
    Direction is set in the `direction` attribute.
    Dims are labeled as `x`, `y`, `z`, and `c`.

    This interface is and behavior is experimental and is subject to possible
    future changes."""
    import xarray as xr
    import itk
    import numpy as np

    array_view = itk.array_view_from_image(l_image)
    l_spacing = itk.spacing(l_image)
    l_origin = itk.origin(l_image)
    l_size = itk.size(l_image)
    direction = np.flip(itk.array_from_matrix(l_image.GetDirection()))
    spatial_dimension = l_image.GetImageDimension()

    spatial_dims = ("x", "y", "z")
    coords = {}
    for l_index, dim in enumerate(spatial_dims[:spatial_dimension]):
        coords[dim] = np.linspace(
            l_origin[l_index],
            l_origin[l_index] + (l_size[l_index] - 1) * l_spacing[l_index],
            l_size[l_index],
            dtype=np.float64,
        )

    dims = list(reversed(spatial_dims[:spatial_dimension]))
    components = l_image.GetNumberOfComponentsPerPixel()
    if components > 1:
        dims.append("c")
        coords["c"] = np.arange(components, dtype=np.uint64)

    data_array = xr.DataArray(array_view,
                              dims=dims,
                              coords=coords,
                              attrs={"direction": direction})
    return data_array
Example #8
0
assert s[0] == s[1] == 256

# test physical size
s = itk.physical_size(reader)
assert s[0] == s[1] == 256.0
s = itk.physical_size(reader.GetOutput())
assert s[0] == s[1] == 256.0

# test spacing
s = itk.spacing(reader)
assert s[0] == s[1] == 1.0
s = itk.spacing(reader.GetOutput())
assert s[0] == s[1] == 1.0

# test origin
s = itk.origin(reader)
assert s[0] == s[1] == 0.0
s = itk.origin(reader.GetOutput())
assert s[0] == s[1] == 0.0

# test index
s = itk.index(reader)
assert s[0] == s[1] == 0
s = itk.index(reader.GetOutput())
assert s[0] == s[1] == 0

# test region
s = itk.region(reader)
assert s.GetIndex()[0] == s.GetIndex()[1] == 0
assert s.GetSize()[0] == s.GetSize()[1] == 256
s = itk.region(reader.GetOutput())
Example #9
0
assert s[0] == s[1] == 256

# test physical size
s = itk.physical_size(reader)
assert s[0] == s[1] == 256.0
s = itk.physical_size(reader.GetOutput())
assert s[0] == s[1] == 256.0

# test spacing
s = itk.spacing(reader)
assert s[0] == s[1] == 1.0
s = itk.spacing(reader.GetOutput())
assert s[0] == s[1] == 1.0

# test origin
s = itk.origin(reader)
assert s[0] == s[1] == 0.0
s = itk.origin(reader.GetOutput())
assert s[0] == s[1] == 0.0

# test index
s = itk.index(reader)
assert s[0] == s[1] == 0
s = itk.index(reader.GetOutput())
assert s[0] == s[1] == 0

# test region
s = itk.region(reader)
assert s.GetIndex()[0] == s.GetIndex()[1] == 0
assert s.GetSize()[0] == s.GetSize()[1] == 256
s = itk.region(reader.GetOutput())
Example #10
0
assert s[0] == s[1] == 256

# test physical size
s = itk.physical_size(reader)
assert s[0] == s[1] == 256.0
s = itk.physical_size(reader.GetOutput())
assert s[0] == s[1] == 256.0

# test spacing
s = itk.spacing(reader)
assert s[0] == s[1] == 1.0
s = itk.spacing(reader.GetOutput())
assert s[0] == s[1] == 1.0

# test origin
s = itk.origin(reader)
assert s[0] == s[1] == 0.0
s = itk.origin(reader.GetOutput())
assert s[0] == s[1] == 0.0

# test index
s = itk.index(reader)
assert s[0] == s[1] == 0
s = itk.index(reader.GetOutput())
assert s[0] == s[1] == 0

# test region
s = itk.region(reader)
assert s.GetIndex()[0] == s.GetIndex()[1] == 0
assert s.GetSize()[0] == s.GetSize()[1] == 256
s = itk.region(reader.GetOutput())
Example #11
0
parser = argparse.ArgumentParser(description="Resample A Scalar Image.")
parser.add_argument("input_image")
parser.add_argument("output_image")
parser.add_argument("size_x", type=int)
parser.add_argument("size_y", type=int)
args = parser.parse_args()

output_size = [args.size_x, args.size_y]

input_image = itk.imread(args.input_image)

input_spacing = itk.spacing(input_image)
input_size = itk.size(input_image)
dimension = input_image.GetImageDimension()
output_spacing = [
    input_spacing[dim] * input_size[dim] / output_size[dim]
    for dim in range(dimension)
]

transform = itk.IdentityTransform[itk.D, dimension].New()

output_image = itk.resample_image_filter(
    input_image,
    size=output_size,
    output_spacing=output_spacing,
    output_origin=itk.origin(input_image),
    transform=transform,
)

itk.imwrite(output_image, args.output_image)
Example #12
0
def attenuation(prim_per_proj, proj_path, num_jobs):
    if not os.path.exists(proj_path):
        os.makedirs(proj_path)
    interp_secfolder = 'interpolated_secondaries'
    if not os.path.exists(interp_secfolder):
        os.makedirs(interp_secfolder)

    for results_dir in glob.glob('./results.*'):
        if os.path.isfile(f'{results_dir}/primary0000.mha'):
            primary_folder = results_dir
        elif os.path.isfile(f'{results_dir}/secondary0000.mha'):
            secondary_folder = results_dir

    #IMC=PMC×#primaries_per_projection×(512/128)^2+SMC
    size_primary = 512
    size_scatter = 64
    # get the number of jobs actually completed from the run folder of the scatter simulation
    #secondary_runfolder = secondary_folder.replace('results','run')
    #job_completed = len(glob.glob(f"{secondary_runfolder}/output.*"))
    with open(f"num_completed_jobs.txt", "r") as f:
        job_completed = int(f.readline())

    factor = (prim_per_proj * job_completed / num_jobs) * pow(
        size_primary / size_scatter, 2)

    # get all the primary projections
    primary_files = sorted(glob.glob(f'{primary_folder}/primary*.mha'))
    interpolate_secondaries(secondary_folder, interp_secfolder, 4,
                            len(primary_files))

    for projnum, primary_filename in enumerate(primary_files):
        # load the primary, secondary, and flatfield
        primary = itk.imread(primary_filename)
        flatfield = itk.imread(primary_filename.replace(
            "primary", "flatfield"))
        #not needed anymore - secondaries only have half the projections, so the secondary projection number = projnum/2
        #second_projnum = projnum // 4
        #secondary = itk.imread(f'{secondary_folder}/secondary{second_projnum:04d}.mha')
        secondary = itk.imread(
            f'{interp_secfolder}/secondary{projnum:04d}.mha')
        resizedsecondary = gt.applyTransformation(
            input=secondary,
            newsize=itk.size(primary),
            neworigin=itk.origin(primary),
            adaptive=True,
            force_resample=True)

        flatfield = itk.MultiplyImageFilter(flatfield, factor)

        prim_second = itk.AddImageFilter(
            itk.MultiplyImageFilter(primary, factor), resizedsecondary)
        #flatfield_sq = itk.MultiplyImageFilter(flatfield,flatfield)

        S = itk.DivideImageFilter(prim_second, flatfield)
        S = itk.MultiplyImageFilter(S, itk.MedianImageFilter(flatfield))
        attenuation = itk.LogImageFilter(S)
        #attenuation = itk.LogImageFilter(itk.DivideImageFilter(prim_second,flatfield))
        attenuation = itk.MultiplyImageFilter(attenuation, -1)

        attenuation_path = primary_filename.replace(
            f'{os.path.dirname(primary_filename)}/primary',
            f'{proj_path}/attenuation_sec')
        itk.imwrite(attenuation, attenuation_path)
Example #13
0
def conv_3Dto2D(img_3D_filename, label_3D_filename, outputimages_foldername_x,
                outputimages_foldername_y, outputimages_foldername_z,
                outputlabels_foldername_x, outputlabels_foldername_y,
                outputlabels_foldername_z, image_identifier_x,
                image_identifier_y, image_identifier_z, patient_names_x,
                patient_names_y, patient_names_z, casenumber_x, casenumber_y,
                casenumber_z, slice_info_filename_x, slice_info_filename_y,
                slice_info_filename_z, localtaskfolder_x, localtaskfolder_y,
                localtaskfolder_z, patient_folder):

    if outputlabels_foldername_x == '':
        test_dataset = True

        images2D_foldername_x = f'{localtaskfolder_x}/2D_testimages_x/'
        labels2D_foldername_x = f'{localtaskfolder_x}/2D_testlabels_x'
        labels_nifti_foldername_x = f'{localtaskfolder_x}/2D_testlabels_nii_x'

        images2D_foldername_y = f'{localtaskfolder_y}/2D_testimages_y/'
        labels2D_foldername_y = f'{localtaskfolder_y}/2D_testlabels_y'
        labels_nifti_foldername_y = f'{localtaskfolder_y}/2D_testlabels_nii_y'

        images2D_foldername_z = f'{localtaskfolder_z}/2D_testimages_z/'
        labels2D_foldername_z = f'{localtaskfolder_z}/2D_testlabels_z'
        labels_nifti_foldername_z = f'{localtaskfolder_z}/2D_testlabels_nii_z'

        outputlabels_foldername_x = labels_nifti_foldername_x
        outputlabels_foldername_y = labels_nifti_foldername_y
        outputlabels_foldername_z = labels_nifti_foldername_z
    else:
        test_dataset = False

        images2D_foldername_x = f'{localtaskfolder_x}/2D_trainingimages_x/'
        labels2D_foldername_x = f'{localtaskfolder_x}/2D_traininglabels_x'
        labels_nifti_foldername_x = f'{localtaskfolder_x}/2D_traininglabels_nii_x'

        images2D_foldername_y = f'{localtaskfolder_y}/2D_trainingimages_y/'
        labels2D_foldername_y = f'{localtaskfolder_y}/2D_traininglabels_y'
        labels_nifti_foldername_y = f'{localtaskfolder_y}/2D_traininglabels_nii_y'

        images2D_foldername_z = f'{localtaskfolder_z}/2D_trainingimages_z/'
        labels2D_foldername_z = f'{localtaskfolder_z}/2D_traininglabels_z'
        labels_nifti_foldername_z = f'{localtaskfolder_z}/2D_traininglabels_nii_z'

    maybe_mkdir_p(images2D_foldername_x)
    maybe_mkdir_p(labels2D_foldername_x)
    maybe_mkdir_p(labels_nifti_foldername_x)
    maybe_mkdir_p(images2D_foldername_y)
    maybe_mkdir_p(labels2D_foldername_y)
    maybe_mkdir_p(labels_nifti_foldername_y)
    maybe_mkdir_p(images2D_foldername_z)
    maybe_mkdir_p(labels2D_foldername_z)
    maybe_mkdir_p(labels_nifti_foldername_z)

    img = itk.imread(img_3D_filename)
    img_spacing = itk.spacing(img)
    img_origin = itk.origin(img)
    img_array = itk.GetArrayFromImage(img)

    if label_3D_filename != '':
        labelimg = itk.imread(label_3D_filename)
        label_spacing = itk.spacing(labelimg)
        label_origin = itk.origin(labelimg)
        label_array = itk.GetArrayFromImage(labelimg)

    # x direction
    # save for each patient the 3d_imagename, the image_identifier, the first slice, last slice, origin, and spacing of the 3d image
    num_slices = itk.size(img)[0]
    with open(slice_info_filename_x, "a") as f:
        f.write(
            f"{os.path.basename(img_3D_filename)}\t{image_identifier_x}\t{casenumber_x}\t{casenumber_x+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n"
        )

    for i in range(num_slices):
        casename = f'{image_identifier_x}_{casenumber_x:04d}'
        img_2D = itk.GetImageFromArray(img_array[:, :, i])
        img_2D.SetSpacing([img_spacing[1], img_spacing[2]])
        img_2D.SetOrigin([img_origin[1], img_origin[2]])

        # save the 2d image in the 2D folder
        image2D_filename = f'{images2D_foldername_x}/{casename}.mha'
        #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha')
        itk.imwrite(img_2D, image2D_filename)

        label_array2D = label_array[:, :, i]
        label_2D = itk.GetImageFromArray(label_array2D)
        label_2D.SetSpacing([label_spacing[1], label_spacing[2]])
        label_2D.SetOrigin([label_origin[1], label_origin[2]])
        #itk.imwrite(label_2D,outputlabel_filename)
        #print(label_array2D)

        # save the 2d label in the 2D folder
        label2D_filename = f'{labels2D_foldername_x}/{casename}.mha'
        #(label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha')
        itk.imwrite(label_2D, label2D_filename)

        # if the label is empty, don't include the image in the training dataset
        if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)):
            patient_names_x.append(casename)

            # save the 2d image as a 3D nifti in the nnunet folder
            outputimage_filename = f'{outputimages_foldername_x}/{casename}'
            convert_2d_image_to_nifti(image2D_filename,
                                      outputimage_filename,
                                      is_seg=False)

            # save the 2d label as a 3D nifti in the nnunet folder
            outputlabel_filename = f'{outputlabels_foldername_x}/{casename}'
            convert_2d_image_to_nifti(label2D_filename,
                                      outputlabel_filename,
                                      is_seg=True)

        casenumber_x = casenumber_x + 1

    # y direction
    num_slices = itk.size(img)[1]
    with open(slice_info_filename_y, "a") as f:
        f.write(
            f"{os.path.basename(img_3D_filename)}\t{image_identifier_y}\t{casenumber_y}\t{casenumber_y+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n"
        )
    for i in range(num_slices):
        casename = f'{image_identifier_y}_{casenumber_y:04d}'
        #outputimage_filename= f'{outputimages_foldername}/{casename}_0000.nii.gz'
        #outputlabel_filename= f'{outputlabels_foldername}/{casename}.nii.gz'

        img_2D = itk.GetImageFromArray(img_array[:, i, :])
        img_2D.SetSpacing([img_spacing[0], img_spacing[2]])
        img_2D.SetOrigin([img_origin[0], img_origin[2]])

        # save the 2d image in the 2D folder
        image2D_filename = f'{images2D_foldername_y}/{casename}.mha'
        #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha')
        itk.imwrite(img_2D, image2D_filename)

        label_array2D = label_array[:, i, :]
        label_2D = itk.GetImageFromArray(label_array2D)
        label_2D.SetSpacing([label_spacing[0], label_spacing[2]])
        label_2D.SetOrigin([label_origin[0], label_origin[2]])
        #itk.imwrite(label_2D,outputlabel_filename)

        # save the 2d label in the 2D folder
        label2D_filename = f'{labels2D_foldername_y}/{casename}.mha'
        #label2D_filename= (label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha')
        itk.imwrite(label_2D, label2D_filename)

        # if the label is empty, don't include the image in the training dataset
        if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)):
            patient_names_y.append(casename)

            # save the 2d image as a 3D nifti in the nnunet folder
            outputimage_filename = f'{outputimages_foldername_y}/{casename}'
            convert_2d_image_to_nifti(image2D_filename,
                                      outputimage_filename,
                                      is_seg=False)

            # save the 2d label as a 3D nifti in the nnunet folder
            outputlabel_filename = f'{outputlabels_foldername_y}/{casename}'
            convert_2d_image_to_nifti(label2D_filename,
                                      outputlabel_filename,
                                      is_seg=True)

        casenumber_y = casenumber_y + 1

    # z direction
    num_slices = itk.size(img)[2]
    with open(slice_info_filename_z, "a") as f:
        f.write(
            f"{os.path.basename(img_3D_filename)}\t{image_identifier_z}\t{casenumber_z}\t{casenumber_z+num_slices-1}\t{np.array(img_origin)}\t{np.array(img_spacing)}\t{patient_folder}\n"
        )
    for i in range(num_slices):
        casename = f'{image_identifier_z}_{casenumber_z:04d}'
        #outputimage_filename= f'{outputimages_foldername}/{casename}_0000.nii.gz'
        #outputlabel_filename= f'{outputlabels_foldername}/{casename}.nii.gz'

        img_2D = itk.GetImageFromArray(img_array[i, :, :])
        img_2D.SetSpacing([img_spacing[0], img_spacing[1]])
        img_2D.SetOrigin([img_origin[0], img_origin[1]])

        # save the 2d image in the 2D folder
        image2D_filename = f'{images2D_foldername_z}/{casename}.mha'
        #image2D_filename= (img_3D_filename.replace('3D','2D')).replace('.',f'_{i:04d}.')
        itk.imwrite(img_2D, image2D_filename)

        label_array2D = label_array[i, :, :]
        label_2D = itk.GetImageFromArray(label_array2D)
        label_2D.SetSpacing([label_spacing[0], label_spacing[1]])
        label_2D.SetOrigin([label_origin[0], label_origin[1]])
        #itk.imwrite(label_2D,outputlabel_filename)

        # save the 2d label in the 2D folder
        label2D_filename = f'{labels2D_foldername_z}/{casename}.mha'
        #label2D_filename= (label_3D_filename.replace('3D','2D')).replace('.mha',f'_{i:04d}.mha')
        itk.imwrite(label_2D, label2D_filename)

        # if the image or the label is empty, don't include the image in the training dataset
        if np.any(img_2D) & ((test_dataset == True) | np.any(label_array2D)):
            patient_names_z.append(casename)

            # save the 2d image as a 3D nifti in the nnunet folder
            outputimage_filename = f'{outputimages_foldername_z}/{casename}'
            convert_2d_image_to_nifti(image2D_filename,
                                      outputimage_filename,
                                      is_seg=False)

            # save the 2d label as a 3D nifti in the nnunet folder
            outputlabel_filename = f'{outputlabels_foldername_z}/{casename}'
            convert_2d_image_to_nifti(label2D_filename,
                                      outputlabel_filename,
                                      is_seg=True)

        casenumber_z = casenumber_z + 1

    return casenumber_x, casenumber_y, casenumber_z, patient_names_x, patient_names_y, patient_names_z