[7823dd]: / pathaia / patches / visu.py

Download this file

70 lines (63 with data), 2.4 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# coding: utf8
"""Useful functions for visualizing patches in WSIs."""
import numpy
from skimage.morphology import binary_dilation, disk
import openslide
from typing import Sequence, Tuple, Optional
from ..util.types import NDByteImage, Patch, Coord
def preview_from_queries(
slide: openslide.OpenSlide,
queries: Sequence[Patch],
min_res: int = 512,
color: Tuple[int, int, int] = (255, 255, 0),
thickness: int = 2,
cell_size: int = 20,
size_0: Optional[Coord] = None,
) -> NDByteImage:
"""
Give thumbnail with patches displayed.
Args:
slide: openslide object
queries: patch objects to preview from
min_res: minimum size for the smallest side of the thumbnail (usually the width)
color: rgb color for patch boundaries
thickness: thickness of patch boundaries
cell_size: size of a cell representing a patch in the grid
psize: size of a patch at level 0
Returns:
Thumbnail image with patches displayed.
"""
# get thumbnail first
slide_size = Coord(slide.dimensions)
if size_0 is None:
size_0 = Coord(queries[0].size_0) if len(queries) != 0 else Coord(min_res)
thickness = 2 * (thickness // 2) + 1
res = slide_size / size_0 * (thickness + cell_size) + thickness
thumb_w = max(min_res, res.x)
thumb_h = max(min_res, res.y)
image = slide.get_thumbnail((thumb_w, thumb_h))
thumb_size = Coord(image.size)
dsr_x = slide_size[0] / thumb_size[0]
dsr_y = slide_size[1] / thumb_size[1]
image = numpy.array(image)[:, :, 0:3]
# get grid
grid = numpy.zeros((thumb_size.y, thumb_size.x), numpy.uint8)
for query in queries:
# position in queries are absolute
x, y = round(query.position[0] / dsr_x), round(query.position[1] / dsr_y)
dx, dy = round(query.size_0[0] / dsr_x), round(query.size_0[1] / dsr_y)
#? startx = numpy.clip(x, 0, thumb_size.x - 1)
startx = min(x, thumb_size.x - 1)
starty = min(y, thumb_size.y - 1)
endx = min(x + dx, thumb_size.x - 1)
endy = min(y + dy, thumb_size.y - 1)
# horizontal segments
grid[starty, startx:endx] = 1
grid[endy - 1, startx:endx] = 1
# vertical segments
grid[starty:endy, startx] = 1
grid[starty:endy, endx - 1] = 1
d = disk(thickness//2)
grid = binary_dilation(grid, d)
image[grid] = color
return image