From 181a6d797caec35cbf826607796d19af1d8bbcd7 Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Sun, 21 Apr 2024 22:44:23 +1200 Subject: [PATCH 1/7] Rename `colour.io.ImageAttribute_Specification` attribute to `Image_Specification_Attribute`. --- colour/io/__init__.py | 48 +++++++++++- colour/io/image.py | 137 ++++++++++++++++++++++++---------- colour/io/tests/test_image.py | 41 +++++++++- docs/colour.io.rst | 2 +- 4 files changed, 181 insertions(+), 47 deletions(-) diff --git a/colour/io/__init__.py b/colour/io/__init__.py index e98a5be1ac..0c7e71d616 100644 --- a/colour/io/__init__.py +++ b/colour/io/__init__.py @@ -1,6 +1,17 @@ +import sys + +from colour.utilities.deprecation import ModuleAPI, build_API_changes +from colour.utilities.documentation import is_documentation_building + +from colour.hints import Any + from .luts import * # noqa: F403 from . import luts -from .image import ImageAttribute_Specification, convert_bit_depth +from .image import ( + Image_Specification_Attribute, + image_specification_OpenImageIO, + convert_bit_depth, +) from .image import read_image_OpenImageIO, write_image_OpenImageIO from .image import read_image_Imageio, write_image_Imageio from .image import READ_IMAGE_METHODS, WRITE_IMAGE_METHODS @@ -28,7 +39,8 @@ __all__ = [] __all__ += luts.__all__ __all__ += [ - "ImageAttribute_Specification", + "Image_Specification_Attribute", + "image_specification_OpenImageIO", "convert_bit_depth", ] __all__ += [ @@ -75,3 +87,35 @@ __all__ += [ "read_sds_from_xrite_file", ] + + +# ----------------------------------------------------------------------------# +# --- API Changes and Deprecation Management ---# +# ----------------------------------------------------------------------------# +class io(ModuleAPI): + """Define a class acting like the *io* module.""" + + def __getattr__(self, attribute) -> Any: + """Return the value from the attribute with given name.""" + + return super().__getattr__(attribute) + + +# v0.4.5 +API_CHANGES = { + "ObjectRenamed": [ + [ + "colour.io.ImageAttribute_Specification", + "colour.io.Image_Specification_Attribute", + ], + ] +} + +"""Defines the *colour.io* sub-package API changes.""" + +if not is_documentation_building(): + sys.modules["colour.io"] = io( # pyright: ignore + sys.modules["colour.io"], build_API_changes(API_CHANGES) + ) + + del ModuleAPI, is_documentation_building, build_API_changes, sys diff --git a/colour/io/image.py b/colour/io/image.py index fb69ff8ae3..b52b71ce6c 100644 --- a/colour/io/image.py +++ b/colour/io/image.py @@ -48,8 +48,9 @@ __status__ = "Production" __all__ = [ - "BitDepth_Specification", - "ImageAttribute_Specification", + "Image_Specification_BitDepth", + "Image_Specification_Attribute", + "image_specification_OpenImageIO", "convert_bit_depth", "read_image_OpenImageIO", "read_image_Imageio", @@ -64,7 +65,7 @@ @dataclass(frozen=True) -class BitDepth_Specification: +class Image_Specification_BitDepth: """ Define a bit-depth specification. @@ -84,7 +85,7 @@ class BitDepth_Specification: @dataclass -class ImageAttribute_Specification: +class Image_Specification_Attribute: """ Define an image specification attribute. @@ -112,33 +113,101 @@ class ImageAttribute_Specification: MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { - "uint8": BitDepth_Specification("uint8", np.uint8, UINT8), - "uint16": BitDepth_Specification("uint16", np.uint16, UINT16), - "float16": BitDepth_Specification("float16", np.float16, HALF), - "float32": BitDepth_Specification("float32", np.float32, FLOAT), - "float64": BitDepth_Specification("float64", np.float64, DOUBLE), + "uint8": Image_Specification_BitDepth("uint8", np.uint8, UINT8), + "uint16": Image_Specification_BitDepth("uint16", np.uint16, UINT16), + "float16": Image_Specification_BitDepth("float16", np.float16, HALF), + "float32": Image_Specification_BitDepth("float32", np.float32, FLOAT), + "float64": Image_Specification_BitDepth("float64", np.float64, DOUBLE), } ) if not TYPE_CHECKING and hasattr(np, "float128"): # pragma: no cover - MAPPING_BIT_DEPTH["float128"] = BitDepth_Specification( + MAPPING_BIT_DEPTH["float128"] = Image_Specification_BitDepth( "float128", np.float128, DOUBLE ) else: # pragma: no cover MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { - "uint8": BitDepth_Specification("uint8", np.uint8, None), - "uint16": BitDepth_Specification("uint16", np.uint16, None), - "float16": BitDepth_Specification("float16", np.float16, None), - "float32": BitDepth_Specification("float32", np.float32, None), - "float64": BitDepth_Specification("float64", np.float64, None), + "uint8": Image_Specification_BitDepth("uint8", np.uint8, None), + "uint16": Image_Specification_BitDepth("uint16", np.uint16, None), + "float16": Image_Specification_BitDepth("float16", np.float16, None), + "float32": Image_Specification_BitDepth("float32", np.float32, None), + "float64": Image_Specification_BitDepth("float64", np.float64, None), } ) if not TYPE_CHECKING and hasattr(np, "float128"): # pragma: no cover - MAPPING_BIT_DEPTH["float128"] = BitDepth_Specification( + MAPPING_BIT_DEPTH["float128"] = Image_Specification_BitDepth( "float128", np.float128, None ) +@required("OpenImageIO") +def image_specification_OpenImageIO( + width: int, + height: int, + channels: int, + bit_depth: Literal[ + "uint8", "uint16", "float16", "float32", "float64", "float128" + ] = "float32", + attributes: Sequence | None = None, +): + """ + Create an *OpenImageIO*. image specification. + + Parameters + ---------- + width + Image width. + height + Image height. + channels + Image channel count. + bit_depth + Bit-depth to create the image with, the bit-depth conversion behaviour is + ruled directly by *OpenImageIO*. + attributes + An array of :class:`colour.io.Image_Specification_Attribute` class + instances used to set attributes of the image. + + Returns + ------- + :class:`ImageSpec` + *OpenImageIO*. image specification. + + Examples + -------- + >>> compression = Image_Specification_Attribute("Compression", "none") + >>> image_specification_OpenImageIO( + ... 1920, 1080, 3, "float16", [compression] + ... ) # doctest: +SKIP + + """ # noqa: D405, D407, D410, D411 + + from OpenImageIO import ImageSpec + + attributes = cast(list, optional(attributes, [])) + + bit_depth_specification = MAPPING_BIT_DEPTH[bit_depth] + + image_specification = ImageSpec( + width, height, channels, bit_depth_specification.openimageio + ) + + for attribute in attributes: + name = str(attribute.name) + value = ( + str(attribute.value) + if isinstance(attribute.value, str) + else attribute.value + ) + type_ = attribute.type_ + if attribute.type_ is None: + image_specification.attribute(name, value) + else: + image_specification.attribute(name, type_, value) + + return image_specification + + def convert_bit_depth( a: ArrayLike, bit_depth: Literal[ @@ -241,7 +310,7 @@ def read_image_OpenImageIO( ------- :class`numpy.ndarray` or :class:`tuple` Image data or tuple of image data and list of - :class:`colour.io.ImageAttribute_Specification` class instances. + :class:`colour.io.Image_Specification_Attribute` class instances. Notes ----- @@ -286,7 +355,7 @@ def read_image_OpenImageIO( extra_attributes = [] for attribute in image_specification.extra_attribs: extra_attributes.append( - ImageAttribute_Specification( + Image_Specification_Attribute( attribute.name, attribute.value, attribute.type ) ) @@ -467,7 +536,7 @@ def write_image_OpenImageIO( Bit-depth to write the image at, the bit-depth conversion behaviour is ruled directly by *OpenImageIO*. attributes - An array of :class:`colour.io.ImageAttribute_Specification` class + An array of :class:`colour.io.Image_Specification_Attribute` class instances used to set attributes of the image. Returns @@ -501,7 +570,7 @@ def write_image_OpenImageIO( Advanced image writing while setting attributes: - >>> compression = ImageAttribute_Specification("Compression", "none") + >>> compression = Image_Specification_Attribute("Compression", "none") >>> write_image_OpenImageIO(image, path, "uint8", [compression]) ... # doctest: +SKIP True @@ -522,16 +591,16 @@ def write_image_OpenImageIO( ... 0.33767, ... ) ... attributes = [ - ... ImageAttribute_Specification("acesImageContainerFlag", True), - ... ImageAttribute_Specification( + ... Image_Specification_Attribute("acesImageContainerFlag", True), + ... Image_Specification_Attribute( ... "chromaticities", chromaticities, TypeDesc("float[8]") ... ), - ... ImageAttribute_Specification("compression", "none"), + ... Image_Specification_Attribute("compression", "none"), ... ] ... write_image_OpenImageIO(image, path, attributes=attributes) """ # noqa: D405, D407, D410, D411 - from OpenImageIO import ImageOutput, ImageSpec + from OpenImageIO import ImageOutput image = as_float_array(image) path = str(path) @@ -557,21 +626,9 @@ def write_image_OpenImageIO( else: height, width, channels = image.shape - image_specification = ImageSpec( - width, height, channels, bit_depth_specification.openimageio + image_specification = image_specification_OpenImageIO( + width, height, channels, bit_depth_specification.openimageio, attributes ) - for attribute in attributes: - name = str(attribute.name) - value = ( - str(attribute.value) - if isinstance(attribute.value, str) - else attribute.value - ) - type_ = attribute.type_ - if attribute.type_ is None: - image_specification.attribute(name, value) - else: - image_specification.attribute(name, type_, value) image_output = ImageOutput.create(path) @@ -705,7 +762,7 @@ def write_image( ---------------- attributes {:func:`colour.io.write_image_OpenImageIO`}, - An array of :class:`colour.io.ImageAttribute_Specification` class + An array of :class:`colour.io.Image_Specification_Attribute` class instances used to set attributes of the image. Returns @@ -751,7 +808,7 @@ def write_image( Advanced image writing while setting attributes using *OpenImageIO*: - >>> compression = ImageAttribute_Specification("Compression", "none") + >>> compression = Image_Specification_Attribute("Compression", "none") >>> write_image(image, path, bit_depth="uint8", attributes=[compression]) ... # doctest: +SKIP True diff --git a/colour/io/tests/test_image.py b/colour/io/tests/test_image.py index 2031a48f50..4a62d25f5a 100644 --- a/colour/io/tests/test_image.py +++ b/colour/io/tests/test_image.py @@ -12,9 +12,10 @@ from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import ( - ImageAttribute_Specification, + Image_Specification_Attribute, as_3_channels_image, convert_bit_depth, + image_specification_OpenImageIO, read_image, read_image_Imageio, read_image_OpenImageIO, @@ -33,17 +34,49 @@ __all__ = [ "ROOT_RESOURCES", + "TestImageSpecificationOpenImageIO", + "TestConvertBitDepth", "TestReadImageOpenImageIO", "TestWriteImageOpenImageIO", "TestReadImageImageio", "TestWriteImageImageio", "TestReadImage", "TestWriteImage", + "TestAs3ChannelsImage", ] ROOT_RESOURCES: str = os.path.join(os.path.dirname(__file__), "resources") +class TestImageSpecificationOpenImageIO: + """ + Define :func:`colour.io.image.image_specification_OpenImageIO` definition + unit tests methods. + """ + + def test_image_specification_OpenImageIO(self): # pragma: no cover + """ + Test :func:`colour.io.image.image_specification_OpenImageIO` + definition. + """ + + if not is_openimageio_installed(): + return + + from OpenImageIO import HALF + + compression = Image_Specification_Attribute("Compression", "none") + specification = image_specification_OpenImageIO( + 1920, 1080, 3, "float16", [compression] + ) + + assert specification.width == 1920 + assert specification.height == 1080 + assert specification.nchannels == 3 + assert specification.format == HALF + assert specification.extra_attribs[0].name == "Compression" + + class TestConvertBitDepth: """ Define :func:`colour.io.image.convert_bit_depth` definition unit tests @@ -367,11 +400,11 @@ def test_write_image_OpenImageIO(self): # pragma: no cover 0.33767, ) write_attributes = [ - ImageAttribute_Specification("acesImageContainerFlag", True), - ImageAttribute_Specification( + Image_Specification_Attribute("acesImageContainerFlag", True), + Image_Specification_Attribute( "chromaticities", chromaticities, TypeDesc("float[8]") ), - ImageAttribute_Specification("compression", "none"), + Image_Specification_Attribute("compression", "none"), ] write_image_OpenImageIO(image, target_image_path, attributes=write_attributes) image, read_attributes = read_image_OpenImageIO( diff --git a/docs/colour.io.rst b/docs/colour.io.rst index 333c7dd1d1..edf2f17e76 100644 --- a/docs/colour.io.rst +++ b/docs/colour.io.rst @@ -25,7 +25,7 @@ Image Data .. autosummary:: :toctree: generated/ - ImageAttribute_Specification + Image_Specification_Attribute convert_bit_depth read_image_OpenImageIO write_image_OpenImageIO From 45c77e83659e9237b514768d9c98b24b2cc3f4b0 Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Sun, 28 Apr 2024 10:06:32 +1200 Subject: [PATCH 2/7] Add `colour.io.image.add_attributes_to_image_specification_OpenImageIO` definition. --- colour/io/image.py | 71 +++++++++++++++++++++++++++++++++++----------- docs/colour.io.rst | 2 ++ 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/colour/io/image.py b/colour/io/image.py index b52b71ce6c..28da6afd6c 100644 --- a/colour/io/image.py +++ b/colour/io/image.py @@ -50,6 +50,8 @@ __all__ = [ "Image_Specification_BitDepth", "Image_Specification_Attribute", + "MAPPING_BIT_DEPTH", + "add_attributes_to_image_specification_OpenImageIO", "image_specification_OpenImageIO", "convert_bit_depth", "read_image_OpenImageIO", @@ -109,7 +111,7 @@ class Image_Specification_Attribute: if is_openimageio_installed(): # pragma: no cover - from OpenImageIO import DOUBLE, FLOAT, HALF, UINT8, UINT16 + from OpenImageIO import DOUBLE, FLOAT, HALF, UINT8, UINT16, ImageSpec MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { @@ -125,6 +127,7 @@ class Image_Specification_Attribute: "float128", np.float128, DOUBLE ) else: # pragma: no cover + ImageSpec = None MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { "uint8": Image_Specification_BitDepth("uint8", np.uint8, None), @@ -140,6 +143,53 @@ class Image_Specification_Attribute: ) +def add_attributes_to_image_specification_OpenImageIO( + image_specification: ImageSpec, attributes: Sequence | None = None +): + """ + Add given attributes to given *OpenImageIO* image specification. + + Parameters + ---------- + image_specification + *OpenImageIO* image specification. + attributes + An array of :class:`colour.io.Image_Specification_Attribute` class + instances used to set attributes of the image. + + Returns + ------- + :class:`ImageSpec` + *OpenImageIO*. image specification. + + Examples + -------- + >>> image_specification = image_specification_OpenImageIO( + ... 1920, 1080, 3, "float16" + ... ) # doctest: +SKIP + >>> compression = Image_Specification_Attribute("Compression", "none") + >>> image_specification = add_attributes_to_image_specification_OpenImageIO( + ... image_specification, [compression] + ... ) # doctest: +SKIP + >>> image_specification.extra_attribs[0].value # doctest: +SKIP + 'none' + """ # noqa: D405, D407, D410, D411 + for attribute in attributes: + name = str(attribute.name) + value = ( + str(attribute.value) + if isinstance(attribute.value, str) + else attribute.value + ) + type_ = attribute.type_ + if attribute.type_ is None: + image_specification.attribute(name, value) + else: + image_specification.attribute(name, type_, value) + + return image_specification + + @required("OpenImageIO") def image_specification_OpenImageIO( width: int, @@ -149,9 +199,9 @@ def image_specification_OpenImageIO( "uint8", "uint16", "float16", "float32", "float64", "float128" ] = "float32", attributes: Sequence | None = None, -): +) -> ImageSpec: """ - Create an *OpenImageIO*. image specification. + Create an *OpenImageIO* image specification. Parameters ---------- @@ -192,18 +242,7 @@ def image_specification_OpenImageIO( width, height, channels, bit_depth_specification.openimageio ) - for attribute in attributes: - name = str(attribute.name) - value = ( - str(attribute.value) - if isinstance(attribute.value, str) - else attribute.value - ) - type_ = attribute.type_ - if attribute.type_ is None: - image_specification.attribute(name, value) - else: - image_specification.attribute(name, type_, value) + add_attributes_to_image_specification_OpenImageIO(image_specification, attributes) return image_specification @@ -627,7 +666,7 @@ def write_image_OpenImageIO( height, width, channels = image.shape image_specification = image_specification_OpenImageIO( - width, height, channels, bit_depth_specification.openimageio, attributes + width, height, channels, bit_depth, attributes ) image_output = ImageOutput.create(path) diff --git a/docs/colour.io.rst b/docs/colour.io.rst index edf2f17e76..48bf939472 100644 --- a/docs/colour.io.rst +++ b/docs/colour.io.rst @@ -26,6 +26,8 @@ Image Data :toctree: generated/ Image_Specification_Attribute + MAPPING_BIT_DEPTH + image_specification_OpenImageIO convert_bit_depth read_image_OpenImageIO write_image_OpenImageIO From b323f2039e4241c581a29e6a3d7d651caece3d81 Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Sun, 28 Apr 2024 10:09:38 +1200 Subject: [PATCH 3/7] Update `colour.io.read_image_OpenImageIO` function signature. --- colour/io/image.py | 27 +++++++++++++++++++-------- colour/io/tests/test_image.py | 4 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/colour/io/image.py b/colour/io/image.py index 28da6afd6c..a81709cad1 100644 --- a/colour/io/image.py +++ b/colour/io/image.py @@ -39,6 +39,7 @@ usage_warning, validate_method, ) +from colour.utilities.deprecation import handle_arguments_deprecation __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -329,7 +330,8 @@ def read_image_OpenImageIO( bit_depth: Literal[ "uint8", "uint16", "float16", "float32", "float64", "float128" ] = "float32", - attributes: bool = False, + additional_data: bool = False, + **kwargs: Any, ) -> NDArrayReal | Tuple[NDArrayReal, list]: """ Read the image data at given path using *OpenImageIO*. @@ -342,8 +344,8 @@ def read_image_OpenImageIO( Returned image bit-depth, the bit-depth conversion behaviour is driven directly by *OpenImageIO*, this definition only converts to the relevant data type after reading. - attributes - Whether to return the image attributes. + additional_data + Whether to return additional data. Returns ------- @@ -367,12 +369,21 @@ def read_image_OpenImageIO( ... "CMS_Test_Pattern.exr", ... ) >>> image = read_image_OpenImageIO(path) # doctest: +SKIP - """ # noqa: D405, D407, D410, D411 + """ from OpenImageIO import ImageInput path = str(path) + kwargs = handle_arguments_deprecation( + { + "ArgumentRenamed": [["attributes", "additional_data"]], + }, + **kwargs, + ) + + additional_data = kwargs.get("additional_data", additional_data) + bit_depth_specification = MAPPING_BIT_DEPTH[bit_depth] image_input = ImageInput.open(path) @@ -390,7 +401,7 @@ def read_image_OpenImageIO( image = np.reshape(np.array(image, dtype=bit_depth_specification.numpy), shape) image = cast(NDArrayReal, np.squeeze(image)) - if attributes: + if additional_data: extra_attributes = [] for attribute in image_specification.extra_attribs: extra_attributes.append( @@ -501,9 +512,9 @@ def read_image( Other Parameters ---------------- - attributes + additional_data {:func:`colour.io.read_image_OpenImageIO`}, - Whether to return the image attributes. + Whether to return additional data. Returns ------- @@ -534,7 +545,7 @@ def read_image( (1267, 1274, 3) >>> image.dtype dtype('float32') - """ # noqa: D405, D407, D410, D411, D414 + """ method = validate_method(method, tuple(READ_IMAGE_METHODS)) diff --git a/colour/io/tests/test_image.py b/colour/io/tests/test_image.py index 4a62d25f5a..d47346585d 100644 --- a/colour/io/tests/test_image.py +++ b/colour/io/tests/test_image.py @@ -292,7 +292,7 @@ def test_read_image_OpenImageIO(self): # pragma: no cover image, attributes = read_image_OpenImageIO( os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr"), - attributes=True, + additional_data=True, ) assert image.shape == (1267, 1274, 3) assert attributes[0].name == "oiio:ColorSpace" @@ -408,7 +408,7 @@ def test_write_image_OpenImageIO(self): # pragma: no cover ] write_image_OpenImageIO(image, target_image_path, attributes=write_attributes) image, read_attributes = read_image_OpenImageIO( - target_image_path, attributes=True + target_image_path, additional_data=True ) for write_attribute in write_attributes: attribute_exists = False From 75aae4c9ceba2ba027eb26e3dc6e911aa2c663d0 Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Mon, 20 May 2024 18:11:55 +1200 Subject: [PATCH 4/7] Rename various variables in `colour.io.tests.test_image` module. --- colour/io/tests/test_image.py | 80 ++++++++++++++++------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/colour/io/tests/test_image.py b/colour/io/tests/test_image.py index d47346585d..5961f885d2 100644 --- a/colour/io/tests/test_image.py +++ b/colour/io/tests/test_image.py @@ -358,34 +358,32 @@ def test_write_image_OpenImageIO(self): # pragma: no cover from OpenImageIO import TypeDesc - image_path = os.path.join(self._temporary_directory, "8-bit.png") + path = os.path.join(self._temporary_directory, "8-bit.png") RGB = full((1, 1, 3), 255, np.uint8) - write_image_OpenImageIO(RGB, image_path, bit_depth="uint8") - image = read_image_OpenImageIO(image_path, bit_depth="uint8") + write_image_OpenImageIO(RGB, path, bit_depth="uint8") + image = read_image_OpenImageIO(path, bit_depth="uint8") np.testing.assert_equal(np.squeeze(RGB), image) - image_path = os.path.join(self._temporary_directory, "16-bit.png") + path = os.path.join(self._temporary_directory, "16-bit.png") RGB = full((1, 1, 3), 65535, np.uint16) - write_image_OpenImageIO(RGB, image_path, bit_depth="uint16") - image = read_image_OpenImageIO(image_path, bit_depth="uint16") + write_image_OpenImageIO(RGB, path, bit_depth="uint16") + image = read_image_OpenImageIO(path, bit_depth="uint16") np.testing.assert_equal(np.squeeze(RGB), image) - source_image_path = os.path.join(ROOT_RESOURCES, "Overflowing_Gradient.png") - target_image_path = os.path.join( + source_path = os.path.join(ROOT_RESOURCES, "Overflowing_Gradient.png") + target_path = os.path.join( self._temporary_directory, "Overflowing_Gradient.png" ) RGB = np.arange(0, 256, 1, dtype=np.uint8)[None] * 2 - write_image_OpenImageIO(RGB, target_image_path, bit_depth="uint8") - image = read_image_OpenImageIO(source_image_path, bit_depth="uint8") + write_image_OpenImageIO(RGB, target_path, bit_depth="uint8") + image = read_image_OpenImageIO(source_path, bit_depth="uint8") np.testing.assert_equal(np.squeeze(RGB), image) - source_image_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") - target_image_path = os.path.join( - self._temporary_directory, "CMS_Test_Pattern.exr" - ) - image = read_image_OpenImageIO(source_image_path) - write_image_OpenImageIO(image, target_image_path) - image = read_image_OpenImageIO(target_image_path) + source_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") + target_path = os.path.join(self._temporary_directory, "CMS_Test_Pattern.exr") + image = read_image_OpenImageIO(source_path) + write_image_OpenImageIO(image, target_path) + image = read_image_OpenImageIO(target_path) assert image.shape == (1267, 1274, 3) assert image.dtype is np.dtype("float32") @@ -406,9 +404,9 @@ def test_write_image_OpenImageIO(self): # pragma: no cover ), Image_Specification_Attribute("compression", "none"), ] - write_image_OpenImageIO(image, target_image_path, attributes=write_attributes) + write_image_OpenImageIO(image, target_path, attributes=write_attributes) image, read_attributes = read_image_OpenImageIO( - target_image_path, additional_data=True + target_path, additional_data=True ) for write_attribute in write_attributes: attribute_exists = False @@ -503,39 +501,35 @@ def teardown_method(self): def test_write_image_Imageio(self): """Test :func:`colour.io.image.write_image_Imageio` definition.""" - source_image_path = os.path.join(ROOT_RESOURCES, "Overflowing_Gradient.png") - target_image_path = os.path.join( + source_path = os.path.join(ROOT_RESOURCES, "Overflowing_Gradient.png") + target_path = os.path.join( self._temporary_directory, "Overflowing_Gradient.png" ) RGB = np.arange(0, 256, 1, dtype=np.uint8)[None] * 2 - write_image_Imageio(RGB, target_image_path, bit_depth="uint8") - image = read_image_Imageio(source_image_path, bit_depth="uint8") + write_image_Imageio(RGB, target_path, bit_depth="uint8") + image = read_image_Imageio(source_path, bit_depth="uint8") np.testing.assert_equal(np.squeeze(RGB), image) - source_image_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") - target_image_path = os.path.join( - self._temporary_directory, "CMS_Test_Pattern.exr" - ) - image = read_image_Imageio(source_image_path) - write_image_Imageio(image, target_image_path) - image = read_image_Imageio(target_image_path) + source_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") + target_path = os.path.join(self._temporary_directory, "CMS_Test_Pattern.exr") + image = read_image_Imageio(source_path) + write_image_Imageio(image, target_path) + image = read_image_Imageio(target_path) assert image.shape == (1267, 1274, 3) assert image.dtype is np.dtype("float32") # NOTE: Those unit tests are breaking unpredictably on Linux, skipping # for now. if platform.system() != "Linux": # pragma: no cover - target_image_path = os.path.join( - self._temporary_directory, "Full_White.exr" - ) + target_path = os.path.join(self._temporary_directory, "Full_White.exr") image = full((32, 16, 3), 1e6, dtype=np.float16) - write_image_Imageio(image, target_image_path) - image = read_image_Imageio(target_image_path) + write_image_Imageio(image, target_path) + image = read_image_Imageio(target_path) assert np.max(image) == np.inf image = full((32, 16, 3), 1e6) - write_image_Imageio(image, target_image_path) - image = read_image_Imageio(target_image_path) + write_image_Imageio(image, target_path) + image = read_image_Imageio(target_path) assert np.max(image) == 1e6 @@ -572,13 +566,11 @@ def teardown_method(self): def test_write_image(self): """Test :func:`colour.io.image.write_image` definition.""" - source_image_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") - target_image_path = os.path.join( - self._temporary_directory, "CMS_Test_Pattern.exr" - ) - image = read_image(source_image_path) - write_image(image, target_image_path) - image = read_image(target_image_path) + source_path = os.path.join(ROOT_RESOURCES, "CMS_Test_Pattern.exr") + target_path = os.path.join(self._temporary_directory, "CMS_Test_Pattern.exr") + image = read_image(source_path) + write_image(image, target_path) + image = read_image(target_path) assert image.shape == (1267, 1274, 3) assert image.dtype is np.dtype("float32") From 6bdafb58b485a836951d8cd25480256e939d10e9 Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Mon, 20 May 2024 07:52:54 +1200 Subject: [PATCH 5/7] Implement support for *Fichet et al. (2021)* *OpenEXR Layout for Spectral Images*. --- colour/__init__.py | 6 + colour/io/__init__.py | 18 + colour/io/fichet2021.py | 841 +++++++++++++++++++++++ colour/io/image.py | 12 +- colour/io/tests/resources/BiSpectral.exr | Bin 0 -> 69336 bytes colour/io/tests/resources/D65.exr | Bin 0 -> 39753 bytes colour/io/tests/resources/Ohta1997.exr | Bin 0 -> 38121 bytes colour/io/tests/resources/Polarised.exr | Bin 0 -> 124481 bytes colour/io/tests/test_fichet2021.py | 532 ++++++++++++++ colour/utilities/common.py | 11 +- colour/utilities/tests/test_common.py | 4 + docs/colour.io.rst | 35 +- 12 files changed, 1449 insertions(+), 10 deletions(-) create mode 100644 colour/io/fichet2021.py create mode 100644 colour/io/tests/resources/BiSpectral.exr create mode 100644 colour/io/tests/resources/D65.exr create mode 100644 colour/io/tests/resources/Ohta1997.exr create mode 100644 colour/io/tests/resources/Polarised.exr create mode 100644 colour/io/tests/test_fichet2021.py diff --git a/colour/__init__.py b/colour/__init__.py index 62c6abfdf7..94edfa6f40 100644 --- a/colour/__init__.py +++ b/colour/__init__.py @@ -254,6 +254,7 @@ LUT3x1D, LUTOperatorMatrix, LUTSequence, + Specification_Fichet2021, SpectralDistribution_IESTM2714, SpectralDistribution_Sekonic, SpectralDistribution_UPRTek, @@ -262,9 +263,11 @@ read_sds_from_csv_file, read_sds_from_xrite_file, read_spectral_data_from_csv_file, + read_spectral_image_Fichet2021, write_image, write_LUT, write_sds_to_csv_file, + write_spectral_image_Fichet2021, ) from .models import ( CCTF_DECODINGS, @@ -636,6 +639,7 @@ "LUT3D", "LUTOperatorMatrix", "LUTSequence", + "Specification_Fichet2021", "READ_IMAGE_METHODS", "SpectralDistribution_IESTM2714", "WRITE_IMAGE_METHODS", @@ -644,11 +648,13 @@ "read_sds_from_csv_file", "read_sds_from_xrite_file", "read_spectral_data_from_csv_file", + "read_spectral_image_Fichet2021", "SpectralDistribution_UPRTek", "SpectralDistribution_Sekonic", "write_image", "write_LUT", "write_sds_to_csv_file", + "write_spectral_image_Fichet2021", ] __all__ += [ "CAM02LCD_to_JMh_CIECAM02", diff --git a/colour/io/__init__.py b/colour/io/__init__.py index 0c7e71d616..ce26ff650c 100644 --- a/colour/io/__init__.py +++ b/colour/io/__init__.py @@ -9,6 +9,7 @@ from . import luts from .image import ( Image_Specification_Attribute, + MAPPING_BIT_DEPTH, image_specification_OpenImageIO, convert_bit_depth, ) @@ -17,6 +18,14 @@ from .image import READ_IMAGE_METHODS, WRITE_IMAGE_METHODS from .image import read_image, write_image from .image import as_3_channels_image +from .fichet2021 import ( + ComponentsFichet2021, + sd_to_spectrum_attribute_Fichet2021, + spectrum_attribute_to_sd_Fichet2021, + Specification_Fichet2021, + read_spectral_image_Fichet2021, + write_spectral_image_Fichet2021, +) from .ctl import ( ctl_render, process_image_ctl, @@ -40,6 +49,7 @@ __all__ += luts.__all__ __all__ += [ "Image_Specification_Attribute", + "MAPPING_BIT_DEPTH", "image_specification_OpenImageIO", "convert_bit_depth", ] @@ -68,6 +78,14 @@ __all__ += [ "as_3_channels_image", ] +__all__ += [ + "ComponentsFichet2021", + "sd_to_spectrum_attribute_Fichet2021", + "spectrum_attribute_to_sd_Fichet2021", + "Specification_Fichet2021", + "read_spectral_image_Fichet2021", + "write_spectral_image_Fichet2021", +] __all__ += [ "process_image_OpenColorIO", ] diff --git a/colour/io/fichet2021.py b/colour/io/fichet2021.py new file mode 100644 index 0000000000..615348b4a0 --- /dev/null +++ b/colour/io/fichet2021.py @@ -0,0 +1,841 @@ +""" +OpenEXR Layout for Spectral Images - Fichet, Pacanowski and Wilkie (2021) +========================================================================= + +Defines the *Fichet et al. (2021)* spectral image input / output objects. + +References +---------- +- :cite:`Fichet2021` : Fichet, A., Pacanowski, R., & Wilkie, A. (2021). An + OpenEXR Layout for Spectral Images. 10(3). Retrieved April 26, 2024, from + http://jcgt.org/published/0010/03/01/ +""" + +from __future__ import annotations + +import re +from collections import defaultdict +from dataclasses import dataclass, field +from pathlib import Path + +import numpy as np + +from colour.colorimetry import ( + MSDS_CMFS, + SDS_ILLUMINANTS, + MultiSpectralDistributions, + SpectralDistribution, + SpectralShape, + msds_to_XYZ, + sds_and_msds_to_msds, +) +from colour.constants import CONSTANT_LIGHT_SPEED +from colour.hints import ( + Callable, + Dict, + List, + Literal, + NDArrayFloat, + Sequence, + Tuple, + Union, +) +from colour.io.image import ( + MAPPING_BIT_DEPTH, + Image_Specification_Attribute, + add_attributes_to_image_specification_OpenImageIO, +) +from colour.models import RGB_COLOURSPACE_sRGB, XYZ_to_RGB +from colour.utilities import ( + as_float_array, + interval, + required, + usage_warning, + validate_method, +) + +__author__ = "Colour Developers" +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "MAPPING_UNIT_CONVERSION", + "PATTERN_FICHET2021", + "ComponentsFichet2021", + "match_groups_to_nm", + "sd_to_spectrum_attribute_Fichet2021", + "spectrum_attribute_to_sd_Fichet2021", + "Specification_Fichet2021", + "read_spectral_image_Fichet2021", + "sds_and_msds_to_components_Fichet2021", + "components_to_sRGB_Fichet2021", + "write_spectral_image_Fichet2021", +] + +MAPPING_UNIT_CONVERSION: dict = { + "Y": 1e24, + "Z": 1e21, + "E": 1e18, + "P": 1e15, + "T": 1e12, + "G": 1e9, + "M": 1e6, + "k": 1e3, + "h": 1e2, + "da": 1e1, + "": 1, + "d": 1e-1, + "c": 1e-2, + "m": 1e-3, + "u": 1e-6, + "n": 1e-9, + "p": 1e-12, +} +""" +Unit conversion mapping. + +References +---------- +:cite:`Fichet2021` +""" + +PATTERN_FICHET2021: str = ( + r"(\d*,?\d*([eE][-+]?\d+)?)(Y|Z|E|P|T|G|M|k|h|da|d|c|m|u|n|p|f|a|z|y)?(m|Hz)" +) +""" +Regex pattern for numbers and quantities. + +References +---------- +:cite:`Fichet2021` +""" + + +ComponentsFichet2021 = Dict[Union[str, float], Tuple[NDArrayFloat, NDArrayFloat]] + + +def match_groups_to_nm( + number: str, + multiplier: Literal[ + "Y", + "Z", + "E", + "P", + "T", + "G", + "M", + "k", + "h", + "da", + "", + "d", + "c", + "m", + "u", + "n", + "p", + ] + | str, + units: Literal["m", "Hz"] | str, +) -> float: + """ + Convert match groups of a wavelength (or frequency) to the nanometer value. + + Parameters + ---------- + number + Wavelength (or frequency) number to convert. + multiplier + Unit multiplier. + units + Frequency or wavelength. + + Returns + ------- + :class:`float` + Nanometer value. + + Examples + -------- + >>> match_groups_to_nm("555.5", "n", "m") + 555.5 + >>> match_groups_to_nm("555.5", "", "m") + 555500000000.0 + >>> from colour.constants import CONSTANT_LIGHT_SPEED + >>> match_groups_to_nm(str(CONSTANT_LIGHT_SPEED / (555 * 1e-9)), "", "Hz") + ... # doctest: +ELLIPSIS + 555.0000000... + """ + + multiplier = validate_method( + multiplier, tuple(MAPPING_UNIT_CONVERSION), as_lowercase=False + ) + units = validate_method(units, ("m", "Hz"), as_lowercase=False) + + v = float(number.replace(",", ".")) + + if multiplier == "n" and units == "m": + return v + + v *= MAPPING_UNIT_CONVERSION[multiplier] + + if units == "m": + v *= 1e9 + elif units == "Hz": + v = CONSTANT_LIGHT_SPEED / v * 1e9 + + return v + + +def sd_to_spectrum_attribute_Fichet2021( + sd: SpectralDistribution, decimals: int = 7 +) -> str: + """ + Convert a spectral distribution to a spectrum attribute value according to + *Fichet et al. (2021)*. + + Parameters + ---------- + sd + Spectral distribution to convert. + decimals + Formatting decimals. + + Returns + ------- + :class:`str` + Spectrum attribute value. + + References + ---------- + :cite:`Fichet2021` + + Examples + -------- + >>> sd_to_spectrum_attribute_Fichet2021(SDS_ILLUMINANTS["D65"], 2)[:56] + '300.00nm:0.03;305.00nm:1.66;310.00nm:3.29;315.00nm:11.77' + """ + + return ";".join( + f"{wavelength:.{decimals}f}nm:{value:.{decimals}f}" + for wavelength, value in zip(sd.wavelengths, sd.values) + ) + + +def spectrum_attribute_to_sd_Fichet2021( + spectrum_attribute: str, +) -> SpectralDistribution: + """ + Convert a spectrum attribute value to a spectral distribution according to + *Fichet et al. (2021)*. + + Parameters + ---------- + spectrum_attribute + Spectrum attribute value to convert. + + Returns + ------- + :class:`SpectralDistribution` + Spectral distribution. + + References + ---------- + :cite:`Fichet2021` + + Examples + -------- + >>> spectrum_attribute_to_sd_Fichet2021( + ... "300.00nm:0.03;305.00nm:1.66;310.00nm:3.29;315.00nm:11.77" + ... ) # doctest: +SKIP + SpectralDistribution([[ 3.0000000...e+02, 3.0000000...e-02], + [ 3.0500000...e+02, 1.6600000...e+00], + [ 3.1000000...e+02, 3.2900000...e+00], + [ 3.1500000...e+02, 1.1770000...e+01]], + SpragueInterpolator, + {}, + Extrapolator, + {'method': 'Constant', 'left': None, 'right': None}) + """ + + data = {} + pattern = re.compile(PATTERN_FICHET2021) + parts = spectrum_attribute.split(";") + for part in parts: + domain, range_ = part.split(":") + match = pattern.match(domain.replace(".", ",")) + if match is not None: + multiplier, units = match.group(3, 4) + wavelength = match_groups_to_nm(match.group(1), multiplier, units) + data[wavelength] = float(range_) + + return SpectralDistribution(data) + + +@dataclass +class Specification_Fichet2021: + """ + Define the *Fichet et al. (2021)* spectral image specification. + + Parameters + ---------- + path + Path of the spectral image. + components + Components of the spectral image, e.g., *S0*, *S1*, *S2*, *S3*, *T*, or + any wavelength number for bi-spectral images. + is_emissive + Whether the image is emissive, i.e, using the *S0* component. + is_polarised + Whether the image is polarised, i.e, using the *S0*, *S1*, *S2*, and + *S3* components. + is_bispectral + Whether the image is bi-spectral, i.e, using the *T*, and any + wavelength number. + attributes + An array of :class:`colour.io.Image_Specification_Attribute` class + instances used to set attributes of the image. + + Methods + ------- + - :meth:`~colour.Specification_Fichet2021.from_spectral_image` + + References + ---------- + :cite:`Fichet2021` + """ # noqa: D405, D407, D410, D411 + + path: str | None = field(default_factory=lambda: None) + components: defaultdict = field(default_factory=lambda: defaultdict(dict)) + is_emissive: bool = field(default_factory=lambda: False) + is_polarised: bool = field(default_factory=lambda: False) + is_bispectral: bool = field(default_factory=lambda: False) + attributes: List | None = field(default_factory=lambda: None) + + @staticmethod + @required("OpenImageIO") + def from_spectral_image(path: str | Path) -> Specification_Fichet2021: + """ + Create a *Fichet et al. (2021)* spectral image specification from given + image path. + + Parameters + ---------- + path + Image path + + Returns + ------- + :class:`Specification_Fichet2021` + *Fichet et al. (2021)* spectral image specification. + + Examples + -------- + >>> import os + >>> import colour + >>> path = os.path.join( + ... colour.__path__[0], + ... "io", + ... "tests", + ... "resources", + ... "D65.exr", + ... ) + >>> specification = Specification_Fichet2021.from_spectral_image(path) + ... # doctest: +SKIP + >>> specification.is_emissive # doctest: +SKIP + True + """ + + from OpenImageIO import ImageInput + + path = str(path) + + components = defaultdict(dict) + is_emissive = False + is_polarised = False + is_bispectral = False + + pattern_emissive = re.compile(rf"^(S[0-3])\.*{PATTERN_FICHET2021}$") + pattern_reflective = re.compile(rf"^T\.*{PATTERN_FICHET2021}$") + pattern_bispectral = re.compile( + rf"^T\.*{PATTERN_FICHET2021}\.*{PATTERN_FICHET2021}$" + ) + + image_specification = ImageInput.open(path).spec() + channels = image_specification.channelnames + + for i, channel in enumerate(channels): + match = pattern_emissive.match(channel) + if match: + is_emissive = True + + component = match.group(1) + multiplier, units = match.group(4, 5) + wavelength = match_groups_to_nm(match.group(2), multiplier, units) + components[component][wavelength] = i + + if len(components) > 1: + is_polarised = True + + match = pattern_bispectral.match(channel) + if match: + is_bispectral = True + + input_multiplier, input_units = match.group(3, 4) + input_wavelength = match_groups_to_nm( + match.group(1), input_multiplier, input_units + ) + output_multiplier, output_units = match.group(7, 8) + output_wavelength = match_groups_to_nm( + match.group(5), output_multiplier, output_units + ) + components[input_wavelength][output_wavelength] = i + + match = pattern_reflective.match(channel) + if match: + multiplier, units = match.group(3, 4) + wavelength = match_groups_to_nm(match.group(1), multiplier, units) + components["T"][wavelength] = i + + attributes = [] + for attribute in image_specification.extra_attribs: + attributes.append( + Image_Specification_Attribute( + attribute.name, attribute.value, attribute.type + ) + ) + + return Specification_Fichet2021( + path, + components, + is_emissive, + is_polarised, + is_bispectral, + attributes, + ) + + +@required("OpenImageIO") +def read_spectral_image_Fichet2021( + path: str | Path, + bit_depth: Literal["float16", "float32"] = "float32", + additional_data: bool = False, +) -> ComponentsFichet2021 | Tuple[ComponentsFichet2021, Specification_Fichet2021]: + """ + Read the *Fichet et al. (2021)* spectral image at given path using + *OpenImageIO*. + + Parameters + ---------- + path + Image path. + bit_depth + Returned image bit-depth. + additional_data + Whether to return additional data. + + Returns + ------- + :class:`dict` or :class:`tuple` + Dictionary of component names and their corresponding tuple of + wavelengths and values or tuple of the aforementioned dictionary and + :class:`colour.Specification_Fichet2021` class instance. + + Notes + ----- + - Spectrum attributes are not parsed but can be converted to spectral + distribution using the :func:`colour.io.spectrum_attribute_to_sd_Fichet2021` + definition. + + References + ---------- + :cite:`Fichet2021` + + Examples + -------- + >>> import os + >>> import colour + >>> path = os.path.join( + ... colour.__path__[0], + ... "io", + ... "tests", + ... "resources", + ... "D65.exr", + ... ) + >>> msds, specification = read_spectral_image_Fichet2021( + ... path, additional_data=True + ... ) # doctest: +SKIP + >>> components.keys() # doctest: +SKIP + dict_keys(['S0']) + >>> components["S0"][0].shape # doctest: +SKIP + (97,) + >>> components["S0"][1].shape # doctest: +SKIP + (1, 1, 97) + >>> specification.is_emissive # doctest: +SKIP + True + """ + + from OpenImageIO import ImageInput + + path = str(path) + + bit_depth_specification = MAPPING_BIT_DEPTH[bit_depth] + + specification = Specification_Fichet2021.from_spectral_image(path) + image = ImageInput.open(path).read_image(bit_depth_specification.openimageio) + + components = {} + for component, wavelengths_indexes in specification.components.items(): + wavelengths, indexes = zip(*wavelengths_indexes.items()) + values = as_float_array( + image[:, :, indexes], + dtype=bit_depth_specification.numpy, + ) + components[component] = ( + as_float_array(wavelengths), + np.array(values, dtype=bit_depth_specification.numpy), + ) + + if additional_data: + return components, specification + else: + return components + + +def sds_and_msds_to_components_Fichet2021( + sds: Sequence[SpectralDistribution | MultiSpectralDistributions] + | SpectralDistribution + | MultiSpectralDistributions, + specification: Specification_Fichet2021 = Specification_Fichet2021(), + **kwargs, +) -> ComponentsFichet2021: + """ + Convert given spectral and multi-spectral distributions to + *Fichet et al. (2021)* components. + + The spectral and multi-spectral distributions will be aligned to the + intersection of their spectral shapes. + + Parameters + ---------- + sds + Spectral and multi-spectral distributions to convert to + *Fichet et al. (2021)* components. + specification + *Fichet et al. (2021)* spectral image specification, used to generate + the proper component type, i.e., emissive or other. + + Other Parameters + ---------------- + shape + Optional shape the *Fichet et al. (2021)* components should take: Used + when converting spectral distributions of a colour + rendition chart to create a rectangular image rather than a single + line of values. + + Returns + ------- + :class:`dict` + Dictionary of component names and their corresponding tuple of + wavelengths and values. + + References + ---------- + :cite:`Fichet2021` + + Examples + -------- + >>> components = sds_and_msds_to_components_Fichet2021(SDS_ILLUMINANTS["D65"]) + >>> components.keys() + dict_keys(['T']) + >>> components = sds_and_msds_to_components_Fichet2021( + ... SDS_ILLUMINANTS["D65"], Specification_Fichet2021(is_emissive=True) + ... ) + >>> components.keys() + dict_keys(['S0']) + >>> components["S0"][0].shape + (97,) + >>> components["S0"][1].shape + (1, 1, 97) + """ + + msds = sds_and_msds_to_msds(sds) + component = "S0" if specification.is_emissive else "T" + + wavelengths = msds.wavelengths + values = np.transpose(msds.values) + values = np.reshape(values, (1, -1, values.shape[-1])) + + if "shape" in kwargs: + values = np.reshape(values, kwargs["shape"]) + + return {component: (wavelengths, values)} + + +@required("OpenImageIO") +def components_to_sRGB_Fichet2021( + components: ComponentsFichet2021, + specification: Specification_Fichet2021 = Specification_Fichet2021(), +) -> Tuple[NDArrayFloat | None, Sequence[Image_Specification_Attribute]]: + """ + Convert given *Fichet et al. (2021)* components to *sRGB* colourspace values. + + Parameters + ---------- + components + *Fichet et al. (2021)* components to convert. + specification + *Fichet et al. (2021)* spectral image specification, used to perform + the proper conversion to *sRGB* colourspace values. + + Returns + ------- + :class:`tuple` + Tuple of *sRGB* colourspace values and list of + :class:`colour.io.Image_Specification_Attribute` class instances. + + Warnings + -------- + - This definition currently assumes a uniform wavelength interval. + - This definition currently does not support integration of bi-spectral + component. + + Notes + ----- + - When an emissive component is given, its exposure will be normalised so + that its median is 0.18. + + References + ---------- + :cite:`Fichet2021` + + Examples + -------- + >>> specification = Specification_Fichet2021(is_emissive=True) + >>> components = sds_and_msds_to_components_Fichet2021( + ... SDS_ILLUMINANTS["D65"], + ... specification, + ... ) + >>> RGB, attributes = components_to_sRGB_Fichet2021( + ... components["S0"], specification + ... ) # doctest: +SKIP + >>> RGB # doctest: +SKIP + array([[[ 0.1799829..., 0.1800080..., 0.1800090...]]]) + >>> for attribute in attributes: + ... print(attribute.name) # doctest: +SKIP + X + Y + Z + illuminant + chromaticities + EV + """ + + from OpenImageIO import TypeDesc + + component = components.get("S0", components.get("T")) + + if component is None: + return None, [] + + # TODO: Implement support for integration of bi-spectral component. + if specification.is_bispectral: + usage_warning( + "Bi-spectral components conversion to *sRGB* colourspace values " + "is unsupported!" + ) + + # TODO: Implement support for re-binning component with non-uniform interval. + if len(interval(component[0])) != 1: + usage_warning( + "Components have a non-uniform interval, unexpected results might occur!" + ) + + msds = component[1] + shape = SpectralShape(component[0][0], component[0][-1], interval(component[0])[0]) + + cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] + colourspace = RGB_COLOURSPACE_sRGB + + if specification.is_emissive: + illuminant = SDS_ILLUMINANTS["E"] + + XYZ = msds_to_XYZ(msds, cmfs=cmfs, method="Integration", shape=shape) + else: + illuminant = SDS_ILLUMINANTS["D65"] + + XYZ = ( + msds_to_XYZ( + msds, + cmfs=cmfs, + illuminant=illuminant, + method="Integration", + shape=shape, + ) + / 100 + ) + + RGB = XYZ_to_RGB(XYZ, colourspace) + + chromaticities = np.ravel( + np.vstack([colourspace.primaries, colourspace.whitepoint]) + ).tolist() + + attributes = [ + Image_Specification_Attribute( + "X", sd_to_spectrum_attribute_Fichet2021(cmfs.signals["x_bar"]) + ), + Image_Specification_Attribute( + "Y", sd_to_spectrum_attribute_Fichet2021(cmfs.signals["y_bar"]) + ), + Image_Specification_Attribute( + "Z", sd_to_spectrum_attribute_Fichet2021(cmfs.signals["z_bar"]) + ), + Image_Specification_Attribute( + "illuminant", sd_to_spectrum_attribute_Fichet2021(illuminant) + ), + Image_Specification_Attribute( + "chromaticities", chromaticities, TypeDesc("float[8]") + ), + ] + + if specification.is_emissive: + EV = np.mean(RGB) / 0.18 + RGB /= EV + attributes.append( + Image_Specification_Attribute("EV", np.log2(EV)), + ) + + return RGB, attributes + + +@required("OpenImageIO") +def write_spectral_image_Fichet2021( + components: Sequence[SpectralDistribution | MultiSpectralDistributions] + | SpectralDistribution + | MultiSpectralDistributions + | ComponentsFichet2021, + path: str | Path, + bit_depth: Literal["float16", "float32"] = "float32", + specification: Specification_Fichet2021 = Specification_Fichet2021(), + components_to_RGB_callable: Callable = components_to_sRGB_Fichet2021, + **kwargs, +): + """ + Write given *Fichet et al. (2021)* components to given path using *OpenImageIO*. + + Parameters + ---------- + components + *Fichet et al. (2021)* components. + path + Image path. + bit_depth + Bit-depth to write the image at, the bit-depth conversion behaviour is + ruled directly by *OpenImageIO*. + specification + *Fichet et al. (2021)* spectral image specification. + components_to_RGB_callable + Callable converting the components to a preview *RGB* image. + + Other Parameters + ---------------- + shape + Optional shape the *Fichet et al. (2021)* components should take: Used + when converting spectral distributions of a colour + rendition chart to create a rectangular image rather than a single + line of values. + + Returns + ------- + :class:`bool`: + Definition success. + + Examples + -------- + >>> import os + >>> import colour + >>> path = os.path.join( + ... colour.__path__[0], + ... "io", + ... "tests", + ... "resources", + ... "BabelColorAverage.exr", + ... ) + >>> msds = list(colour.SDS_COLOURCHECKERS["BabelColor Average"].values()) + >>> specification = Specification_Fichet2021(is_emissive=False) + >>> write_spectral_image_Fichet2021( + ... msds, + ... path, + ... "float16", + ... specification, + ... shape=(4, 6, len(msds[0].shape.wavelengths)), + ... ) # doctest: +SKIP + True + """ + + from OpenImageIO import ImageBuf, ImageBufAlgo + + path = str(path) + + if isinstance( + components, (Sequence, SpectralDistribution, MultiSpectralDistributions) + ): + components = sds_and_msds_to_components_Fichet2021( + components, specification, **kwargs + ) + + if specification.attributes is None: + specification.attributes = [ + Image_Specification_Attribute("spectralLayoutVersion", "1.0") + ] + + if specification.is_emissive: + specification.attributes.extend( + [ + Image_Specification_Attribute("polarisationHandedness", "right"), + Image_Specification_Attribute("emissiveUnits", "W.m^-2.sr^-1"), + ] + ) + + bit_depth_specification = MAPPING_BIT_DEPTH[bit_depth] + + channels = {} + + RGB, attributes = components_to_RGB_callable(components, specification) + if RGB is not None: + channels.update({"R": RGB[..., 0], "G": RGB[..., 1], "B": RGB[..., 2]}) + + for component, wavelengths_values in components.items(): + wavelengths, values = wavelengths_values + for i, wavelength in enumerate(wavelengths): + component_type = str(component)[0] + if component_type == "S": # Emissive Component Type # noqa: SIM114 + channel_name = f'{component}.{str(wavelength).replace(".", ",")}nm' + elif component_type == "T": # Reflectance et al. Component Type + channel_name = f'{component}.{str(wavelength).replace(".", ",")}nm' + else: # Bi-spectral Component Type + channel_name = ( + f'T.{str(component).replace(".", ",")}nm.' + f'{str(wavelength).replace(".", ",")}nm' + ) + + channels[channel_name] = values[..., i] + + image_buffer = ImageBuf() + for channel_name, channel_data in channels.items(): + channel_buffer = ImageBuf(channel_data.astype(bit_depth_specification.numpy)) + channel_specification = channel_buffer.specmod() + channel_specification.channelnames = [channel_name] + image_buffer = ImageBufAlgo.channel_append(image_buffer, channel_buffer) + + add_attributes_to_image_specification_OpenImageIO( + image_buffer.specmod(), [*specification.attributes, *attributes] + ) + + image_buffer.write(path) + + return True diff --git a/colour/io/image.py b/colour/io/image.py index a81709cad1..6353bafe98 100644 --- a/colour/io/image.py +++ b/colour/io/image.py @@ -128,7 +128,10 @@ class Image_Specification_Attribute: "float128", np.float128, DOUBLE ) else: # pragma: no cover - ImageSpec = None + # + class ImageSpec: + attribute: Any + MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { "uint8": Image_Specification_BitDepth("uint8", np.uint8, None), @@ -145,7 +148,7 @@ class Image_Specification_Attribute: def add_attributes_to_image_specification_OpenImageIO( - image_specification: ImageSpec, attributes: Sequence | None = None + image_specification: ImageSpec, attributes: Sequence ): """ Add given attributes to given *OpenImageIO* image specification. @@ -175,6 +178,7 @@ def add_attributes_to_image_specification_OpenImageIO( >>> image_specification.extra_attribs[0].value # doctest: +SKIP 'none' """ # noqa: D405, D407, D410, D411 + for attribute in attributes: name = str(attribute.name) value = ( @@ -243,7 +247,9 @@ def image_specification_OpenImageIO( width, height, channels, bit_depth_specification.openimageio ) - add_attributes_to_image_specification_OpenImageIO(image_specification, attributes) + add_attributes_to_image_specification_OpenImageIO( + image_specification, attributes or [] + ) return image_specification diff --git a/colour/io/tests/resources/BiSpectral.exr b/colour/io/tests/resources/BiSpectral.exr new file mode 100644 index 0000000000000000000000000000000000000000..c0885ae9e2ccc0bc467a8b9a4b29210ead79d2eb GIT binary patch literal 69336 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 literal 0 HcmV?d00001 diff --git a/colour/io/tests/resources/D65.exr b/colour/io/tests/resources/D65.exr new file mode 100644 index 0000000000000000000000000000000000000000..c0a25fa28fc94d4e6d6ec13fcf31b7a303eb7523 GIT binary patch literal 39753 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 XUw-u~U-`-_|M2qL4&Q#`#n=8HsV|6e literal 0 HcmV?d00001 diff --git a/colour/io/tests/resources/Ohta1997.exr b/colour/io/tests/resources/Ohta1997.exr new file mode 100644 index 0000000000000000000000000000000000000000..9050c9db60364f252f1c25411b53f43449c64c5a GIT binary patch literal 38121 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 str: """ Validate whether given method exists in the given valid methods and - returns the method lower cased. + optionally returns the method lower cased. Parameters ---------- @@ -1469,11 +1470,13 @@ def validate_method( Valid methods. message Message for the exception. + as_lowercase + Whether to convert the given method to lower case or not. Returns ------- :class:`str` - Method lower cased. + Method optionally lower cased. Raises ------ @@ -1484,6 +1487,8 @@ def validate_method( -------- >>> validate_method("Valid", ("Valid", "Yes", "Ok")) 'valid' + >>> validate_method("Valid", ("Valid", "Yes", "Ok"), as_lowercase=False) + 'Valid' """ valid_methods = tuple([str(valid_method) for valid_method in valid_methods]) @@ -1492,7 +1497,7 @@ def validate_method( if method_lower not in [valid_method.lower() for valid_method in valid_methods]: raise ValueError(message.format(method, valid_methods)) - return method_lower + return method_lower if as_lowercase else method T = TypeVar("T") diff --git a/colour/utilities/tests/test_common.py b/colour/utilities/tests/test_common.py index 1cf53130dc..782d3af327 100644 --- a/colour/utilities/tests/test_common.py +++ b/colour/utilities/tests/test_common.py @@ -567,6 +567,10 @@ def test_validate_method(self): """Test :func:`colour.utilities.common.validate_method` definition.""" assert validate_method("Valid", ("Valid", "Yes", "Ok")) == "valid" + assert ( + validate_method("Valid", ("Valid", "Yes", "Ok"), as_lowercase=False) + == "Valid" + ) def test_raise_exception_validate_method(self): """ diff --git a/docs/colour.io.rst b/docs/colour.io.rst index 48bf939472..85eb3edfb8 100644 --- a/docs/colour.io.rst +++ b/docs/colour.io.rst @@ -1,8 +1,8 @@ -Input and Output -================ +Input and Output (IO) +===================== -Image Data ----------- +Image IO +-------- ``colour`` @@ -35,6 +35,33 @@ Image Data write_image_Imageio as_3_channels_image +Spectral Image - Fichet et al. (2021) +===================================== + +``colour`` + +.. currentmodule:: colour + +.. autosummary:: + :toctree: generated/ + + Specification_Fichet2021 + read_spectral_image_Fichet2021 + write_spectral_image_Fichet2021 + +**Ancillary Objects** + +``colour.io`` + +.. currentmodule:: colour.io + +.. autosummary:: + :toctree: generated/ + + ComponentsFichet2021 + sd_to_spectrum_attribute_Fichet2021 + spectrum_attribute_to_sd_Fichet2021 + OpenColorIO Processing ---------------------- From 405498d9b033b00da1b4457dae2c6f1dda897e0a Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Wed, 1 May 2024 20:05:15 +1200 Subject: [PATCH 6/7] Update `BIBLIOGRAPHY.bib` file. --- BIBLIOGRAPHY.bib | 301 ++++++++++++++++++++++++----------------------- 1 file changed, 156 insertions(+), 145 deletions(-) diff --git a/BIBLIOGRAPHY.bib b/BIBLIOGRAPHY.bib index fab24e24b2..d39ba3eb3a 100644 --- a/BIBLIOGRAPHY.bib +++ b/BIBLIOGRAPHY.bib @@ -9,7 +9,7 @@ @book{ANSI2018 {{Evaluating Light Source Color Rendition}}}, author = {{ANSI} and {IES Color Committee}}, year = 2018, - publisher = {{ANSI/IES}}, + publisher = {ANSI/IES}, isbn = {978-0-87995-379-9}, annotation = {thomas.mansencal@gmail.com}, } @@ -90,10 +90,10 @@ @article{Abebe2017 pages = {1--19}, issn = 15443558, doi = {10.1145/3086577}, - abstract = {{\textcopyright} 2017 ACM. The human visual system - (HVS) non-linearly processes light from the real world, allowing - us to perceive detail over a wide range of illumination. Although - models that describe this non-linearity are constructed based on + abstract = {{\copyright} 2017 ACM. The human visual system (HVS) + non-linearly processes light from the real world, allowing us to + perceive detail over a wide range of illumination. Although models + that describe this non-linearity are constructed based on psycho-visual experiments, they generally apply to a limited range of illumination and therefore may not fully explain the behavior of theHVS under more extreme illumination conditions. We propose a @@ -173,7 +173,7 @@ @book{Barten1999 year = 1999, month = dec, number = 1999, - publisher = {{SPIE}}, + publisher = {SPIE}, issn = 10924388, doi = {10.1117/3.353254}, isbn = {978-0-8194-7849-8}, @@ -369,7 +369,7 @@ @misc{Broadbent2009a author = {Broadbent, A. D.}, year = 2009, journal = {Qu{\'e}bec, Canada: D{\'e}partement de g{\'e}nie - chimique, {\ldots}}, + chimique, {\dots}}, pages = {1--17}, urldate = {2014-06-12}, abstract = {This paper describes all the steps in the @@ -391,8 +391,8 @@ @book{Burger2009b title = {Principles of {{Digital Image Processing}}}, author = {Burger, Wilhelm and Burge, Mark James}, year = 2009, - publisher = {{Springer London}}, - address = {{London}}, + publisher = {Springer London}, + address = {London}, doi = {10.1007/978-1-84800-195-4}, isbn = {978-1-84800-194-7}, } @@ -401,7 +401,7 @@ @book{CIEDivision12022 Appearance Model}} for {{Colour Management Systems}}: {{CIECAM16}}}, author = {{CIE Division 1} and {CIE Division 8}}, year = 2022, - publisher = {{Commission Internationale de l'Eclairage}}, + publisher = {Commission Internationale de l'Eclairage}, isbn = {978-3-902842-94-7}, } @book{CIETC1-321994b, @@ -410,7 +410,7 @@ @book{CIETC1-321994b {{Illuminance Adaptations}}}, author = {{CIE TC 1-32}}, year = 1994, - publisher = {{Commission Internationale de l'Eclairage}}, + publisher = {Commission Internationale de l'Eclairage}, isbn = {978-3-900734-51-0}, } @book{CIETC1-362006a, @@ -418,7 +418,7 @@ @book{CIETC1-362006a Diagram}} with {{Physiological Axes}} - {{Part}} 1}, author = {{CIE TC 1-36}}, year = 2006, - publisher = {{Commission Internationale de l'Eclairage}}, + publisher = {Commission Internationale de l'Eclairage}, isbn = {978-3-901906-46-6}, } @incollection{CIETC1-382005e, @@ -476,7 +476,7 @@ @book{CIETC1-482004h author = {{CIE TC 1-48}}, year = 2004, journal = {CIE 015:2004 Colorimetry, 3rd Edition}, - publisher = {{Commission Internationale de l'Eclairage}}, + publisher = {Commission Internationale de l'Eclairage}, isbn = {978-3-901906-33-6}, } @incollection{CIETC1-482004i, @@ -545,8 +545,8 @@ @book{CIETC1-902017 year = 2017, series = {{Technical report / CIE}}, number = 224, - publisher = {{CIE Central Bureau}}, - address = {{Vienna}}, + publisher = {CIE Central Bureau}, + address = {Vienna}, isbn = {978-3-902842-61-9}, langid = {eng fre ger}, annotation = {OCLC: 988568299}, @@ -682,8 +682,8 @@ @techreport{Carter2018 J.H.}, year = 2018, month = oct, - address = {{Vienna}}, - institution = {{International Commission on Illumination}}, + address = {Vienna}, + institution = {International Commission on Illumination}, doi = {10.25039/TR.015.2018}, isbn = 9783902842138, } @@ -900,12 +900,10 @@ @article{Cui2002 CIE94 colour-difference formulas and only slightly worse than CIEDE2000 (which was optimized on the experimental data). However, these formulas all have an associated UCS. The spaces are similar - in form to L*a*b*. {\textcopyright} 2002 Wiley Periodicals, Inc. - Col Res Appl, 27, 282{\textendash}290, 2002; Published online in - Wiley InterScience (www.interscience.wiley.com). DOI - 10.1002/col.10066}, - copyright = {Copyright {\textcopyright} 2002 Wiley Periodicals, - Inc.}, + in form to L*a*b*. {\copyright} 2002 Wiley Periodicals, Inc. Col + Res Appl, 27, 282--290, 2002; Published online in Wiley + InterScience (www.interscience.wiley.com). DOI 10.1002/col.10066}, + copyright = {Copyright {\copyright} 2002 Wiley Periodicals, Inc.}, langid = {english}, keywords = {colour discrimination ellipses,colour-difference metrics,uniform colour space}, @@ -980,15 +978,15 @@ @article{Davis2010a doi = {10.1117/1.3360335}, abstract = {The color rendering index (CRI) has been shown to have deficiencies when applied to white - light-emitting-diode{\textendash}based sources. Furthermore, - evidence suggests that the restricted scope of the CRI - unnecessarily penalizes some light sources with desirable color - qualities. To solve the problems of the CRI and include other - dimensions of color quality, the color quality scale (CQS) has - been developed. Although the CQS uses many of elements of the CRI, - there are a number of fundamental differences. Like the CRI, the - CQS is a test-samples method that compares the appearance of a set - of reflective samples when illuminated by the test lamp to their + light-emitting-diode--based sources. Furthermore, evidence + suggests that the restricted scope of the CRI unnecessarily + penalizes some light sources with desirable color qualities. To + solve the problems of the CRI and include other dimensions of + color quality, the color quality scale (CQS) has been developed. + Although the CQS uses many of elements of the CRI, there are a + number of fundamental differences. Like the CRI, the CQS is a + test-samples method that compares the appearance of a set of + reflective samples when illuminated by the test lamp to their appearance under a reference illuminant. The CQS uses a larger set of reflective samples, all of high chroma, and combines the color differences of the samples with a root mean square. Additionally, @@ -1215,7 +1213,7 @@ @incollection{Fairchild2004c year = 2004, edition = 2, pages = {289--301}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-470-01216-1}, } @inproceedings{Fairchild2010, @@ -1251,7 +1249,7 @@ @incollection{Fairchild2013ba year = 2013, edition = 3, pages = {4810--5085}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013s, @@ -1261,7 +1259,7 @@ @incollection{Fairchild2013s year = 2013, edition = 3, pages = {4418--4495}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013t, @@ -1271,7 +1269,7 @@ @incollection{Fairchild2013t year = 2013, edition = 3, pages = {4179--4252}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013u, @@ -1281,7 +1279,7 @@ @incollection{Fairchild2013u year = 2013, edition = 3, pages = {5094--5556}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013v, @@ -1291,7 +1289,7 @@ @incollection{Fairchild2013v year = 2013, edition = 3, pages = {5852--5991}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013w, @@ -1301,7 +1299,7 @@ @incollection{Fairchild2013w year = 2013, edition = 3, pages = {5563--5824}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013x, @@ -1311,7 +1309,7 @@ @incollection{Fairchild2013x year = 2013, edition = 3, pages = {6025--6178}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @incollection{Fairchild2013y, @@ -1321,7 +1319,7 @@ @incollection{Fairchild2013y year = 2013, edition = 3, pages = {6197--6223}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {B00DAYO8E2}, } @article{Fairchild2020, @@ -1399,6 +1397,22 @@ @misc{FiLMiCInc2017 year = 2017, pages = {1--46}, } +@article{Fichet2021, + title = {An {{OpenEXR Layout}} for {{Spectral Images}}}, + author = {Fichet, A and Pacanowski, R and Wilkie, A}, + year = 2021, + volume = 10, + number = 3, + urldate = {2024-04-26}, + abstract = {We propose a standardized layout to organize + spectral data stored in OpenEXR images. We motivate why we chose + the OpenEXR format as the basis for our work, and we explain our + choices with regard to data selection and organization: our goal + is to define a standard for the exchange of measured or simulated + spectral and bi-spectral data. We also provide sample code to + store spectral images in OpenEXR format.}, + langid = {english}, +} @article{Finlayson2015, title = {Color {{Correction Using Root-Polynomial Regression}}}, @@ -1414,18 +1428,18 @@ @article{Finlayson2015 doi = {10.1109/TIP.2015.2405336}, abstract = {Cameras record three color responses (RGB) which are device dependent. Camera coordinates are mapped to a standard - color space, such as XYZ{\textemdash}useful for color - measurement{\textemdash}by amapping function, e.g., the simple - 3{\texttimes}3 linear transform (usually derived through - regression). This mapping, which we will refer to as linear color - correction (LCC), has been demonstrated to work well in the number - of studies. However, it can map RGBs to XYZs with high error. The - advantage of the LCC is that it is independent of camera exposure. - An alternative and potentially more powerful method for color - correction is polynomial color correction (PCC). Here, the R, - G,and B values at a pixel are extended by the polynomial terms. - For a given calibration training set PCC can significantly reduce - the colorimetric error. However, the PCC fit depends on exposure, + color space, such as XYZ---useful for color measurement---by + amapping function, e.g., the simple 3{\texttimes}3 linear + transform (usually derived through regression). This mapping, + which we will refer to as linear color correction (LCC), has been + demonstrated to work well in the number of studies. However, it + can map RGBs to XYZs with high error. The advantage of the LCC is + that it is independent of camera exposure. An alternative and + potentially more powerful method for color correction is + polynomial color correction (PCC). Here, the R, G,and B values at + a pixel are extended by the polynomial terms. For a given + calibration training set PCC can significantly reduce the + colorimetric error. However, the PCC fit depends on exposure, i.e., as exposure changes the vector of polynomial components is altered in a nonlinear way which results in hue and saturation shifts. This paper proposes a new polynomial-type regression @@ -1450,7 +1464,7 @@ @misc{Frohlich2017 Imagery}, author = {Fr{\"o}hlich, Jan}, year = 2017, - publisher = {{Universit{\"a}t Stuttgart}}, + publisher = {Universit{\"a}t Stuttgart}, urldate = {2021-08-07}, abstract = {In dieser Dissertation wird ein szenischer Bewegtbilddatensatz mit erweitertem Dynamikumfang (High Dynamic @@ -1552,7 +1566,7 @@ @article{Glasser1958a volume = 48, number = 10, pages = 736, - publisher = {{OSA}}, + publisher = {OSA}, issn = {0030-3941}, doi = {10.1364/JOSA.48.000736}, abstract = {A visually uniform color coordinate system, based @@ -1620,8 +1634,8 @@ @inproceedings{Hanbury2003 editor = {Bigun, Josef and Gustavsson, Tomas}, year = 2003, pages = {804--811}, - publisher = {{Springer Berlin Heidelberg}}, - address = {{Berlin, Heidelberg}}, + publisher = {Springer Berlin Heidelberg}, + address = {Berlin, Heidelberg}, abstract = {Representations of the RGB space in terms of 3D-polar coordinates (hue, saturation and brightness) are often used in image analysis. The literature describes a large number of @@ -1686,7 +1700,7 @@ @article{Hellwig2022 } @article{Hellwig2022a, title = {Extending {{CIECAM02}} and {{CAM16}} for the - {{Helmholtz}}{\textendash}{{Kohlrausch}} Effect}, + {{Helmholtz}}--{{Kohlrausch}} Effect}, shorttitle = {Extending}, author = {Hellwig, Luke and Stolitzka, Dale and Fairchild, Mark D.}, @@ -1710,8 +1724,8 @@ @article{Hernandez-Andres1999a volume = 38, number = 27, pages = 5703, - publisher = {{Departamento de Optica, Facultad de Ciencias, - Universidad de Granada, Granada 18071, Spain.}}, + publisher = {Departamento de Optica, Facultad de Ciencias, + Universidad de Granada, Granada 18071, Spain.}, issn = {0003-6935}, doi = {10.1364/AO.38.005703}, abstract = {Natural outdoor illumination daily undergoes large @@ -1779,8 +1793,8 @@ @book{Hunt2004b year = 2004, month = sep, edition = 6, - publisher = {{John Wiley \& Sons, Ltd}}, - address = {{Chichester, UK}}, + publisher = {John Wiley \& Sons, Ltd}, + address = {Chichester, UK}, doi = {10.1002/0470024275}, isbn = {978-0-470-02427-0}, keywords = {calanus finmarchicus,egg production,gonad @@ -1828,7 +1842,7 @@ @book{IESComputerCommittee2014a author = {{IES Computer Committee} and {TM-27-14 Working Group}}, year = 2014, - publisher = {{Illuminating Engineering Society}}, + publisher = {Illuminating Engineering Society}, isbn = {978-0-87995-295-2}, } @misc{ImageEngineering2017, @@ -2012,7 +2026,7 @@ @inproceedings{Jiang2013 year = 2013, month = jan, pages = {168--179}, - publisher = {{IEEE}}, + publisher = {IEEE}, issn = 21583978, doi = {10.1109/WACV.2013.6475015}, abstract = {Camera spectral sensitivity functions relate scene @@ -2131,8 +2145,8 @@ @article{Konovalenko2021 to perform linear colour analysis.}, archiveprefix = {arxiv}, langid = {english}, - keywords = {⛔ No DOI found,Computer Science - Computer Vision - and Pattern Recognition}, + keywords = {Computer Science - Computer Vision and Pattern + Recognition,No DOI found}, } @misc{Konovalenko2021a, title = {{{proLab}}\_param.m}, @@ -2148,7 +2162,7 @@ @article{Krystek1985b volume = 10, number = 1, pages = {38--40}, - publisher = {{Wiley Subscription Services, Inc., A Wiley Company}}, + publisher = {Wiley Subscription Services, Inc., A Wiley Company}, issn = 03612317, doi = {10.1002/col.5080100109}, } @@ -2300,23 +2314,23 @@ @article{Lu2016c pages = {32--38}, abstract = {High Dynamic Range (HDR) and Wider Colour Gamut (WCG) content represents a greater range of luminance levels and a - more complete reproduction of colours found in - real{$\hyphenbullet$}world scenes. The current video distribution - environments deliver Standard Dynamic Range (SDR) signal - Y{${'}$}CbCr. For HDR and WCG content, it is desirable to examine - if such signal format still works well for compression, and to - know if the overall system performance can be further improved by - exploring different signal formats. In this paper, ITP (ICTCP) - colour space is presented. The paper concentrates on examining the - two aspects of ITP colour space: 1) ITP characteristics in terms - of signal quantization at a given bit depth; 2) ITP compression - performance. The analysis and simulation results show that ITP 10 - bit has better properties than Y{${'}$}CbCr{$\hyphenbullet$}PQ - 10bit in colour quantization, constant luminance, hue property and - chroma subsampling, and it also has good compression efficiency. - Therefore it is desirable to adopt ITP colour space as a new - signal format for HDR/WCG video compression.}, - keywords = {HDR,ICT CP,ITP,WCG,Y{${'}$}CbCr}, + more complete reproduction of colours found in real⁃world scenes. + The current video distribution environments deliver Standard + Dynamic Range (SDR) signal Y{$\prime$}CbCr. For HDR and WCG + content, it is desirable to examine if such signal format still + works well for compression, and to know if the overall system + performance can be further improved by exploring different signal + formats. In this paper, ITP (ICTCP) colour space is presented. The + paper concentrates on examining the two aspects of ITP colour + space: 1) ITP characteristics in terms of signal quantization at a + given bit depth; 2) ITP compression performance. The analysis and + simulation results show that ITP 10 bit has better properties than + Y{$\prime$}CbCr⁃PQ 10bit in colour quantization, constant + luminance, hue property and chroma subsampling, and it also has + good compression efficiency. Therefore it is desirable to adopt + ITP colour space as a new signal format for HDR/WCG video + compression.}, + keywords = {HDR,ICT CP,ITP,WCG,Y'CbCr}, } @article{Luo1996b, title = {The {{LLAB}} (l:C) Colour Model}, @@ -2327,7 +2341,7 @@ @article{Luo1996b volume = 21, number = 6, pages = {412--429}, - publisher = {{Wiley Subscription Services, Inc., A Wiley Company}}, + publisher = {Wiley Subscription Services, Inc., A Wiley Company}, issn = {0361-2317}, doi = {10.1002/(SICI)1520-6378(199612)21:6<412::AID-COL4>3.0.CO;2-Z}, abstract = {A new colour model, named LLAB(l:c) is derived. It @@ -2350,7 +2364,7 @@ @article{Luo1996b constancy, and quantification of colour-rendering properties. The model does not give predictions for chroma (as distinct from colourfulness), or for brightness, and it does not include any rod - response. {\textcopyright} 1996 John Wiley \& Sons, Inc.}, + response. {\copyright} 1996 John Wiley \& Sons, Inc.}, keywords = {chromatic adaptation transform,colour appearance,colour appearance model,colour difference,colour difference formula,corresponding colours,uniform colour space}, @@ -2359,8 +2373,8 @@ @inproceedings{Luo1996c title = {Two {{Unsolved Issues}} in {{Colour Management}} - {{Colour Appearance}} and {{Gamut Mapping}}}, booktitle = {Conference: 5th {{International Conference}} on - {{High Technology}}: {{Imaging Science}} and {{Technology}} - {\textendash} {{Evolution}} \& {{Promise}}}, + {{High Technology}}: {{Imaging Science}} and {{Technology}} -- + {{Evolution}} \& {{Promise}}}, author = {Luo, Ming Ronnier and Morovic, J{\'a}n}, year = 1996, pages = {136--147}, @@ -2444,8 +2458,8 @@ @incollection{Luo2013 editor = {{Fernandez-Maloigne}, Christine}, year = 2013, pages = {19--58}, - publisher = {{Springer New York}}, - address = {{New York, NY}}, + publisher = {Springer New York}, + address = {New York, NY}, doi = {10.1007/978-1-4419-6190-7}, urldate = {2014-09-27}, isbn = {978-1-4419-6189-1}, @@ -2463,7 +2477,7 @@ @article{MacAdam1935a volume = 25, number = 11, pages = {361--367}, - publisher = {{OSA}}, + publisher = {OSA}, doi = {10.1364/JOSA.25.000361}, abstract = {Tristimulus values have been computed for hypothetical spectrophotometric curves of the type found to give @@ -2580,7 +2594,7 @@ @article{Mallett2019 journal = {Eurographics Symposium on Rendering - DL-only and Industry Track}, pages = {7 pages}, - publisher = {{The Eurographics Association}}, + publisher = {The Eurographics Association}, issn = {1727-3463}, doi = {10.2312/SR.20191216}, urldate = {2020-08-08}, @@ -2705,7 +2719,7 @@ @article{Mokrzycki2011 popular colors spaces, as both linear and nonlinear due to perceptual abilities, and are briefly discussed and compared to the sample values.}, - keywords = {⛔ No DOI found}, + keywords = {No DOI found}, } @article{Moroney2003, title = {A {{Radial Sampling}} of the {{OSA Uniform Color @@ -2735,7 +2749,7 @@ @article{Moroney2003 parent_itemid = {infobike://ist/cic}, publication_date = {2003-01-01T00:00:00}, publishercode = {ist}, - keywords = {⛔ No DOI found}, + keywords = {No DOI found}, } @article{Moroneya, title = {The {{CIECAM02}} Color Appearance Model}, @@ -2777,7 +2791,7 @@ @article{Morovic2000 Descriptor obtained using the Segment Maxima Method. Throughout the article, the focus is both on colour reproduction media and colour images as well as on the suitability of the methods for use - in gamut mapping. {\textcopyright} 2000 John Wiley \& Sons. Inc.}, + in gamut mapping. {\copyright} 2000 John Wiley \& Sons. Inc.}, keywords = {Cross-media reproduction,Gamut boundary calculation,Gamut mapping}, } @@ -2814,7 +2828,7 @@ @article{Nayatani1995a volume = 20, number = 3, pages = {156--167}, - publisher = {{Wiley Subscription Services, Inc., A Wiley Company}}, + publisher = {Wiley Subscription Services, Inc., A Wiley Company}, issn = 03612317, doi = {10.1002/col.5080200305}, keywords = {color-vision model,lightness dependency of @@ -2822,7 +2836,7 @@ @article{Nayatani1995a } @article{Nayatani1997, title = {Simple Estimation Methods for the - {{Helmholtz}}{\textemdash}{{Kohlrausch}} Effect}, + {{Helmholtz}}---{{Kohlrausch}} Effect}, author = {Nayatani, Yoshinobu}, year = 1997, journal = {Color Research \& Application}, @@ -2833,32 +2847,29 @@ @article{Nayatani1997 doi = {10.1002/(SICI)1520-6378(199712)22:6<385::AID-COL6>3.0.CO;2-R}, urldate = {2021-06-22}, abstract = {Four kinds of simple estimation equations are - proposed for the Helmholtz{\textemdash}Kohlrausch effect. Two of - them can be used for luminous colors, and the other two for object - colors. In each of luminous and object colors, the two estimation - equations are given to each of the Variable-Achromatic-Color (VAC) - and the Variable-Chromatic-Color (VCC) methods. All the equations - are similar in type to the Ware{\textemdash}Cowan equation. They - give the ratio between luminance (or metric lightness) of test - color stimulus and its equivalent luminance (or equivalent - lightness) directly. Though their computations are simple, they - can apply to various H{\textemdash}K effects including their - adapting luminance dependency. The applicable fields of the - proposed equations are wider than those of the - Ware{\textemdash}Cowan equation. The proposed equations can be - applied to predict the H{\textemdash}K effect within the whole - chromaticity gamut including spectral colors, spectral luminosity - functions based on direct color matching from 0.01 Td to 100 000 - Td using the photopic and the scotopic spectral luminosity - functions specified by CIE, equivalent lightness values of NCS - colors, and others. {\textcopyright} 1997 John Wiley \& Sons, Inc. - Col Res Appl. 22, 385{\textendash}401, 1997}, - copyright = {Copyright {\textcopyright} 1997 John Wiley \& Sons, - Inc.}, + proposed for the Helmholtz---Kohlrausch effect. Two of them can be + used for luminous colors, and the other two for object colors. In + each of luminous and object colors, the two estimation equations + are given to each of the Variable-Achromatic-Color (VAC) and the + Variable-Chromatic-Color (VCC) methods. All the equations are + similar in type to the Ware---Cowan equation. They give the ratio + between luminance (or metric lightness) of test color stimulus and + its equivalent luminance (or equivalent lightness) directly. + Though their computations are simple, they can apply to various + H---K effects including their adapting luminance dependency. The + applicable fields of the proposed equations are wider than those + of the Ware---Cowan equation. The proposed equations can be + applied to predict the H---K effect within the whole chromaticity + gamut including spectral colors, spectral luminosity functions + based on direct color matching from 0.01 Td to 100 000 Td using + the photopic and the scotopic spectral luminosity functions + specified by CIE, equivalent lightness values of NCS colors, and + others. {\copyright} 1997 John Wiley \& Sons, Inc. Col Res Appl. + 22, 385--401, 1997}, + copyright = {Copyright {\copyright} 1997 John Wiley \& Sons, Inc.}, langid = {english}, keywords = {CIELUV formula,color appearance,equivalent - lightness,equivalent luminance,Helmholtz{\textemdash}Kohlrausch - effect}, + lightness,equivalent luminance,Helmholtz-Kohlrausch effect}, } @article{Newhall1943a, title = {Final {{Report}} of the {{OSA Subcommittee}} on the @@ -3219,8 +3230,8 @@ @inproceedings{Smith1978b author = {Smith, Alvy Ray}, year = 1978, pages = {12--19}, - publisher = {{ACM Press}}, - address = {{New York, New York, USA}}, + publisher = {ACM Press}, + address = {New York, New York, USA}, doi = {10.1145/800248.807361}, keywords = {Brightness,Color,Color transform,color transforms,Gamut,HSL,HSV,Hue,Luminance,NTSC,RGB,Saturation,Value}, @@ -3235,7 +3246,7 @@ @article{Smits1999a volume = 4, number = 4, pages = {11--22}, - publisher = {{AK Peters, Ltd.}}, + publisher = {AK Peters, Ltd.}, issn = {1086-7651}, doi = {10.1080/10867651.1999.10487511}, urldate = {2014-09-19}, @@ -3308,7 +3319,7 @@ @misc{SocietyofMotionPictureandTelevisionEngineers2014a } @misc{SocietyofMotionPictureandTelevisionEngineers2019, title = {{{ST}} 428-1:2019 - {{D-Cinema Distribution Master}} - {\textemdash} {{Image Characteristic}}}, + --- {{Image Characteristic}}}, author = {{Society of Motion Picture and Television Engineers}}, year = 2019, doi = {10.5594/SMPTE.ST428-1.2019}, @@ -3388,7 +3399,7 @@ @article{Stearns1988a volume = 13, number = 4, pages = {257--259}, - publisher = {{Wiley Subscription Services, Inc., A Wiley Company}}, + publisher = {Wiley Subscription Services, Inc., A Wiley Company}, issn = 03612317, doi = {10.1002/col.5080130410}, } @@ -3623,7 +3634,7 @@ @article{Ward2002 year = 2002, journal = {Eurographics workshop on Rendering}, pages = {117--124}, - publisher = {{Eurographics Association}}, + publisher = {Eurographics Association}, doi = {10.2312/EGWR/EGWR02/117-124}, urldate = {2014-09-27}, abstract = {Abstract Accurate color requires the consideration @@ -3658,8 +3669,8 @@ @incollection{Westland2004 month = mar, edition = 1, pages = 137, - publisher = {{John Wiley \& Sons, Ltd}}, - address = {{Chichester, UK}}, + publisher = {John Wiley \& Sons, Ltd}, + address = {Chichester, UK}, doi = {10.1002/0470020326}, isbn = {978-0-470-84562-2}, } @@ -3790,11 +3801,11 @@ @misc{Wikipedia2003e howpublished = {https://en.wikipedia.org/wiki/Vandermonde\_matrix}, } @misc{Wikipedia2003f, - title = {Rayleigh{\textendash}{{Jeans}} Law}, + title = {Rayleigh--{{Jeans}} Law}, author = {{Wikipedia}}, year = 2003, urldate = {2022-02-12}, - howpublished = {https://en.wikipedia.org/wiki/Rayleigh{\textendash}Jeans\_law}, + howpublished = {https://en.wikipedia.org/wiki/Rayleigh--Jeans\_law}, } @misc{Wikipedia2004, title = {Peak Signal-to-Noise Ratio}, @@ -3966,7 +3977,7 @@ @article{Wyszecki1963b volume = 53, number = 11, pages = 1318, - publisher = {{OSA}}, + publisher = {OSA}, issn = {0030-3941}, doi = {10.1364/JOSA.53.001318}, urldate = {2014-09-26}, @@ -3981,7 +3992,7 @@ @incollection{Wyszecki2000 author = {Wyszecki, G{\"u}nther and Stiles, W S}, year = 2000, pages = 309, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000a, @@ -3991,7 +4002,7 @@ @incollection{Wyszecki2000a author = {Wyszecki, G{\"u}nther and Stiles, W S}, year = 2000, pages = 8, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000ba, @@ -4002,7 +4013,7 @@ @incollection{Wyszecki2000ba author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {837--839}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000bb, @@ -4012,7 +4023,7 @@ @incollection{Wyszecki2000bb author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {776--777}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000bd, @@ -4023,7 +4034,7 @@ @incollection{Wyszecki2000bd author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = 167, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000be, @@ -4033,7 +4044,7 @@ @incollection{Wyszecki2000be author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = 141, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000bf, @@ -4043,7 +4054,7 @@ @incollection{Wyszecki2000bf author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {158--163}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000bg, @@ -4053,7 +4064,7 @@ @incollection{Wyszecki2000bg author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {138--139}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000bh, @@ -4063,7 +4074,7 @@ @incollection{Wyszecki2000bh author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {778--779}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000s, @@ -4073,7 +4084,7 @@ @incollection{Wyszecki2000s author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {256--259,395}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000x, @@ -4083,7 +4094,7 @@ @incollection{Wyszecki2000x author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = 228, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000y, @@ -4094,7 +4105,7 @@ @incollection{Wyszecki2000y author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {224--229}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @incollection{Wyszecki2000z, @@ -4104,7 +4115,7 @@ @incollection{Wyszecki2000z author = {Wyszecki, G{\"u}nther and Stiles, W. S.}, year = 2000, pages = {145--146}, - publisher = {{Wiley}}, + publisher = {Wiley}, isbn = {978-0-471-39918-6}, } @misc{X-Rite2012a, From 970f59cebab45c80dbb3c1bd6630ff4a8f30d7ca Mon Sep 17 00:00:00 2001 From: Thomas Mansencal Date: Wed, 1 May 2024 20:31:17 +1200 Subject: [PATCH 7/7] Add *Fichet et al. (2021)* examples. --- README.rst | 12 +++++++++ colour/examples/io/examples_fichet2021.py | 32 +++++++++++++++++++++++ docs/index.rst | 12 +++++++++ 3 files changed, 56 insertions(+) create mode 100644 colour/examples/io/examples_fichet2021.py diff --git a/README.rst b/README.rst index ffcf3903d4..1300d7c0a6 100644 --- a/README.rst +++ b/README.rst @@ -876,6 +876,18 @@ Images (276, 281, 3) +Spectral Images - Fichet et al. (2021) +************************************** + +.. code-block:: python + + components = colour.read_spectral_image_Fichet2021("Polarised.exr") + list(components.keys()) + +.. code-block:: text + + ['S0', 'S1', 'S2', 'S3'] + Look Up Table (LUT) Data ************************ diff --git a/colour/examples/io/examples_fichet2021.py b/colour/examples/io/examples_fichet2021.py new file mode 100644 index 0000000000..542051a030 --- /dev/null +++ b/colour/examples/io/examples_fichet2021.py @@ -0,0 +1,32 @@ +""" +Showcases *Fichet, Pacanowski and Wilkie (2021)* +*OpenEXR Layout for Spectral Images* related examples. +""" + +import os +import tempfile + +import colour +from colour.utilities import message_box + +ROOT_RESOURCES = os.path.join( + os.path.dirname(__file__), "..", "..", "io", "tests", "resources" +) + +message_box('"Fichet, Pacanowski and Wilkie (2021)" Spectral Image Reading and Writing') + +message_box("Reading a spectral image.") +path = os.path.join(ROOT_RESOURCES, "Ohta1997.exr") +components, specification = colour.read_spectral_image_Fichet2021( + path, additional_data=True +) +print(components) +print(specification) + +print("\n") + +message_box("Writing a spectral image.") +_descriptor, path = tempfile.mkstemp(suffix=".exr") +colour.write_spectral_image_Fichet2021(components, path) # pyright: ignore +components = colour.read_spectral_image_Fichet2021(path) +print(components) diff --git a/docs/index.rst b/docs/index.rst index 4b8feaf643..fe0b31287f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -651,6 +651,18 @@ Images (276, 281, 3) +Spectral Images - Fichet et al. (2021) +************************************** + +.. code-block:: python + + components = colour.read_spectral_image_Fichet2021("Polarised.exr") + list(components.keys()) + +.. code-block:: text + + ['S0', 'S1', 'S2', 'S3'] + Look Up Table (LUT) Data ************************