-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmask_segmentation_with_dapi.py
More file actions
52 lines (41 loc) · 2.42 KB
/
mask_segmentation_with_dapi.py
File metadata and controls
52 lines (41 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from skimage import filters, morphology, measure
from typing import Optional
import numpy as np
def apply_tissue_mask(dapi_image: np.ndarray, segmentation: np.ndarray, sigma: float = 2.0,
area_threshold: int = 1000, dilation_radius: int = 3) -> np.ndarray:
"""
Removes border nuclei from a DAPI-stained image by applying a mask based on segmentation.
Parameters:
- dapi_image (np.ndarray): Input grayscale DAPI image as a NumPy array.
- segmentation (np.ndarray): Binary or labeled segmentation image to be masked.
- sigma (float, optional): Sigma for Gaussian blur to smoothen the DAPI image. Default is 2.0.
- area_threshold (int, optional): Minimum area for small hole removal. Default is 1000.
- dilation_radius (int, optional): Radius for morphological dilation. Default is 3.
Returns:
- np.ndarray: Masked segmentation image with border nuclei removed.
Raises:
- ValueError: If input images are of different shapes or if they are not 2D or 3D arrays.
"""
# Validate input dimensions
if dapi_image.shape != segmentation.shape:
raise ValueError("Input images must have the same shape.")
# Step 1: Apply Gaussian blur to the DAPI image
blurred_image = filters.gaussian(dapi_image, sigma=sigma)
print(f"Applied Gaussian blur with sigma={sigma}. Shape: {blurred_image.shape}")
# Step 2: Threshold the blurred image using Otsu's method
threshold_value = filters.threshold_otsu(blurred_image)
binary_image = blurred_image > threshold_value
print(f"Applied Otsu thresholding. Threshold value: {threshold_value}")
# Step 3: Fill holes in the binary image
filled_image = morphology.remove_small_holes(binary_image, area_threshold=area_threshold)
print(f"Filled small holes in binary image. Area threshold: {area_threshold}")
# Step 4: Label connected regions in the filled image
labeled_image = measure.label(filled_image)
print(f"Labeled connected regions. Number of regions: {labeled_image.max()}")
# Step 5: Merge small regions using morphological dilation
merged_image = morphology.dilation(labeled_image, morphology.disk(dilation_radius))
print(f"Applied morphological dilation with radius={dilation_radius}")
# Step 6: Apply merged mask to the segmentation image
masked_image = segmentation * (merged_image > 0)
print("Applied merged mask to segmentation image.")
return masked_image