scientific-skills/histolab/references/tissue_masks.md
Tissue masks are binary representations that identify tissue regions within whole slide images. They are essential for filtering out background, artifacts, and non-tissue areas during tile extraction. Histolab provides several mask classes to accommodate different tissue segmentation needs.
Purpose: Generic base class for creating custom binary masks.
from histolab.masks import BinaryMask
class CustomMask(BinaryMask):
def _mask(self, obj):
# Implement custom masking logic
# Return binary numpy array
pass
Use cases:
Purpose: Segments all tissue regions in the slide using automated filters.
from histolab.masks import TissueMask
# Create tissue mask
tissue_mask = TissueMask()
# Apply to slide
mask_array = tissue_mask(slide)
How it works:
Returns: Binary NumPy array where:
True (or 1): Tissue pixelsFalse (or 0): Background pixelsBest for:
Purpose: Identifies and returns the bounding box of the largest connected tissue region.
from histolab.masks import BiggestTissueBoxMask
# Create mask for largest tissue region
biggest_mask = BiggestTissueBoxMask()
# Apply to slide
mask_array = biggest_mask(slide)
How it works:
Best for:
Masks accept custom filter chains for specialized tissue detection:
from histolab.masks import TissueMask
from histolab.filters.image_filters import RgbToGrayscale, OtsuThreshold
from histolab.filters.morphological_filters import BinaryDilation, RemoveSmallHoles
# Define custom filter composition
custom_mask = TissueMask(
filters=[
RgbToGrayscale(),
OtsuThreshold(),
BinaryDilation(disk_size=5),
RemoveSmallHoles(area_threshold=500)
]
)
from histolab.slide import Slide
from histolab.masks import TissueMask
slide = Slide("slide.svs", processed_path="output/")
mask = TissueMask()
# Visualize mask boundaries on thumbnail
slide.locate_mask(mask)
This displays the slide thumbnail with mask boundaries overlaid in a contrasting color.
import matplotlib.pyplot as plt
from histolab.masks import TissueMask
slide = Slide("slide.svs", processed_path="output/")
tissue_mask = TissueMask()
# Generate mask
mask_array = tissue_mask(slide)
# Plot side by side
fig, axes = plt.subplots(1, 2, figsize=(15, 7))
axes[0].imshow(slide.thumbnail)
axes[0].set_title("Original Slide")
axes[0].axis('off')
axes[1].imshow(mask_array, cmap='gray')
axes[1].set_title("Tissue Mask")
axes[1].axis('off')
plt.show()
Define specific regions of interest:
from histolab.masks import BinaryMask
import numpy as np
class RectangularMask(BinaryMask):
def __init__(self, x_start, y_start, width, height):
self.x_start = x_start
self.y_start = y_start
self.width = width
self.height = height
def _mask(self, obj):
# Create mask with specified rectangular region
thumb = obj.thumbnail
mask = np.zeros(thumb.shape[:2], dtype=bool)
mask[self.y_start:self.y_start+self.height,
self.x_start:self.x_start+self.width] = True
return mask
# Use custom mask
roi_mask = RectangularMask(x_start=1000, y_start=500, width=2000, height=1500)
Pathology slides often contain pen markings or digital annotations. Exclude them using custom masks:
from histolab.masks import TissueMask
from histolab.filters.image_filters import RgbToGrayscale, OtsuThreshold
from histolab.filters.morphological_filters import BinaryDilation
class AnnotationExclusionMask(BinaryMask):
def _mask(self, obj):
thumb = obj.thumbnail
# Convert to HSV to detect pen marks (often blue/green)
hsv = cv2.cvtColor(np.array(thumb), cv2.COLOR_RGB2HSV)
# Define color ranges for pen marks
lower_blue = np.array([100, 50, 50])
upper_blue = np.array([130, 255, 255])
# Create mask excluding pen marks
pen_mask = cv2.inRange(hsv, lower_blue, upper_blue)
# Apply standard tissue detection
tissue_mask = TissueMask()(obj)
# Combine: keep tissue, exclude pen marks
final_mask = tissue_mask & ~pen_mask.astype(bool)
return final_mask
Masks integrate seamlessly with tilers through the extraction_mask parameter:
from histolab.tiler import RandomTiler
from histolab.masks import TissueMask, BiggestTissueBoxMask
# Use TissueMask to extract from all tissue
random_tiler = RandomTiler(
tile_size=(512, 512),
n_tiles=100,
level=0,
extraction_mask=TissueMask() # Extract from all tissue regions
)
# Or use default BiggestTissueBoxMask
random_tiler = RandomTiler(
tile_size=(512, 512),
n_tiles=100,
level=0,
extraction_mask=BiggestTissueBoxMask() # Default behavior
)
locate_mask() or manual visualization to verify mask qualityTissueMask for multiple tissue sections, BiggestTissueBoxMask for single main sectionsTissueMask is more comprehensive but computationally intensive than BiggestTissueBoxMaskSolution: Adjust Otsu threshold or increase small object removal threshold
Solution: Reduce small object removal threshold or modify dilation parameters
Solution: Switch from BiggestTissueBoxMask to TissueMask
Solution: Implement custom annotation exclusion mask (see example above)