Skip to content

Commit

Permalink
Tissues segmentation now handle artifacts in the tissue
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-Milk committed Mar 22, 2024
1 parent cbe6b27 commit 095e657
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
55 changes: 44 additions & 11 deletions lazyslide/cv_mods/mods.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# See https://github.com/Dana-Farber-AIOS/pathml/blob/master/pathml/preprocessing/transforms.py
import cv2
import matplotlib.pyplot as plt
import numpy as np

from .base import Transform
Expand Down Expand Up @@ -138,6 +139,33 @@ def apply(self, image):
return out.astype(np.uint8)


class ArtifactFilterThreshold(Transform):
def __init__(self, threshold=0):
self.threshold = threshold

def __repr__(self):
return "ArtifactFilterThreshold()"

def apply(self, image):
assert image.dtype == np.uint8, f"image dtype {image.dtype} must be np.uint8"
red_channel = image[:, :, 0].astype(float)
green_channel = image[:, :, 1].astype(float)
blue_channel = image[:, :, 2].astype(float)

red_to_green_mask = np.maximum(red_channel - green_channel, 0)
blue_to_green_mask = np.maximum(blue_channel - green_channel, 0)

tissue_heatmap = red_to_green_mask * blue_to_green_mask

_, out = cv2.threshold(
src=tissue_heatmap.astype(np.uint8),
thresh=self.threshold,
maxval=255,
type=(cv2.THRESH_BINARY + cv2.THRESH_OTSU),
)
return out.astype(np.uint8)


class MorphOpen(Transform):
"""
Morphological opening. First applies erosion operation, then dilation.
Expand Down Expand Up @@ -417,7 +445,7 @@ class TissueDetectionHE(Transform):

def __init__(
self,
use_saturation=True,
use_saturation=False,
blur_ksize=17,
threshold=7,
morph_n_iter=3,
Expand All @@ -426,6 +454,7 @@ def __init__(
max_hole_size=100,
outer_contours_only=False,
return_contours=False,
filter_artifacts=True,
):
self.use_sat = use_saturation
self.blur_ksize = blur_ksize
Expand All @@ -435,11 +464,15 @@ def __init__(
self.min_region_size = min_region_size
self.max_hole_size = max_hole_size
self.outer_contours_only = outer_contours_only
self.filter_artifacts = filter_artifacts

if self.threshold is None:
thresholder = BinaryThreshold(use_otsu=True)
if self.filter_artifacts:
thresholder = ArtifactFilterThreshold(threshold=self.threshold)
else:
thresholder = BinaryThreshold(use_otsu=False, threshold=self.threshold)
if self.threshold is None:
thresholder = BinaryThreshold(use_otsu=True)
else:
thresholder = BinaryThreshold(use_otsu=False, threshold=self.threshold)

if not return_contours:
foreground = ForegroundDetection(
Expand All @@ -457,7 +490,7 @@ def __init__(
self.pipeline = [
MedianBlur(kernel_size=self.blur_ksize),
thresholder,
MorphOpen(kernel_size=self.morph_k_size, n_iterations=self.morph_n_iter),
# MorphOpen(kernel_size=self.morph_k_size, n_iterations=self.morph_n_iter),
MorphClose(kernel_size=self.morph_k_size, n_iterations=self.morph_n_iter),
foreground,
]
Expand All @@ -475,13 +508,13 @@ def apply(self, image):
image.dtype == np.uint8
), f"Input image dtype {image.dtype} must be np.uint8"
# first get single channel image_ref
if self.use_sat:
one_channel = ConvertColorspace(code=cv2.COLOR_RGB2HSV).apply(image)
one_channel = one_channel[:, :, 1]
else:
one_channel = ConvertColorspace(code=cv2.COLOR_RGB2GRAY).apply(image)
# if self.use_sat:
# one_channel = ConvertColorspace(code=cv2.COLOR_RGB2HSV).apply(image)
# one_channel = one_channel[:, :, 1]
# else:
# one_channel = ConvertColorspace(code=cv2.COLOR_RGB2GRAY).apply(image)

tissue = one_channel
tissue = image
for p in self.pipeline:
tissue = p.apply(tissue)
return tissue
4 changes: 2 additions & 2 deletions lazyslide/wsi.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def create_tiles(
mpp=None,
tolerance=0.05,
mask_name="tissue",
background_fraction=0.8,
background_fraction=0.3,
tile_pts=3,
errors="ignore",
tile_filter=None,
Expand Down Expand Up @@ -570,7 +570,7 @@ def plot_tissue(
max_size=1000,
tiles=False,
contours=False,
contour_color="green",
contour_color="red",
hole_color="blue",
linewidth=1,
show_origin=True,
Expand Down

0 comments on commit 095e657

Please sign in to comment.