Source code for luna.pathology.cli.dsa.utils

from random import randint

import numpy as np
from skimage import measure
import seaborn as sns


[docs]def get_color(name, line_colors={}, fill_colors={}, alpha = 100): """Get colors for cells/regions based on discrete categories. Args: name (string): feature name e.g. Stroma, Tumor line_colors (dict, optional): line color map with {feature name:rgb values} fill_colors (dict, optional): fill color map with {feature name:rgba values} alpha (int, optional): alpha value for the fill color. 100 by default Returns: string: RGBA values for line and fill colors """ if name not in line_colors and name not in fill_colors: r = randint(0, 255) g = randint(0, 255) b = randint(0, 255) fill_colors[name] = "rgba({}, {}, {}, {})".format(r,g,b, alpha) line_colors[name] = "rgb({}, {}, {})".format(r,g,b) return line_colors[name], fill_colors[name]
[docs]def get_continuous_color(value, outline_color='same_as_fill', alpha = 100): """Get RGBA line and fill colors for value. Use color palette `viridis` to set a fill value - the color ranges from purple to yellow, for the values from 0 to 1. This function is used in generating a heatmap. Args: value (float): continuous value in [0,1] outline_color (string, optional): manages the color used to outline the border of the annotation. by default, uses the same color as fill_color. alpha (int, optional): alpha value for the fill color. 100 by default Returns: string: RGBA line and fill colors """ c = sns.color_palette("viridis", as_cmap=True) r,g,b,a = c(value, bytes=True) fill_color = "rgba({}, {}, {}, {})".format(r,g,b,alpha) if outline_color == 'same_as_fill': line_color = "rgb({}, {}, {})".format(r,g,b) elif outline_color == 'black': line_color = "rgb({}, {}, {})".format(0,0,0) elif outline_color == 'white': line_color = "rgb({}, {}, {})".format(255,255,255) else: return None,None return line_color, fill_color
[docs]def vectorize_np_array_bitmask_by_pixel_value(bitmask_np, label_num = 255, polygon_tolerance = 1, contour_level = .5): """Get simplified contours from the bitmask Args: bitmask_np (np.array): a numpy bitmask label_num (int, optional): numeric value to filter the numpy array polygon_tolerance (float, optional): Maximum distance from original points of polygon to approximated polygonal chain. If tolerance is 0, the original coordinate array is returned. contour_level (float, optional): Value along which to find contours in the array. 0.5 by default Returns: list: simplified approximated contours """ mask = np.where(bitmask_np==label_num,1,0).astype(np.int8) contours = measure.find_contours(mask, level = contour_level) simplified_contours = [measure.approximate_polygon(c, tolerance=polygon_tolerance) for c in contours] for _, contour in enumerate(simplified_contours): for coord in contour: x = int(round(coord[0])) y = int(round(coord[1])) # switch coordinates, otherwise gets flipped coord[0] = y coord[1] = x return simplified_contours