Skip to content

Commit

Permalink
[pre-commit.ci] auto fixes from pre-commit.com hooks
Browse files Browse the repository at this point in the history
for more information, see https://pre-commit.ci
  • Loading branch information
pre-commit-ci[bot] committed May 8, 2024
1 parent b93f023 commit b2f5197
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 43 deletions.
32 changes: 18 additions & 14 deletions monailabel/transform/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import nibabel as nib
import numpy as np
import skimage.measure as measure
from skimage.measure import find_contours,approximate_polygon

import torch
from monai.config import KeysCollection, NdarrayOrTensor
from monai.data import MetaTensor
Expand All @@ -30,6 +28,7 @@
)
from monai.utils import InterpolateMode, convert_to_numpy, ensure_tuple_rep
from shapely.geometry import Point, Polygon
from skimage.measure import approximate_polygon, find_contours
from torchvision.utils import make_grid, save_image

from monailabel.utils.others.label_colors import get_color
Expand Down Expand Up @@ -189,7 +188,7 @@ def __init__(
self.key_label_colors = key_label_colors
self.key_foreground_points = key_foreground_points
self.colormap = colormap

labels = labels if labels else dict()
labels = [labels] if isinstance(labels, str) else labels
if not isinstance(labels, dict):
Expand All @@ -213,35 +212,39 @@ def __call__(self, data):
p = d[key]
if np.count_nonzero(p) < self.min_positive:
continue

labels = [label for label in np.unique(p).tolist() if label > 0]

for label_idx in labels:
p = convert_to_numpy(d[key]) if isinstance(d[key], torch.Tensor) else d[key]
p = np.where(p == label_idx, 1, 0).astype(np.uint8)
p = np.moveaxis(p, 0, 1)
p = np.moveaxis(p, 0, 1)

if label_idx == 0:
continue

Check warning on line 224 in monailabel/transform/post.py

View check run for this annotation

Codecov / codecov/patch

monailabel/transform/post.py#L224

Added line #L224 was not covered by tests
label_name = self.labels.get(label_idx, label_idx)
label_names.add(label_name)
contours = find_contours(p, 0.5) # note: skimage use subpixel interpolation for contours
contours = find_contours(p, 0.5) # note: skimage use subpixel interpolation for contours
contours = [np.round(contour).astype(int) for contour in contours]

for contour in contours:
if not np.array_equal(contour[0], contour[-1]):
contour = np.append(contour, [contour[0]], axis=0)

Check warning on line 232 in monailabel/transform/post.py

View check run for this annotation

Codecov / codecov/patch

monailabel/transform/post.py#L232

Added line #L232 was not covered by tests

simplified_contour = approximate_polygon(contour, tolerance=0.5) #loose the contour by tolerance
simplified_contour = approximate_polygon(contour, tolerance=0.5) # loose the contour by tolerance
if len(simplified_contour) < 4:
continue
continue

simplified_contour = np.flip(simplified_contour, axis=1)
simplified_contour += location
simplified_contour = simplified_contour.astype(int)

simplified_contour = np.flip(simplified_contour, axis=1)
simplified_contour += location
simplified_contour = simplified_contour.astype(int)

polygon = Polygon(simplified_contour)
if polygon.is_valid and polygon.area >= min_poly_area and (max_poly_area <= 0 or polygon.area <= max_poly_area):
if (
polygon.is_valid
and polygon.area >= min_poly_area
and (max_poly_area <= 0 or polygon.area <= max_poly_area)
):
formatted_contour = [simplified_contour.tolist()]
if foreground_points:
if any(polygon.contains(point) for point in foreground_points):
Expand All @@ -263,6 +266,7 @@ def __call__(self, data):
print(elements)
return d


class DumpImagePrediction2Dd(Transform):
def __init__(self, image_path, pred_path, pred_only=True):
self.image_path = image_path
Expand Down
5 changes: 1 addition & 4 deletions sample-apps/pathology/lib/trainers/hovernet_nuclei.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@
from lib.hovernet import PatchExtractor
from lib.utils import split_dataset
from PIL import Image
from scipy.ndimage import label
from tqdm import tqdm

from monailabel.interfaces.datastore import Datastore
from monailabel.tasks.train.bundle import BundleConstants, BundleTrainTask
from monailabel.utils.others.generic import remove_file

from scipy.ndimage import label
import numpy as np

logger = logging.getLogger(__name__)


Expand All @@ -38,7 +36,6 @@ def __init__(self, path: str, conf: Dict[str, str], const: Optional[BundleConsta
self.step_size = (164, 164)
self.extract_type = "mirror"


def remove_file(path):
if os.path.exists(path):
os.remove(path)
Expand Down
49 changes: 24 additions & 25 deletions sample-apps/pathology/lib/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,15 @@
import numpy as np
import openslide
import scipy
from PIL import Image
from PIL import Image, ImageDraw
from scipy.ndimage import center_of_mass, find_objects, label
from tqdm import tqdm

from monailabel.datastore.dsa import DSADatastore
from monailabel.datastore.local import LocalDatastore
from monailabel.interfaces.datastore import Datastore
from monailabel.utils.others.generic import get_basename, get_basename_no_ext, is_openslide_supported

import numpy as np
import os
from PIL import Image
from scipy.ndimage import label, find_objects, center_of_mass
import logging
from PIL import Image, ImageDraw
from math import ceil


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -462,6 +454,7 @@ def _process_item(
item["label"] = label_file
return item


def split_nuclei_dataset(
d,
output_dir,
Expand Down Expand Up @@ -496,7 +489,7 @@ def split_nuclei_dataset(
dx, dy = slice_tuple
area = (dx.stop - dx.start) * (dy.stop - dy.start)
stats.append([dy.start, dx.start, dy.stop - dy.start, dx.stop - dx.start, area])

logger.info("-------------------------------------------------------------------------------")
logger.info(f"Image/Label ========> {d['image']} =====> {d['label']}")
logger.info(f"Total Labels: {numLabels}")
Expand All @@ -506,10 +499,10 @@ def split_nuclei_dataset(
logger.info(f"Total Classes in Mask: {np.unique(mask_np)}")

for nuclei_id, centroid in enumerate(centroids):
if nuclei_id == 0:
if nuclei_id == 0:
continue

x, y = int(centroid[1]), int(centroid[0])
x, y = int(centroid[1]), int(centroid[0])

this_instance = np.where(instances == nuclei_id, mask_np, 0)
class_id = int(np.max(this_instance))
Expand Down Expand Up @@ -574,25 +567,28 @@ def _group_item(groups, d, output_dir):
os.makedirs(output_dir, exist_ok=True)
return groups, item_id


def calculate_bounding_rect(points):
points = np.array(points, dtype=int)
points = np.array(points, dtype=int)
x_min, y_min = np.min(points, axis=0)
x_max, y_max = np.max(points, axis=0)
w = x_max - x_min + 1
h = y_max - y_min + 1
w = x_max - x_min + 1
h = y_max - y_min + 1
return int(x_min), int(y_min), int(w), int(h)

def fill_poly(image_size, polygons, color, mode='L'):
if mode.upper() == 'RGB':
img = Image.new('RGB', image_size, (0, 0, 0))

def fill_poly(image_size, polygons, color, mode="L"):
if mode.upper() == "RGB":
img = Image.new("RGB", image_size, (0, 0, 0))
else:
img = Image.new('L', image_size, 0)
img = Image.new("L", image_size, 0)

draw = ImageDraw.Draw(img)
for polygon in polygons:
draw.polygon([tuple(p) for p in polygon], fill=color)
return np.array(img)


def _to_roi(points, max_region, polygons, annotation_id):
logger.info(f"Total Points: {len(points)}")
x, y, w, h = calculate_bounding_rect(points)
Expand All @@ -606,6 +602,7 @@ def _to_roi(points, max_region, polygons, annotation_id):
h = max_region[1]
return x, y, w, h


def _to_dataset(item_id, x, y, w, h, img, tile_size, polygons, groups, output_dir, debug=False):
dataset_json = []

Expand All @@ -623,16 +620,16 @@ def _to_dataset(item_id, x, y, w, h, img, tile_size, polygons, groups, output_di
# Create a new blank image for labels
label_img = Image.new("L", (w, h), 0)
draw = ImageDraw.Draw(label_img)

for group, contours in polygons.items():
color = groups.get(group, 1)
# Convert contours to PIL.ImageDraw polygon format and offset them
pil_contours = [tuple((p[0] - x, p[1] - y) for p in contour) for contour in contours]

# Draw each polygon onto the label image
for contour in pil_contours:
draw.polygon(contour, outline=color, fill=color)

if debug:
regions_dir = os.path.join(output_dir, "regions")
label_path = os.path.realpath(os.path.join(regions_dir, "labels", group, f"{name}.png"))
Expand All @@ -641,8 +638,10 @@ def _to_dataset(item_id, x, y, w, h, img, tile_size, polygons, groups, output_di

# Convert label image to numpy array for tiling
label_np = np.array(label_img)
tiled_labels = _region_to_tiles(name, w, h, label_np, tile_size, os.path.join(output_dir, "labels", "final"), "Label")

tiled_labels = _region_to_tiles(
name, w, h, label_np, tile_size, os.path.join(output_dir, "labels", "final"), "Label"
)

for k in tiled_images:
dataset_json.append({"image": tiled_images[k], "label": tiled_labels[k]})

Expand Down

0 comments on commit b2f5197

Please sign in to comment.