Segment background and foreground (cells) components of rgb image.
Parameters:
Name |
Type |
Description |
Default |
img
|
ndarray
|
The input image. Shape (H, W, 3).
|
required
|
label
|
ndarray
|
The cell mask. Shape (H, W).
|
required
|
Returns:
Type |
Description |
Tuple[ndarray, ndarray]
|
Tuple[np.ndarray, np.ndarray]:
The background and dark components. Shapes (H, W).
|
Source code in src/histolytics/stroma_feats/utils.py
| def tissue_components(
img: np.ndarray, label: np.ndarray
) -> Tuple[np.ndarray, np.ndarray]:
"""Segment background and foreground (cells) components of rgb image.
Parameters:
img (np.ndarray):
The input image. Shape (H, W, 3).
label (np.ndarray):
The cell mask. Shape (H, W).
Returns:
Tuple[np.ndarray, np.ndarray]:
The background and dark components. Shapes (H, W).
"""
# mask out dark pixels
kmasks = kmeans_img(img, n_clust=3)
# Determine the mean color of each k-means cluster
cluster_means = [img[kmasks == i].mean(axis=0) for i in range(1, 4)]
# Identify the bg, cells, and stroma clusters based on mean color
bg_label = (
np.argmin([np.linalg.norm(mean - [255, 255, 255]) for mean in cluster_means])
+ 1
)
dark_label = np.argmin([np.linalg.norm(mean) for mean in cluster_means]) + 1
# stroma_label = 6 - bg_label - dark_label # Since we have 3 clusters
# Create masks for each cluster
bg_mask = kmasks == bg_label
dark_mask = kmasks == dark_label
if label is not None:
dark_mask += label > 0
bg_mask = rm_objects_mask(erosion(bg_mask, square(3)), min_size=1000)
dark_mask = rm_objects_mask(dilation(dark_mask, square(3)), min_size=200)
bg_mask = fill_holes_mask(bg_mask, min_size=500)
dark_mask = fill_holes_mask(dark_mask, min_size=500)
return bg_mask, dark_mask
|