[Python] How can I visualize the segmentation masks predicted by my U-Net model in a...

Discussão em 'Python' iniciado por Stack, Agosto 30, 2025.

  1. Stack

    Stack Membro Participativo

    I'm using CustomTkinter to build a GUI for medical image segmentation. I have a button to load the images, and I’ve previously saved my trained model as "unet_model.h5". I want to display the predicted segmentation masks in the interface so that doctors can visualize the segmentations, but they currently don’t appear. Instead, I get the following error:

    Exception in Tkinter callback
    Traceback (most recent call last):
    File "C:\Users\maria\anaconda3\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
    ^^^^^^^^^^^^^^^^
    File "C:\Users\maria\anaconda3\Lib\site-packages\customtkinter\windows\widgets\ctk_button.py", line 554, in _clicked
    self._command()
    File "C:\Users\maria\AppData\Local\Temp\ipykernel_27908\467682517.py", line 141, in loadimg
    segment_volume(pasta)
    File "C:\Users\maria\AppData\Local\Temp\ipykernel_27908\467682517.py", line 131, in segment_volume
    show_slice(current_slice)
    File "C:\Users\maria\AppData\Local\Temp\ipykernel_27908\467682517.py", line 93, in show_slice
    img_label.configure(image=img_label._image_ref)
    File "C:\Users\maria\anaconda3\Lib\site-packages\customtkinter\windows\widgets\ctk_label.py", line 222, in configure
    self._update_image()
    File "C:\Users\maria\anaconda3\Lib\site-packages\customtkinter\windows\widgets\ctk_label.py", line 144, in _update_image
    self._label.configure(image=self._image)
    File "C:\Users\maria\anaconda3\Lib\tkinter\__init__.py", line 1702, in configure
    return self._configure('configure', cnf, kw)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "C:\Users\maria\anaconda3\Lib\tkinter\__init__.py", line 1692, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
    _tkinter.TclError: image "pyimage7" doesn't exist


    This is the code I tried:

    import os
    import cv2
    import numpy as np
    from tensorflow.keras.models import load_model
    import customtkinter
    from tkinter import filedialog
    from PIL import Image, ImageTk

    #Pre-processing before segmentation
    def natural_key(string_):
    import re
    return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_)]

    def resize_and_pad(img, size):
    desired_size = size[0]
    old_size = img.shape[:2]

    if old_size[0] == 0 or old_size[1] == 0:
    print("Warning: Image with zero dimensions. Skip")
    return None

    ratio = float(desired_size) / max(old_size)
    new_size = tuple([int(x*ratio) for x in old_size])

    if new_size[0] == 0 or new_size[1] == 0:
    print("Warning: Redimensioning with zero dimensions. Skip")
    return None

    img_resized = cv2.resize(img, (new_size[1], new_size[0]))
    delta_w = desired_size - new_size[1]
    delta_h = desired_size - new_size[0]
    top, bottom = delta_h//2, delta_h-(delta_h//2)
    left, right = delta_w//2, delta_w-(delta_w//2)

    color = [0, 0, 0]
    new_img = cv2.copyMakeBorder(img_resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    return new_img

    def load_test_volume(test_folder, img_size=(256, 256), downsample_factor=1):
    slice_folder = os.path.join(test_folder)

    slice_files = sorted(
    [f for f in os.listdir(slice_folder) if f.endswith(('.tif', '.png'))],
    key=natural_key
    )

    slices = []
    for slice_file in slice_files:
    slice_path = os.path.join(slice_folder, slice_file)
    img = cv2.imread(slice_path, cv2.IMREAD_GRAYSCALE)
    if img is None:
    print(f"Warning: impossible to read the image {slice_path}. Skip")
    continue

    img = cv2.resize(img, (0, 0), fx=downsample_factor, fy=downsample_factor, interpolation=cv2.INTER_LINEAR)
    img = resize_and_pad(img, img_size)
    if img is None:
    continue
    slices.append(img)

    return slices

    #Load model

    MODEL_PATH = "unet_model.h5"
    model = load_model(MODEL_PATH, compile=False)

    current_slice = 0
    Xtest_global = None
    preds_global = None
    img_label = None
    mask_label = None


    def show_slice(index):
    global img_label, mask_label

    if Xtest_global is None or preds_global is None:
    return

    img = (Xtest_global[index].squeeze() * 255).astype(np.uint8)
    img_pil = Image.fromarray(img)
    img_tk = ImageTk.PhotoImage(img_pil)
    img_label._image_ref = img_tk
    img_label.configure(image=img_label._image_ref)

    mask = (preds_global[index].squeeze() * 255).astype(np.uint8)
    mask_pil = Image.fromarray(mask)
    mask_tk = ImageTk.PhotoImage(mask_pil)
    mask_label._image_ref = mask_tk
    mask_label.configure(image=mask_label._image_ref)

    def next_slice():
    global current_slice
    if Xtest_global is None:
    return
    if current_slice < len(Xtest_global)-1:
    current_slice += 1
    show_slice(current_slice)

    def prev_slice():
    global current_slice
    if Xtest_global is None:
    return
    if current_slice > 0:
    current_slice -= 1
    show_slice(current_slice)

    #Segmentation

    def segment_volume(folder_path):
    global Xtest_global, preds_global, current_slice

    slice_imgs = load_test_volume(folder_path, downsample_factor=1)
    if len(slice_imgs) == 0:
    print("None valid image found in the folder")
    return

    X_slices = [img[..., np.newaxis] / 255.0 for img in slice_imgs]
    Xtest_global = np.array(X_slices)
    preds_global = (model.predict(Xtest_global) > 0.5).astype("int32")

    current_slice = 0
    show_slice(current_slice)

    prev_btn.configure(state="normal")
    next_btn.configure(state="normal")

    #Load images

    def loadimg():
    pasta = filedialog.askdirectory()
    if pasta:
    print("Selected folder", pasta)
    segment_volume(pasta)

    customtkinter.set_appearance_mode("light")
    customtkinter.set_default_color_theme("dark-blue")

    root = customtkinter.CTk()
    root.geometry("900x600")

    frame_top = customtkinter.CTkFrame(master=root)
    frame_top.pack(pady=10, padx=10, fill="x")

    label = customtkinter.CTkLabel(master=frame_top, text="Segmentator OCT- Retina", font=("Roboto", 24))
    label.pack(pady=12)

    botao = customtkinter.CTkButton(master=frame_top, text="Load OCT Volume", command=loadimg)
    botao.pack(pady=5)

    frame_imgs = customtkinter.CTkFrame(master=root)
    frame_imgs.pack(pady=10, padx=10, fill="both", expand=True)

    img_label = customtkinter.CTkLabel(master=frame_imgs)
    img_label.pack(side="left", padx=10, pady=10)

    mask_label = customtkinter.CTkLabel(master=frame_imgs)
    mask_label.pack(side="right", padx=10, pady=10)

    frame_nav = customtkinter.CTkFrame(master=root)
    frame_nav.pack(pady=10)

    prev_btn = customtkinter.CTkButton(master=frame_nav, text="Anterior", command=prev_slice, state="disabled")
    prev_btn.pack(side="left", padx=20)

    next_btn = customtkinter.CTkButton(master=frame_nav, text="Próximo", command=next_slice, state="disabled")
    next_btn.pack(side="right", padx=20)

    root.mainloop()

    Continue reading...

Compartilhe esta Página