Repost in support (sorry) python function vs main / crash in function but not in main

Nicolas_Tempier
Thu, 08 Jun 2023 10:15:05 +0000
Support

Hello everyone,
first of all, sorry for the repost, i posted this issue in development section instead of support …

i have a little problem understanding why my code crashes when i use it as a function.

i want to display a ndpi image, which works but i want to improve the code to make it quicker.

so i made a new script to load and display my image. if i use it as an “alone” code, or main like this :

import numpy as np
import slicer
import vtk
from vtk.util import numpy_support
from PIL import Image
import openslide

volume_name = ‘image_loaded’
size = None
image_path = ‘/media/nicolas.tempier/NT_LAU_KARA/These/NDPI_treatment/H2h_TH_330_2022_04_26_16_34_57.ndpi’
level = 5
top_left_coordinates = (0, 0)

# Charger l’image NDPI

image_ndpi = openslide.OpenSlide(image_path)

# Obtenir les dimensions du niveau

dimensions = image_ndpi.level_dimensions[level]

# Obtenir le facteur de sous-échantillonnage du niveau

downsample_factor = image_ndpi.level_downsamples[level]

# Convertir les coordonnées du niveau cible en coordonnées du niveau 0

top_left_coordinates_level_0 = (int(top_left_coordinates[0] * downsample_factor),
int(top_left_coordinates[1] * downsample_factor))

# Sélectionner résolution

print(f"Résolution sélectionnée: {level}")
if size is None:
size = image_ndpi.level_dimensions[level]

# Lire l’image en utilisant les coordonnées du niveau 0

image_matrix = image_ndpi.read_region(top_left_coordinates_level_0, level, size)

# Convertir l’image en un tableau NumPy et créer un objet VTK Image

image_array = np.array(image_matrix)[:, :, :3]
image_array = np.swapaxes(image_array, 0, 1)
image_array = np.ascontiguousarray(image_array, dtype=np.uint8)

# Créer une image VTK avec 3 dimensions spatiales et 3 dimensions d’intensité pour les canaux RGB

vtk_image_rgb = vtk.vtkImageData()
vtk_image_rgb.SetDimensions(image_array.shape[1], image_array.shape[0], 1)
vtk_image_rgb.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 3)
vtk_image_rgb.SetSpacing(1, 1, 1)

# Convertir le tableau NumPy en une liste d’octets

image_list = image_array.flatten()

# Convertir la liste d’octets en un tableau VTK

vtk_array = numpy_support.numpy_to_vtk(num_array=image_list, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR)

# Associer le tableau VTK à un vtkUnsignedCharArray

rgb_array_vtk = vtk.vtkUnsignedCharArray()
rgb_array_vtk.SetNumberOfComponents(3)
rgb_array_vtk.SetArray(vtk_array, len(image_list), 1)

# Associer le tableau vtkUnsignedCharArray aux scalaires de l’image VTK

vtk_image_rgb.GetPointData().SetScalars(rgb_array_vtk)

# Ajouter l’image à un nœud de volume dans 3D Slicer

volume_node = slicer.mrmlScene.AddNewNodeByClass(‘vtkMRMLVectorVolumeNode’, volume_name)
volume_node.SetSpacing(1, 1, 1)
volume_node.SetAndObserveImageData(vtk_image_rgb)
slicer.app.applicationLogic().PropagateVolumeSelection(0)

It works ! i can clic on on display, volume information etc

But when i modify it as a function :

import numpy as np
import slicer
import vtk
from vtk.util.vtkImageImportFromArray import vtkImageImportFromArray
from vtk.util import numpy_support
from PIL import Image
import timeit

try:
import openslide
except:
slicer.util.pip_install(‘openslide-python’)
import openslide

def load_ndpi_image2(image_path, level, bottom_right_coordinates, size=None, volume_name=‘image_loaded’):
# Charger l’image NDPI
image_ndpi = openslide.OpenSlide(image_path)

# Obtenir les dimensions du niveau
dimensions = image_ndpi.level_dimensions[level]

# Obtenir le facteur de sous-échantillonnage du niveau
downsample_factor = image_ndpi.level_downsamples[level]

# Convertir les coordonnées du niveau cible en coordonnées du niveau 0
top_left_coordinates_level_0 = (int(bottom_right_coordinates[0] * downsample_factor),
                                int(bottom_right_coordinates[1] * downsample_factor))

# test1 = int(input('crash ? 1 '))


# Sélectionner résolution
print(f"Résolution sélectionnée: {level}")
if size is None:
    size = image_ndpi.level_dimensions[level]

# Lire l'image en utilisant les coordonnées du niveau 0
image_matrix = image_ndpi.read_region(top_left_coordinates_level_0, level, size)

# Convertir l'image en un tableau NumPy et créer un objet VTK Image
image_array = np.array(image_matrix)[:, :, :3]
image_array = np.swapaxes(image_array, 0, 1)
image_array = np.ascontiguousarray(image_array, dtype=np.uint8)

# test2 = int(input('crash ? 2 '))


# Créer une image VTK avec 3 dimensions spatiales et 3 dimensions d'intensité pour les canaux RGB
vtk_image_rgb = vtk.vtkImageData()
vtk_image_rgb.SetDimensions(image_array.shape[1], image_array.shape[0], 1)
vtk_image_rgb.AllocateScalars(vtk.VTK_UNSIGNED_CHAR, 3)
vtk_image_rgb.SetSpacing(1, 1, 1)

# Convertir le tableau NumPy en une liste d'octets
image_list = image_array.flatten()

# Convertir la liste d'octets en un tableau VTK
vtk_array = numpy_support.numpy_to_vtk(num_array=image_list, deep=True, array_type=vtk.VTK_UNSIGNED_CHAR)

# test3 = int(input('crash ? 3 '))


# Associer le tableau VTK à un vtkUnsignedCharArray
rgb_array_vtk = vtk.vtkUnsignedCharArray()
rgb_array_vtk.SetNumberOfComponents(3)
rgb_array_vtk.SetArray(vtk_array, len(image_list), 1)

# Associer le tableau vtkUnsignedCharArray aux scalaires de l'image VTK
vtk_image_rgb.GetPointData().SetScalars(rgb_array_vtk)

# test4 = int(input('crash ? 4 '))


# Ajouter l'image à un nœud de volume dans 3D Slicer
volume_node = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLVectorVolumeNode', volume_name)
volume_node.SetSpacing(1, 1, 1)
volume_node.SetAndObserveImageData(vtk_image_rgb)
slicer.app.applicationLogic().PropagateVolumeSelection(0)

image_path = “ilovedealingwithcrashes.ndpi”
load_ndpi_image2(“/media/nicolas.tempier/NT_LAU_KARA/These/NDPI_treatment/H2h_TH_330_2022_04_26_16_34_57.ndpi”, 6, (0,0), volume_name=‘image_lowres_time_2’)

( till there it works great i can see the image was created)

but if i click on it to display it or if i want to see the volume informations, it crashes …

i tried using python to display it to :

volume_node = slicer.util.getNode(‘image_lowres_time_2’)
slicer.app.layoutManager().sliceWidget(“Red”).sliceLogic().GetSliceCompositeNode().SetForegroundVolumeID(volume_node.GetID())

but it crashes too.

the images at this level of zoom are not that big (1600,1900) and RGB but still, it works when i’m not using it as a function …

Thanks you all in advance if you can find me some help

Best,
Nicolas

4 posts - 2 participants