Mercurial > repos > imgteam > overlay_images
comparison contours.py @ 2:b74693340624 draft
planemo upload for repository https://github.com/BMCV/galaxy-image-analysis/tree/master/tools/overlay_images/ commit 71dae1df58f579b84d4f9d92fb0dd509c02dd48f
author | imgteam |
---|---|
date | Thu, 10 Aug 2023 07:29:34 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:bf590a9733ed | 2:b74693340624 |
---|---|
1 """ | |
2 Copyright (c) 2017-2023 Leonid Kostrykin, Biomedical Computer Vision Group, Heidelberg University. | |
3 | |
4 Distributed under the MIT license. | |
5 See file LICENSE for detail or copy at https://opensource.org/licenses/MIT | |
6 """ | |
7 | |
8 import numpy as np | |
9 import skimage.morphology as morph | |
10 | |
11 | |
12 class ContourPaint: | |
13 """Yields masks corresponding to contours of objects. | |
14 | |
15 :param fg_mask: Binary mask of the image foreground. Any contour never overlaps the image foreground except of those image regions corresponding to the contoured object itself. | |
16 :param thickness: The thickness of the contour (width, in pixels). | |
17 :param where: The position of the contour (``inner``, ``center``, or ``outer``). | |
18 """ | |
19 | |
20 def __init__(self, fg_mask, thickness, where='center'): | |
21 assert where in ('inner', 'center', 'outer') | |
22 self.fg_mask = fg_mask | |
23 self.where = where | |
24 self.thickness = thickness | |
25 if where == 'inner': | |
26 self.selem_inner = morph.disk(self.thickness) | |
27 self.selem_outer = None | |
28 elif where == 'center': | |
29 self.selem_inner = morph.disk(self.thickness - self.thickness // 2) | |
30 self.selem_outer = morph.disk(self.thickness // 2) | |
31 elif where == 'outer': | |
32 self.selem_inner = None | |
33 self.selem_outer = morph.disk(self.thickness) | |
34 | |
35 def get_contour_mask(self, mask): | |
36 """Returns the binary mask of the contour of an object. | |
37 | |
38 :param mask: Binary mask of an object. | |
39 :return: Binary mask of the contour | |
40 """ | |
41 if self.selem_inner is not None: | |
42 inner_contour = np.logical_xor(mask, morph.binary_erosion(mask, self.selem_inner)) | |
43 else: | |
44 inner_contour = np.zeros(mask.shape, bool) | |
45 if self.selem_outer is not None: | |
46 outer_contour = np.logical_and(np.logical_not(self.fg_mask), morph.binary_dilation(mask, self.selem_outer)) | |
47 else: | |
48 outer_contour = np.zeros(mask.shape, bool) | |
49 return np.logical_or(inner_contour, outer_contour) |