Skip to content

Commit

Permalink
Merge 84ae90e into b6f9fe8
Browse files Browse the repository at this point in the history
  • Loading branch information
alessiamarcolini committed Sep 22, 2020
2 parents b6f9fe8 + 84ae90e commit 92178a5
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/histolab/filters/image_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,43 @@ def __repr__(self) -> str:
return self.__class__.__name__ + "()"


class RgbToLab:
"""Convert from the sRGB color space to the CIE Lab colorspace.
sRGB color space reference: IEC 61966-2-1:1999
Parameters
----------
img : PIL.Image.Image
Input image
illuminant : {“A”, “D50”, “D55”, “D65”, “D75”, “E”}, optional
The name of the illuminant (the function is NOT case sensitive).
observer : {“2”, “10”}, optional
The aperture angle of the observer.
Returns
-------
PIL.Image.Image
Image in LAB space
Raises
------
Exception
If the image mode is not RGB
"""

def __init__(self, illuminant: str = "D65", observer: int = "2") -> None:
self.illuminant = illuminant
self.observer = observer

def __call__(self, img: PIL.Image.Image) -> PIL.Image.Image:
lab = F.rgb_to_lab(img)
return lab

def __repr__(self) -> str:
return self.__class__.__name__ + "()"


class HematoxylinChannel:
"""Obtain Hematoxylin channel from RGB image.
Expand Down
39 changes: 39 additions & 0 deletions src/histolab/filters/image_filters_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,11 @@ def rgb_to_hsv(img: PIL.Image.Image) -> PIL.Image.Image:
-------
PIL.Image.Image
Image in HED space
Raises
------
Exception
If the image mode is not RGB
"""
if img.mode != "RGB":
raise Exception("Input image must be RGB")
Expand All @@ -477,6 +482,40 @@ def rgb_to_hsv(img: PIL.Image.Image) -> PIL.Image.Image:
return hsv


def rgb_to_lab(
img: PIL.Image.Image, illuminant: str = "D65", observer: int = "2"
) -> PIL.Image.Image:
"""Convert from the sRGB color space to the CIE Lab colorspace.
sRGB color space reference: IEC 61966-2-1:1999
Parameters
----------
img : PIL.Image.Image
Input image
illuminant : {“A”, “D50”, “D55”, “D65”, “D75”, “E”}, optional
The name of the illuminant (the function is NOT case sensitive).
observer : {“2”, “10”}, optional
The aperture angle of the observer.
Returns
-------
PIL.Image.Image
Image in LAB space
Raises
------
Exception
If the image mode is not RGB
"""
if img.mode != "RGB":
raise Exception("Input image must be RGB")
img_arr = np.array(img)
lab_arr = sk_color.rgb2lab(img_arr)
lab = np_to_pil(lab_arr)
return lab


def stretch_contrast(
img: PIL.Image.Image, low: int = 40, high: int = 60
) -> PIL.Image.Image:
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions tests/integration/test_image_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1650,3 +1650,40 @@ def test_yen_threshold_filter_on_gs_image():
yen_threshold_mask = imf.yen_threshold(gs_img)

np.testing.assert_array_equal(yen_threshold_mask, expected_value)


@pytest.mark.parametrize(
"pil_image, expected_image",
(
(
RGB.DIAGNOSTIC_SLIDE_THUMB_RGB,
"pil-images-rgb/diagnostic-slide-thumb-rgb-to-lab",
),
(
RGB.DIAGNOSTIC_SLIDE_THUMB_HSV,
"pil-images-rgb/diagnostic-slide-thumb-hsv-rgb-to-lab",
),
(
RGB.DIAGNOSTIC_SLIDE_THUMB_YCBCR,
"pil-images-rgb/diagnostic-slide-thumb-ycbcr-rgb-to-lab",
),
),
)
def test_rgb_to_lab_filter_with_rgb_image(pil_image, expected_image):
expected_value = load_expectation(expected_image, type_="png")

lab_img = imf.rgb_to_lab(pil_image)

np.testing.assert_array_almost_equal(np.array(lab_img), np.array(expected_value))
assert np.unique(np.array(ImageChops.difference(lab_img, expected_value)))[0] == 0


@pytest.mark.parametrize(
"pil_image", (RGBA.DIAGNOSTIC_SLIDE_THUMB, GS.DIAGNOSTIC_SLIDE_THUMB_GS),
)
def test_rgb_to_lab_raises_exception_on_gs_and_rgba_image(pil_image):
with pytest.raises(Exception) as err:
imf.rgb_to_lab(pil_image)

assert isinstance(err.value, Exception)
assert str(err.value) == "Input image must be RGB"
14 changes: 14 additions & 0 deletions tests/unit/filters/test_image_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import numpy as np
import PIL

from histolab.filters import image_filters as imf

from ...unitutil import PILIMG, NpArrayMock, function_mock
Expand Down Expand Up @@ -407,3 +408,16 @@ def it_calls_yen_threshold(self, request):

F_yen_threshold.assert_called_once_with(image, operator.lt)
assert type(yen_threshold(image)) == np.ndarray

def it_calls_rgb_to_lab_functional(self, request):
image = PILIMG.RGBA_COLOR_500X500_155_249_240
F_rgb_to_lab = function_mock(
request, "histolab.filters.image_filters_functional.rgb_to_lab"
)
F_rgb_to_lab.return_value = image
rgb_to_lab = imf.RgbToLab()

rgb_to_lab(image)

F_rgb_to_lab.assert_called_once_with(image)
assert type(rgb_to_lab(image)) == PIL.Image.Image

0 comments on commit 92178a5

Please sign in to comment.