Skip to content

Commit

Permalink
Merge pull request #959 from benmalef/change_lib_from_tiffslide_to_op…
Browse files Browse the repository at this point in the history
…enslide

Add support for DICOM WSI by using OpenSlide
  • Loading branch information
sarthakpati authored Oct 31, 2024
2 parents 4659f19 + 94feb7f commit e69e4d5
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Dockerfile-CPU
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ CMD run
# See https://github.com/hexops/dockerfile as a best practices guide.
#RUN addgroup --gid 10001 --system nonroot \
# && adduser --uid 10000 --system --ingroup nonroot --home /home/nonroot nonroot
#
#
#USER nonroot

# Prepare the container for possible model embedding later.
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile-ROCm
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ CMD run
# See https://github.com/hexops/dockerfile as a best practices guide.
#RUN addgroup --gid 10001 --system nonroot \
# && adduser --uid 10000 --system --ingroup nonroot --home /home/nonroot nonroot
#
#
#USER nonroot

# Prepare the container for possible model embedding later.
Expand Down
14 changes: 8 additions & 6 deletions GANDLF/compute/inference_loop.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from skimage.io import imsave
from tqdm import tqdm
from torch.cuda.amp import autocast
import tiffslide as openslide
import openslide
from GANDLF.data import get_testing_loader
from GANDLF.utils import (
best_model_path_end,
Expand Down Expand Up @@ -344,11 +344,13 @@ def inference_loop(
)
cv2.imwrite(file_to_write, heatmaps[key])

os_image_array = os_image.read_region(
(0, 0),
parameters["slide_level"],
(level_width, level_height),
as_array=True,
# this is needed because openslide returns an RGBA image
os_image_array = np.asarray(
os_image.read_region(
(0, 0),
parameters["slide_level"],
(level_width, level_height),
).convert("RGB")
)
blended_image = cv2.addWeighted(
os_image_array,
Expand Down
17 changes: 10 additions & 7 deletions GANDLF/data/inference_dataloader_histopath.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from typing import Optional
import numpy as np
import tiffslide
import openslide
from GANDLF.data.patch_miner.opm.utils import get_patch_size_in_microns, tissue_mask
from skimage.transform import resize
from torch.utils.data.dataset import Dataset
Expand Down Expand Up @@ -51,7 +51,7 @@ def __init__(
self._stride_size = get_patch_size_in_microns(wsi_path, self._stride_size)
self._selected_level = selected_level
self._mask_level = mask_level
self._os_image = tiffslide.open_slide(os.path.join(self._wsi_path))
self._os_image = openslide.open_slide(os.path.join(self._wsi_path))
self._points = []
self._basic_preprocessing()

Expand All @@ -61,11 +61,13 @@ def _basic_preprocessing(self):
try:
mask_xdim, mask_ydim = self._os_image.level_dimensions[self._mask_level]
mask = get_tissue_mask(
self._os_image.read_region(
(0, 0), self._mask_level, (mask_xdim, mask_ydim), as_array=True
# this is needed because openslide returns an RGBA image
np.asarray(
self._os_image.read_region(
(0, 0), self._mask_level, (mask_xdim, mask_ydim)
).convert("RGB")
)
)

if self._selected_level != self._mask_level:
mask = resize(mask, (height, width))
mask = (mask > 0).astype(np.ubyte)
Expand Down Expand Up @@ -134,9 +136,10 @@ def __getitem__(self, idx):
(x_loc, y_loc),
self._selected_level,
(self._patch_size[0], self._patch_size[1]),
as_array=True,
)
# as_array=True, openslide-python returns an RGBA PIL image
).convert("RGB")

patch = np.asarray(patch) # convert the image to ndarray
# this is to ensure that channels come at the beginning
patch = patch.transpose([2, 0, 1])
# this is to ensure that we always have a z-stack before applying any torchio transforms
Expand Down
4 changes: 3 additions & 1 deletion GANDLF/data/patch_miner/opm/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def read_patch(self):
return np.asarray(
self.slide_object.read_region(
(self.coordinates[1], self.coordinates[0]), self.level, self.size
)
).convert(
"RGB"
) # openslide-python returns an RGBA PIL image
)

def copy(self):
Expand Down
6 changes: 3 additions & 3 deletions GANDLF/data/patch_miner/opm/patch_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from tqdm import tqdm
from pathlib import Path
import pandas as pd
import tiffslide
import openslide


class PatchManager:
Expand Down Expand Up @@ -41,7 +41,7 @@ def set_subjectID(self, subjectID):
def set_slide_path(self, filename):
self.img_path = filename
self.img_path = convert_to_tiff(self.img_path, self.output_dir, "img")
self.slide_object = tiffslide.open_slide(self.img_path)
self.slide_object = openslide.open_slide(self.img_path)
self.slide_dims = self.slide_object.dimensions

def set_label_map(self, path):
Expand All @@ -50,7 +50,7 @@ def set_label_map(self, path):
@param path: path to label map.
"""
self.label_map = convert_to_tiff(path, self.output_dir, "mask")
self.label_map_object = tiffslide.open_slide(self.label_map)
self.label_map_object = openslide.open_slide(self.label_map)

assert all(
x == y for x, y in zip(self.label_map_object.dimensions, self.slide_dims)
Expand Down
14 changes: 7 additions & 7 deletions GANDLF/data/patch_miner/opm/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# import matplotlib.pyplot as plt
import yaml
import tiffslide
import openslide

# RGB Masking (pen) constants
RGB_RED_CHANNEL = 0
Expand Down Expand Up @@ -428,7 +428,7 @@ def generate_initial_mask(slide_path: str, scale: int) -> Tuple[np.ndarray, tupl
Tuple[np.ndarray, tuple]: The valid mask and the real scale.
"""
# Open slide and get properties
slide = tiffslide.open_slide(slide_path)
slide = openslide.open_slide(slide_path)
slide_dims = slide.dimensions

# Call thumbnail for effiency, calculate scale relative to whole slide
Expand Down Expand Up @@ -505,26 +505,26 @@ def get_patch_size_in_microns(
"Using mpp to calculate patch size for dimension {}".format(i)
)
# only enter if "m" is present in patch size
input_slide = tiffslide.open_slide(input_slide_path)
input_slide = openslide.open_slide(input_slide_path)
metadata = input_slide.properties
if i == 0:
for _property in [
tiffslide.PROPERTY_NAME_MPP_X,
openslide.PROPERTY_NAME_MPP_X,
"tiff.XResolution",
"XResolution",
]:
if _property in metadata:
magnification = metadata[_property]
magnification = float(metadata[_property])
magnification_prev = magnification
break
elif i == 1:
for _property in [
tiffslide.PROPERTY_NAME_MPP_Y,
openslide.PROPERTY_NAME_MPP_Y,
"tiff.YResolution",
"YResolution",
]:
if _property in metadata:
magnification = metadata[_property]
magnification = float(metadata[_property])
break
if magnification == -1:
# if y-axis data is missing, use x-axis data
Expand Down
2 changes: 0 additions & 2 deletions GANDLF/entrypoints/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import argparse
import ast

# import traceback
from typing import Optional

from deprecated import deprecated
import click

Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
import sys, re, os
from setuptools import setup, find_packages


try:
with open("README.md") as readme_file:
readme = readme_file.read()
except Exception as error:
readme = "No README information found."
sys.stderr.write("Warning: Could not open '%s' due %s\n" % ("README.md", error))


try:
filepath = "GANDLF/version.py"
version_file = open(filepath)
Expand Down Expand Up @@ -52,7 +52,6 @@
"setuptools",
"seaborn",
"pyyaml==6.0.1",
"tiffslide",
"matplotlib",
"gdown==5.1.0",
"pytest",
Expand Down Expand Up @@ -83,6 +82,8 @@
"colorlog",
"opacus==1.5.2",
"huggingface-hub==0.25.1",
"openslide-bin",
"openslide-python==1.4.1",
]

if __name__ == "__main__":
Expand Down

0 comments on commit e69e4d5

Please sign in to comment.