Source code for spateo.digitization.boundary_old

"""Written by @Jinerhal, adapted by @Xiaojieqiu.
"""

from typing import List, Optional, Tuple, Union

import cv2
import numpy as np
from anndata import AnnData

from ..configuration import SKM
from ..logging import logger_manager as lm
from .contour import *
from .utils_old import *


[docs]def identify_boundary( adata: AnnData, cluster_key, source_id, target_id, bin_size: int = 1, spatial_key: str = "spatial", boundary_key: str = "boundary_line", k_size=8, min_area=30, dilate_k_size: int = 3, ): lm.main_info(f"Setting up source and target area.") adata_tmp = adata.copy() adata_tmp.obs["tmp_boundary"] = 0 adata_tmp.obs["tmp_boundary"][adata_tmp.obs[cluster_key].isin(source_id)] = 1 adata_tmp.obs["tmp_boundary"][adata_tmp.obs[cluster_key].isin(target_id)] = 2 lm.main_info(f"Identifying boundary.") boundary_img = gen_cluster_image(adata_tmp, bin_size, spatial_key, "tmp_boundary", show=False) source_label = np.unique( adata_tmp[ np.isin( adata_tmp.obs["tmp_boundary"], [ 1, ], ), :, ].obs["cluster_img_label"] ) target_label = np.unique( adata_tmp[ np.isin( adata_tmp.obs["tmp_boundary"], [ 2, ], ), :, ].obs["cluster_img_label"] ) _, _, ctr_img = extract_cluster_contours( boundary_img, source_label, bin_size=bin_size, k_size=k_size, min_area=min_area, show=False ) _, tgt_img, _ = extract_cluster_contours( boundary_img, target_label, bin_size=bin_size, k_size=k_size, min_area=min_area, show=False ) dilate_kernel = np.ones((dilate_k_size, dilate_k_size), np.uint8) tgt_img = cv2.dilate(tgt_img, dilate_kernel, iterations=1) lm.main_info(f"Generating boundary line image.") boundary_line_img = np.where(tgt_img != 0, ctr_img, 0) lm.main_info(f"Saving boundary into adata.obs['{boundary_key}'] for visualization.") adata.obs[boundary_key] = " " for i in range(len(adata)): if boundary_line_img[int(adata.obsm[spatial_key][i, 0]), int(adata.obsm[spatial_key][i, 1])] != 0: adata.obs["boundary_line"][i] = "Boundary Line" return boundary_line_img.astype(np.uint8)
[docs]def boundary_gridding( adata: AnnData, boundary_line_img, boundary_line_list, n_layer=3, n_column=25, layer_width=10, spatial_key: str = "spatial", init: bool = False, ): bdl_seg_inner_list = [] bdl_seg_outer_list = [] bdl_seg_ori = segment_bd_line(boundary_line_list, n_column) for i_layer in range(n_layer): curr_layer = i_layer + 1 extend_width = layer_width * curr_layer img_ex, ext_bdl_list = extend_layer(boundary_line_img, boundary_line_list, extend_width=extend_width) # plt.imshow(img_ex) ext_bdl_list_tmp = ext_bdl_list.copy() ext_bdl_list_tmp.append(ext_bdl_list_tmp[0]) edge_point_index = [] for i in range(len(ext_bdl_list_tmp) - 1): max_manh_dist = max( abs(ext_bdl_list_tmp[i][0] - ext_bdl_list_tmp[i + 1][0]), abs(ext_bdl_list_tmp[i][1] - ext_bdl_list_tmp[i + 1][1]), ) if max_manh_dist > 1: edge_point_index.append(i) ext_bdl_inner = ext_bdl_list[edge_point_index[0] + 1 : edge_point_index[1] + 1] ext_bdl_outer = ext_bdl_list[edge_point_index[1] + 1 :] + ext_bdl_list[: edge_point_index[0] + 1] ext_bdl_outer = ext_bdl_outer[::-1] ext_bdl_inner_seg = segment_bd_line(ext_bdl_inner, n_column) bdl_seg_inner_list.append(ext_bdl_inner_seg) ext_bdl_outer_seg = segment_bd_line(ext_bdl_outer, n_column) bdl_seg_outer_list.append(ext_bdl_outer_seg) bdl_seg_all_list = bdl_seg_inner_list[::-1] + [bdl_seg_ori] + bdl_seg_outer_list for i_layer in range(n_layer * 2): curr_layer_num = i_layer % 3 + 1 curr_sign = (-1) ** (i_layer // 3 + 1) seg_grid_img = draw_seg_grid(boundary_line_img, bdl_seg_all_list[i_layer], bdl_seg_all_list[i_layer + 1]) fill_grid_label( adata, spatial_key, seg_grid_img, bdl_seg_all_list[i_layer], bdl_seg_all_list[i_layer + 1], curr_layer_num, curr_sign, init=init and (i_layer == 0), )