Spaces:
Sleeping
Sleeping
| """ | |
| @author: louisblankemeier | |
| """ | |
| import os | |
| from pathlib import Path | |
| from typing import Union | |
| import numpy as np | |
| from comp2comp.visualization.detectron_visualizer import Visualizer | |
| def spine_binary_segmentation_overlay( | |
| img_in: Union[str, Path], | |
| mask: Union[str, Path], | |
| base_path: Union[str, Path], | |
| file_name: str, | |
| figure_text_key=None, | |
| spine_hus=None, | |
| seg_hus=None, | |
| spine=True, | |
| model_type=None, | |
| pixel_spacing=None, | |
| ): | |
| """Save binary segmentation overlay. | |
| Args: | |
| img_in (Union[str, Path]): Path to the input image. | |
| mask (Union[str, Path]): Path to the mask. | |
| base_path (Union[str, Path]): Path to the output directory. | |
| file_name (str): Output file name. | |
| centroids (list, optional): List of centroids. Defaults to None. | |
| figure_text_key (dict, optional): Figure text key. Defaults to None. | |
| spine_hus (list, optional): List of HU values. Defaults to None. | |
| spine (bool, optional): Spine flag. Defaults to True. | |
| model_type (Models): Model type. Defaults to None. | |
| """ | |
| _COLORS = ( | |
| np.array( | |
| [ | |
| 1.000, | |
| 0.000, | |
| 0.000, | |
| 0.000, | |
| 1.000, | |
| 0.000, | |
| 1.000, | |
| 1.000, | |
| 0.000, | |
| 1.000, | |
| 0.500, | |
| 0.000, | |
| 0.000, | |
| 1.000, | |
| 1.000, | |
| 1.000, | |
| 0.000, | |
| 1.000, | |
| ] | |
| ) | |
| .astype(np.float32) | |
| .reshape(-1, 3) | |
| ) | |
| label_map = {"L5": 0, "L4": 1, "L3": 2, "L2": 3, "L1": 4, "T12": 5} | |
| _ROI_COLOR = np.array([1.000, 0.340, 0.200]) | |
| _SPINE_TEXT_OFFSET_FROM_TOP = 10.0 | |
| _SPINE_TEXT_OFFSET_FROM_RIGHT = 40.0 | |
| _SPINE_TEXT_VERTICAL_SPACING = 14.0 | |
| img_in = np.clip(img_in, -300, 1800) | |
| img_in = normalize_img(img_in) * 255.0 | |
| images_base_path = Path(base_path) / "images" | |
| images_base_path.mkdir(exist_ok=True) | |
| img_in = img_in.reshape((img_in.shape[0], img_in.shape[1], 1)) | |
| img_rgb = np.tile(img_in, (1, 1, 3)) | |
| vis = Visualizer(img_rgb) | |
| levels = list(spine_hus.keys()) | |
| levels.reverse() | |
| num_levels = len(levels) | |
| # draw seg masks | |
| for i, level in enumerate(levels): | |
| color = _COLORS[label_map[level]] | |
| edge_color = None | |
| alpha_val = 0.2 | |
| vis.draw_binary_mask( | |
| mask[:, :, i].astype(int), | |
| color=color, | |
| edge_color=edge_color, | |
| alpha=alpha_val, | |
| area_threshold=0, | |
| ) | |
| # draw rois | |
| for i, _ in enumerate(levels): | |
| color = _ROI_COLOR | |
| edge_color = color | |
| vis.draw_binary_mask( | |
| mask[:, :, num_levels + i].astype(int), | |
| color=color, | |
| edge_color=edge_color, | |
| alpha=alpha_val, | |
| area_threshold=0, | |
| ) | |
| vis.draw_text( | |
| text="ROI", | |
| position=( | |
| mask.shape[1] - _SPINE_TEXT_OFFSET_FROM_RIGHT - 35, | |
| _SPINE_TEXT_OFFSET_FROM_TOP, | |
| ), | |
| color=[1, 1, 1], | |
| font_size=9, | |
| horizontal_alignment="center", | |
| ) | |
| vis.draw_text( | |
| text="Seg", | |
| position=( | |
| mask.shape[1] - _SPINE_TEXT_OFFSET_FROM_RIGHT, | |
| _SPINE_TEXT_OFFSET_FROM_TOP, | |
| ), | |
| color=[1, 1, 1], | |
| font_size=9, | |
| horizontal_alignment="center", | |
| ) | |
| # draw text and lines | |
| for i, level in enumerate(levels): | |
| vis.draw_text( | |
| text=f"{level}:", | |
| position=( | |
| mask.shape[1] - _SPINE_TEXT_OFFSET_FROM_RIGHT - 80, | |
| _SPINE_TEXT_VERTICAL_SPACING * (i + 1) + _SPINE_TEXT_OFFSET_FROM_TOP, | |
| ), | |
| color=_COLORS[label_map[level]], | |
| font_size=9, | |
| horizontal_alignment="left", | |
| ) | |
| vis.draw_text( | |
| text=f"{round(float(spine_hus[level]))}", | |
| position=( | |
| mask.shape[1] - _SPINE_TEXT_OFFSET_FROM_RIGHT - 35, | |
| _SPINE_TEXT_VERTICAL_SPACING * (i + 1) + _SPINE_TEXT_OFFSET_FROM_TOP, | |
| ), | |
| color=_COLORS[label_map[level]], | |
| font_size=9, | |
| horizontal_alignment="center", | |
| ) | |
| vis.draw_text( | |
| text=f"{round(float(seg_hus[level]))}", | |
| position=( | |
| mask.shape[1] - _SPINE_TEXT_OFFSET_FROM_RIGHT, | |
| _SPINE_TEXT_VERTICAL_SPACING * (i + 1) + _SPINE_TEXT_OFFSET_FROM_TOP, | |
| ), | |
| color=_COLORS[label_map[level]], | |
| font_size=9, | |
| horizontal_alignment="center", | |
| ) | |
| """ | |
| vis.draw_line( | |
| x_data=(0, mask.shape[1] - 1), | |
| y_data=( | |
| int( | |
| inferior_superior_centers[num_levels - i - 1] | |
| * (pixel_spacing[2] / pixel_spacing[1]) | |
| ), | |
| int( | |
| inferior_superior_centers[num_levels - i - 1] | |
| * (pixel_spacing[2] / pixel_spacing[1]) | |
| ), | |
| ), | |
| color=_COLORS[label_map[level]], | |
| linestyle="dashed", | |
| linewidth=0.25, | |
| ) | |
| """ | |
| vis_obj = vis.get_output() | |
| img = vis_obj.save(os.path.join(images_base_path, file_name)) | |
| return img | |
| def normalize_img(img: np.ndarray) -> np.ndarray: | |
| """Normalize the image. | |
| Args: | |
| img (np.ndarray): Input image. | |
| Returns: | |
| np.ndarray: Normalized image. | |
| """ | |
| return (img - img.min()) / (img.max() - img.min()) | |