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()) | |