Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions src/histolab/tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,25 +153,23 @@ def tissue_ratio(self) -> float:

# ------- implementation helpers -------

def _has_only_some_tissue(self, near_zero_var_threshold: float = 0.1) -> np.bool_:
def _has_only_some_tissue(self, min_var: float = 150.0) -> np.bool_:
"""Check if the tile is composed by only some tissue.

Parameters
----------
near_zero_var_threshold : float, optional
Minimum image variance after morphological operations (dilation, fill holes)
to consider the image to be composed by only some tissue, default is 0.1
min_var : float, optional
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now the docstring is not correct because it refers to the old filters that were applied

Minimum image variance to consider the image to be composed by only some
tissue, default is 150.

Returns
-------
bool
True if the image is composed by only some tissue. False if the tile is
composed by all tissue or by no tissue at all.
"""
filters = FiltersComposition(Tile).tissue_mask_filters
tissue_mask = filters(self._image)

return np.var(tissue_mask) > near_zero_var_threshold
np_img = np.array(self._image.convert("L"))
return np.var(np_img) > min_var

def _has_tissue_more_than_percent(self, tissue_percent: float = 80.0) -> bool:
"""Check if tissue represent more than ``tissue_percent`` % of the image.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions tests/integration/test_tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,17 @@ def it_knows_if_is_is_almost_white(self, tile_img, expected_result):
is_almost_white = tile._is_almost_white

assert is_almost_white == expected_result

@pytest.mark.parametrize(
"tile_image, expected_value",
(
(TILES.LIVER_LEVEl2_10907_7808_11707_8608, False), # all tissue
(TILES.LIVER_LEVEl2_20914_13715_21714_14515, True), # some tissue
(TILES.LIVER_LEVEl2_57138_8209_57938_9009, True), # some tissue
(TILES.LIVER_LEVEl2_38626_13514_39426_14315, False), # no tissue
),
)
def it_knows_if_it_has_only_some_tissue(self, tile_image, expected_value):
tile = Tile(tile_image, CP(5, 5, 5, 5))

assert tile._has_only_some_tissue() == expected_value
78 changes: 54 additions & 24 deletions tests/integration/test_tiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,37 @@

class DescribeRandomTiler:
@pytest.mark.parametrize(
"fixture_slide, expectation",
"fixture_slide, check_tissue, expectation",
[
(
SVS.CMU_1_SMALL_REGION,
"tiles-location-images/cmu-1-small-region-tiles-location-random",
False,
"tiles-location-images/cmu-1-small-region-tl-random-false",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tiles-location-random",
False,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-random-false",
),
(
SVS.CMU_1_SMALL_REGION,
True,
"tiles-location-images/cmu-1-small-region-tl-random-true",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
True,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-random-true",
),
],
)
def it_locates_tiles_on_the_slide(
self, request, fixture_slide, expectation, tmpdir
self, request, fixture_slide, check_tissue, expectation, tmpdir
):
slide = Slide(fixture_slide, os.path.join(tmpdir, "processed"))
slide.save_scaled_image(10)
random_tiles_extractor = RandomTiler(
tile_size=(512, 512), n_tiles=2, level=0, seed=42, check_tissue=False
tile_size=(512, 512), n_tiles=2, level=0, seed=42, check_tissue=check_tissue
)
expected_img = load_expectation(
expectation,
Expand All @@ -43,68 +55,88 @@ def it_locates_tiles_on_the_slide(
# --- Expanding test report with actual and expected images ---
expand_tests_report(request, actual=tiles_location_img, expected=expected_img)

np.testing.assert_array_almost_equal(
np.asarray(tiles_location_img), expected_img
)
np.testing.assert_array_almost_equal(tiles_location_img, expected_img)


class DescribeGridTiler:
@pytest.mark.parametrize(
"fixture_slide, expectation",
"fixture_slide, check_tissue, expectation",
[
(
SVS.CMU_1_SMALL_REGION,
"tiles-location-images/cmu-1-small-region-tiles-location-grid",
False,
"tiles-location-images/cmu-1-small-region-tl-grid-false",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tiles-location-grid",
False,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-grid-false",
),
(
SVS.CMU_1_SMALL_REGION,
True,
"tiles-location-images/cmu-1-small-region-tl-grid-true",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
True,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-grid-true",
),
],
)
def it_locates_tiles_on_the_slide(
self, request, fixture_slide, expectation, tmpdir
self, request, fixture_slide, check_tissue, expectation, tmpdir
):
slide = Slide(fixture_slide, os.path.join(tmpdir, "processed"))
grid_tiles_extractor = GridTiler(
tile_size=(512, 512),
level=0,
check_tissue=False,
check_tissue=check_tissue,
)
expected_img = load_expectation(expectation, type_="png")
tiles_location_img = grid_tiles_extractor.locate_tiles(slide, scale_factor=10)
# --- Expanding test report with actual and expected images ---
expand_tests_report(request, expected=expected_img, actual=tiles_location_img)

np.testing.assert_array_almost_equal(
np.asarray(tiles_location_img), expected_img
)
np.testing.assert_array_almost_equal(tiles_location_img, expected_img)


class DescribeScoreTiler:
@pytest.mark.parametrize(
"fixture_slide, expectation",
"fixture_slide, check_tissue, expectation",
[
(
SVS.CMU_1_SMALL_REGION,
"tiles-location-images/cmu-1-small-region-tiles-location-scored",
False,
"tiles-location-images/cmu-1-small-region-tl-scored-false",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
False,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-scored-false",
),
(
SVS.CMU_1_SMALL_REGION,
True,
"tiles-location-images/cmu-1-small-region-tl-scored-true",
),
(
SVS.TCGA_CR_7395_01A_01_TS1,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tiles-location-scored",
True,
"tiles-location-images/tcga-cr-7395-01a-01-ts1-tl-scored-true",
),
],
)
def it_locates_tiles_on_the_slide(
self, request, fixture_slide, expectation, tmpdir
self, request, fixture_slide, check_tissue, expectation, tmpdir
):
slide = Slide(fixture_slide, os.path.join(tmpdir, "processed"))
scored_tiles_extractor = ScoreTiler(
scorer=NucleiScorer(),
tile_size=(512, 512),
n_tiles=2,
level=0,
check_tissue=True,
check_tissue=check_tissue,
)
expected_img = load_expectation(
expectation,
Expand All @@ -114,6 +146,4 @@ def it_locates_tiles_on_the_slide(
# --- Expanding test report with actual and expected images ---
expand_tests_report(request, expected=expected_img, actual=tiles_location_img)

np.testing.assert_array_almost_equal(
np.asarray(tiles_location_img), expected_img
)
np.testing.assert_array_almost_equal(tiles_location_img, expected_img)
18 changes: 4 additions & 14 deletions tests/unit/test_tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from histolab.filters.compositions import _TileFiltersComposition
from histolab.filters.image_filters import Compose
from histolab.tile import Tile
from histolab.types import CoordinatePair
from histolab.types import CP

from ..base import COMPLEX_MASK
from ..unitutil import (
Expand All @@ -24,7 +24,7 @@ def it_constructs_from_args(self, request):
_init = initializer_mock(request, Tile)
_image = PILIMG.RGBA_COLOR_50X50_155_0_0
_level = 0
_coords = CoordinatePair(0, 0, 50, 50)
_coords = CP(0, 0, 50, 50)

tile = Tile(_image, _coords, _level)

Expand All @@ -35,14 +35,14 @@ def but_it_has_wrong_image_type(self):
"""This test simulates a wrong user behaviour, using a None object instead of a
PIL Image for image param"""
with pytest.raises(AttributeError) as err:
tile = Tile(None, CoordinatePair(0, 0, 50, 50), 0)
tile = Tile(None, CP(0, 0, 50, 50), 0)
tile.has_enough_tissue()

assert isinstance(err.value, AttributeError)
assert str(err.value) == "'NoneType' object has no attribute 'convert'"

def it_knows_its_coords(self):
_coords = CoordinatePair(0, 0, 50, 50)
_coords = CP(0, 0, 50, 50)
tile = Tile(None, _coords, 0)

coords = tile.coords
Expand Down Expand Up @@ -144,30 +144,20 @@ def it_knows_if_has_tissue_more_than_percent(

def it_calls_tile_tissue_mask_filters(
self,
request,
RgbToGrayscale_,
OtsuThreshold_,
BinaryDilation_,
BinaryFillHoles_,
):
_tissue_mask_filters = property_mock(
request, _TileFiltersComposition, "tissue_mask_filters"
)
BinaryFillHoles_.return_value = np.zeros((50, 50))
_tissue_mask_filters.return_value = Compose(
[RgbToGrayscale_, OtsuThreshold_, BinaryDilation_, BinaryFillHoles_]
)
image = PILIMG.RGBA_COLOR_50X50_155_0_0
tile = Tile(image, None, 0)

tile._has_only_some_tissue()

_tissue_mask_filters.assert_called_once()
assert type(tile._has_only_some_tissue()) == np.bool_

def it_knows_its_tissue_mask(
self,
request,
RgbToGrayscale_,
OtsuThreshold_,
BinaryDilation_,
Expand Down