Colour v0.3.14 Release Notes

Release Date: 2019-10-26 // over 4 years ago
  • Colour 0.3.14 - Alpha Milestone

    We would like to thanks all the contributors as usual!

    ๐Ÿš€ With this release we are getting close to have a beta candidate in the coming months. It will likely be the last version to support Python 2.x.

    NumFOCUS

    Colour is now a NumFOCUS affiliated project:

    image

    Hacktoberfest - 2019

    We had a few new contributors for the 2019 edition of the Hacktoberfest. Thanks to @Chinmayrane16, @evalevanto, @feralpoosum, @BPearlstine and, @pavithraes for their contributions!

    Automatic Colour Conversion Graph

    Colour now implements an automatic colour conversion graph based on NetworkX and enabling easier colour conversions:

    \>\>\> sd = colour.COLOURCHECKERS\_SDS['ColorChecker N Ohta']['dark skin']\>\>\> convert(sd, 'Spectral Distribution', 'sRGB', verbose={'mode': 'Short'})
    

    Image Input and Output

    Imageio is now a requirement for reading and writing images, it will be used if OpenImageIO is not available. If you wish to read OpenEXR files or develop Colour, you will need to install the FreeImage plugin as follows:

    $ python -c "import imageio;imageio.plugins.freeimage.download()"
    

    ๐Ÿ‘Œ Support for OpenImageIO 2.x has also been implemented.

    Name and Signature Changes

    Various colour component transfer functions objects have been either renamed or their signature changed, most notably the sRGB transfer functions and the colour.oetf definition.

    All the reverse words have been replaced with inverse in object names, file names and, docstrings.

    Coverage

    Coverage was raised to 100%. It does not mean that all the possible code paths are covered but it certainly strengthen the API.

    Dependency Management

    We have adopted Poetry to manage the development dependencies, the setup.py file has been replaced with a standardized pyproject.toml file.

    Continuous Integration

    Travis-ci and Azure Pipelines have been replaced with Github Actions.

    ๐Ÿ“š Documentation

    ๐Ÿ‘ The README and the Manual have been slightly reorganised to create a better separation between the tutorials, API reference and, the new How-To Guide.

    ๐Ÿ”‹ Features

    colour.colorimetry

    • Add colour.sds_and_multi_sds_to_sds definition that converts given spectral and multi-spectral distributions to a flat list of spectral distributions. (@KelSolaar)
    • Implement support for ICC D50 illuminant computed from the following CIE XYZ tristimulus values [96.42, 100.00, 82.49]. (@KelSolaar)
    • Add colour.colorimetry.multi_sds_to_XYZ_ASTME308 definition that converts given multi-spectral distributions to CIE XYZ tristimulus values according to to practise ASTM E308-15 method. (@KelSolaar)
    • Implement support for ICC D50 illuminant computed from the following CIE XYZ tristimulus values [96.42, 100.00, 82.49]. (@KelSolaar)

    colour.corresponding

    • colour.corresponding_chromaticities_prediction definition can now use a colour.CorrespondingColourDataset class instance as argument. (@KelSolaar)

    colour.io

    • The colour.read_image and colour.write_image definitions support Imageio and will fallback to it if OpenImageIO is not available.
    • ๐Ÿš€ OpenImageIO 2.x is now supported.

    colour.graph

    • The new colour.convert definition leverages an automatic colour conversion graph enabling easier colour conversions:

      >>> sd = colour.COLOURCHECKERS_SDS['ColorChecker N Ohta']['dark skin']>>> convert(sd, 'Spectral Distribution', 'sRGB', verbose={'mode': 'Short'})

      ===============================================================================

      • *
      • [Conversion Path] *
      • *
      • "sd_to_XYZ" --> "XYZ_to_sRGB" *

      * *

      array([0.45675795, 0.30986982, 0.24861924])>>> illuminant = colour.ILLUMINANTS_SDS['FL2']>>> convert(sd, 'Spectral Distribution', 'sRGB', sd_to_XYZ={'illuminant': illuminant}) array([0.47924575, 0.31676968, 0.17362725])

    image

    colour.models

    • Implement support for Recommendation ITU-R BT.2100-2 with the modified black lift handling of HLG EOTF. (@KelSolaar, @nick-shaw)
    • Implement support for Fujifilm F-Gamut RGB colourspace with colour.models.F_GAMUT_COLOURSPACE class and Fujifilm F-Log with colour.models.log_encoding_FLog and colour.models.log_decoding_FLog transfer functions. (@sobotka, @KelSolaar, @nick-shaw)
    • Re-implement support for SMPTE C RGB colourspace with colour.models.SMPTE_C_COLOURSPACE class and related NTSC (1987) RGB colourspace with colour.models.NTSC_1987_COLOURSPACE class. (@KelSolaar)

    colour.plotting

    • Add colour.plotting.plot_constant_hue_loci definition plotting Constant Hue Loci as given by Hung and Berns (1995) or Ebner and Fairchild (1998). It is intended to be used with Colour - Datasets as follows:

      from colour_datasets import loadfrom colour.plotting import plot_constant_hue_loci plot_constant_hue_loci(load('3362536'), 'IPT')

    image

    colour.temperature

    • โž• Add various optimization based correlated colour temperature computation definitions: (@KelSolaar)
      • colour.temperature.xy_to_CCT_CIE_D
      • colour.temperature.CCT_to_xy_Hernandez1999, this definition is not a bijective function and might produce unexpected results. It is given for consistency with other correlated colour temperature computation methods but should be avoided for practical applications.
      • colour.temperature.xy_to_CCT_Kang2002
      • colour.temperature.uv_to_CCT_Krystek1985
      • colour.temperature.CCT_to_xy_McCamy1992, this definition is not a bijective function and might produce unexpected results. It is given for consistency with other correlated colour temperature computation methods but should be avoided for practical applications.

    ๐Ÿ›  Fixes

    colour.quality

    • The individual colour scales returned by colour.colour_quality_scale definition when using the additional_data argument were incorrectly scaled and have been fixed. (@KelSolaar)

    ๐Ÿ”„ Changes

    colour.adaptation

    • colour.adaptation.chromatic_adaptation_reverse_CMCCAT2000: (@KelSolaar)
      • Name: chromatic_adaptation_inverse_CMCCAT2000

    colour.appearance

    • โœ… yield based tests dependent on nosetests have been replaced. (@MichaelMauderer)

    colour.characterisation

    • The following colour checkers now use ICC D50 illuminant instead of D50: (@KelSolaar)
      • ColorChecker 2005
      • BabelColor Average
      • ColorChecker24 - Before November 2014
      • ColorChecker24 - After November 2014

    colour.colorimetry

    • colour.ASTME30815_PRACTISE_SHAPE: (@KelSolaar)
      • Name: ASTME308_PRACTISE_SHAPE
    • colour.MultiSpectralDistribution: (@KelSolaar)
      • Name: MultiSpectralDistributions
    • colour.multi_sds_to_XYZ: (@KelSolaar)
      • Signature: multi_sds_to_XYZ(msds, cmfs=STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy().trim(DEFAULT_SPECTRAL_SHAPE), illuminant=sd_ones(), k=None, method='ASTM E308-15', **kwargs)
    • colour.colorimetry.multi_sds_to_XYZ_integration: (@KelSolaar)
      • Signature: multi_sds_to_XYZ_integration(msds, cmfs=STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']. copy().trim(DEFAULT_SPECTRAL_SHAPE), illuminant=sd_ones(), k=None, shape=DEFAULT_SPECTRAL_SHAPE)
    • colour.colorimetry.adjust_tristimulus_weighting_factors_ASTME30815: (@KelSolaar)
      • Name: adjust_tristimulus_weighting_factors_ASTME308
    • colour.colorimetry.lagrange_coefficients_ASTME202211: (@KelSolaar)
      • Name: lagrange_coefficients_ASTME2022
    • colour.colorimetry.luminance_ASTMD153508: (@KelSolaar)
      • Name: luminance_ASTMD1535
    • colour.colorimetry.sd_to_XYZ_ASTME30815: (@KelSolaar)
      • Name: sd_to_XYZ_ASTME308
    • colour.colorimetry.sd_to_XYZ_tristimulus_weighting_factors_ASTME30815: (@KelSolaar)
      • Name: sd_to_XYZ_tristimulus_weighting_factors_ASTME308
    • colour.colorimetry.tristimulus_weighting_factors_ASTME202211: (@KelSolaar)
      • Name: tristimulus_weighting_factors_ASTME2022

    colour.continuous

    • ๐Ÿšฆ colour.continuous.MultiSignal: (@KelSolaar)
      • Name: MultiSignals

    colour.io

    • colour.read_image: (@KelSolaar)
      • Signature: read_image(path, method='OpenImageIO', **kwargs)
    • colour.write_image: (@KelSolaar)
      • Signature: write_image(image, path, method='OpenImageIO', **kwargs)

    colour.models

    • Various CCTF related objects, signatures and properties have been renamed for consistency purposes:
    • colour.ENCODING_CCTFS: (@KelSolaar)
      • Name: CCTF_ENCODINGS
    • colour.encoding_cctf: (@KelSolaar)
      • Name: cctf_encoding
    • colour.DECODING_CCTFS: (@KelSolaar)
      • Name: CCTF_DECODINGS
    • colour.decoding_cctf: (@KelSolaar)
      • Name: cctf_decoding
    • colour.RGB_Colourspace.encoding_cctf: (@KelSolaar)
      • Name: cctf_encoding
    • colour.RGB_Colourspace.decoding_cctf: (@KelSolaar)
      • Name: decoding_cctf
    • colour.XYZ_to_RGB: (@KelSolaar)
      • Signature: XYZ_to_RGB(XYZ, illuminant_XYZ, illuminant_RGB, XYZ_to_RGB_matrix, chromatic_adaptation_transform='CAT02', cctf_encoding=None, **kwargs)
    • colour.XYZ_to_RGB: (@KelSolaar)
      • Signature: RGB_to_XYZ(RGB, illuminant_RGB, illuminant_XYZ, RGB_to_XYZ_matrix, chromatic_adaptation_transform='CAT02', cctf_decoding=None, **kwargs)
    • colour.XYZ_to_sRGB: (@KelSolaar)
      • Signature: XYZ_to_sRGB(XYZ, illuminant=ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65'], chromatic_adaptation_transform='CAT02', apply_cctf_encoding=True, **kwargs)
    • colour.XYZ_to_sRGB: (@KelSolaar)
      • Signature: sRGB_to_XYZ(RGB, illuminant=ILLUMINANTS['CIE 1931 2 Degree Standard Observer']['D65'], chromatic_adaptation_method='CAT02', apply_cctf_decoding=True, **kwargs)

    The colour.RGB_to_RGB definition now accepts keyword arguments, they are filtered and passed accordingly to the decoding and encoding colour component transfer functions:

    colour.RGB_to_RGB: (@KelSolaar)

    - Signature: RGB_to_RGB(RGB, input_colourspace, output_colourspace, chromatic_adaptation_transform='CAT02', apply_decoding_cctf=False, apply_encoding_cctf=False, **kwargs)

    ๐ŸŒฒ Various log related objects and signatures have been renamed for consistency purposes:

    colour.log_decoding_curve: (@KelSolaar)

    • Name: colour.log_decoding

    - Signature: log_decoding(value, function='Cineon', **kwargs)

    colour.LOG_DECODING_CURVES: (@KelSolaar)

    - Name: colour.LOG_DECODINGS

    colour.log_encoding_curve: (@KelSolaar)

    • Name: colour.log_encoding

    - Signature: log_encoding(value, function='Cineon', **kwargs)

    colour.LOG_ENCODING_CURVES: (@KelSolaar)

    • Name: colour.LOG_ENCODINGS

    The IEC 61966-2-1:1999 standard does not actually define an OETF but and EOTF so the sRGB related definitions have been renamed accordingly:

    • colour.models.oetf_sRGB: (@KelSolaar)
      • Name: eotf_inverse_sRGB
    • colour.models.oetf_reverse_sRGB: (@KelSolaar)
      • Name: eotf_sRGB

    Various other colour component transfer functions objects have been either renamed or their signature changed:

    colour.eotf: (@KelSolaar)

    - Signature: eotf(value, function='ITU-R BT.1886', **kwargs)

    colour.EOTFS_REVERSE: (@KelSolaar)

    - Name: EOTF_INVERSES

    colour.eotf_reverse: (@KelSolaar)

    - Signature: eotf_inverse(value, function='ITU-R BT.1886', **kwargs)

    colour.oetf: (@KelSolaar)

    - Signature: oetf(value, function='ITU-R BT.709', **kwargs)

    colour.OETFS_REVERSE: (@KelSolaar)

    - Name: OETF_INVERSES

    colour.oetf_reverse: (@KelSolaar)

    - Signature: oetf_inverse(value, function='ITU-R BT.709', **kwargs)

    colour.OOTFS_REVERSE: (@KelSolaar)

    - Name: OOTF_INVERSES

    colour.models.oetf_DICOMGSDF: (@KelSolaar)

    - Name: eotf_inverse_DICOMGSDF

    colour.models.eotf_reverse_BT1886: (@KelSolaar)

    - Name: eotf_inverse_BT1886

    colour.models.eotf_reverse_DCDM: (@KelSolaar)

    - Name: eotf_inverse_DCDM

    colour.models.oetf_ST2084: (@KelSolaar)

    - Name: eotf_inverse_ST2084

    colour.models.oetf_reverse_ARIBSTDB67: (@KelSolaar)

    - Name: oetf_inverse_ARIBSTDB67

    colour.models.oetf_reverse_BT601: (@KelSolaar)

    - Name: oetf_inverse_BT601

    colour.models.oetf_reverse_BT709: (@KelSolaar)

    - Name: oetf_inverse_BT709

    colour.models.oetf_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: oetf_HLG_BT2100

    - Signature: oetf_HLG_BT2100(E, constants=BT2100_HLG_CONSTANTS)

    colour.models.oetf_reverse_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: oetf_inverse_HLG_BT2100

    - Signature: oetf_inverse_HLG_BT2100(E_p, constants=BT2100_HLG_CONSTANTS)

    colour.models.eotf_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: eotf_HLG_BT2100

    - Signature: eotf_HLG_BT2100(E_p, L_B=0, L_W=1000, gamma=None, constants=BT2100_HLG_CONSTANTS, method='ITU-R BT.2100-2')

    colour.models.eotf_reverse_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: eotf_inverse_HLG_BT2100

    - Signature: eotf_inverse_HLG_BT2100(F_D, L_B=0, L_W=1000, gamma=None, constants=BT2100_HLG_CONSTANTS, method='ITU-R BT.2100-2')

    colour.models.ootf_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: ootf_HLG_BT2100

    - Signature: ootf_HLG_BT2100(E, L_B=0, L_W=1000, gamma=None, method='ITU-R BT.2100-2')

    colour.models.ootf_reverse_BT2100_HLG: (@KelSolaar, @nick-shaw)

    • Name: ootf_inverse_HLG_BT2100

    - Signature: ootf_inverse_HLG_BT2100(F_D, L_B=0, gamma=None, method='ITU-R BT.2100-2')

    colour.models.oetf_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: oetf_PQ_BT2100

    colour.models.oetf_reverse_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: oetf_inverse_PQ_BT2100

    colour.models.eotf_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: eotf_PQ_BT2100

    colour.models.eotf_reverse_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: eotf_inverse_PQ_BT2100

    colour.models.ootf_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: ootf_PQ_BT2100

    colour.models.ootf_reverse_BT2100_PQ: (@KelSolaar, @nick-shaw)

    - Name: ootf_inverse_PQ_BT2100

    colour.models.log_encoding_Log3G10: (@KelSolaar)

    - Signature: log_encoding_Log3G10(x, method='v2', **kwargs)

    colour.models.log_decoding_Log3G10: (@KelSolaar)

    - Signature: log_decoding_Log3G10(y, method='v2', **kwargs)

    colour.models.log_encoding_CanonLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_CanonLog(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_CanonLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_CanonLog(clog, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.log_encoding_CanonLog2: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_CanonLog2(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_CanonLog2: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_CanonLog2(clog2, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.log_encoding_CanonLog3: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_CanonLog3(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_CanonLog3: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_CanonLog3(clog3, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.log_encoding_VLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_VLog(L_in, bit_depth=10, out_normalised_code_value=True, in_reflection=True, constants=VLOG_CONSTANTS, **kwargs)

    colour.models.log_decoding_VLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_VLog(V_out, bit_depth=10, in_normalised_code_value=True, out_reflection=True, constants=VLOG_CONSTANTS, **kwargs)

    colour.models.log_encoding_SLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_SLog(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_SLog: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_SLog(y, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.log_encoding_SLog2: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_SLog2(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_SLog2: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_SLog2(y, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.log_encoding_SLog3: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_encoding_SLog3(x, bit_depth=10, out_normalised_code_value=True, in_reflection=True, **kwargs)

    colour.models.log_decoding_SLog3: (@KelSolaar, @nick-shaw, @KevinJW)

    - Signature: log_decoding_SLog3(y, bit_depth=10, in_normalised_code_value=True, out_reflection=True, **kwargs)

    colour.models.oetf_ROMMRGB: (@KelSolaar)

    - Name: cctf_encoding_ROMMRGB

    colour.models.eotf_ROMMRGB: (@KelSolaar)

    - Name: cctf_decoding_ROMMRGB

    colour.models.oetf_ProPhotoRGB: (@KelSolaar)

    - Name: cctf_encoding_ProPhotoRGB

    colour.models.eotf_ProPhotoRGB: (@KelSolaar)

    - Name: cctf_decoding_ProPhotoRGB

    colour.models.oetf_RIMMRGB: (@KelSolaar)

    - Name: cctf_encoding_RIMMRGB

    colour.models.eotf_RIMMRGB: (@KelSolaar)

    - Name: cctf_decoding_RIMMRGB

    colour.models.XYZ_to_colourspace_model: (@feralpoosum)

    - Deprecated

    colour.models.NTSC_COLOURSPACE: (@KelSolaar)

    • Name: NTSC_1953_COLOURSPACE

    colour.notation

    • colour.notation.munsell_value_ASTMD153508: (@KelSolaar)
      • Name: munsell_value_ASTMD1535

    colour.plotting

    • colour.plotting.ASTM_G_173_DIRECT_CIRCUMSOLAR: (@KelSolaar)
      • Name: ASTMG173_DIRECT_CIRCUMSOLAR
    • colour.plotting.ASTM_G_173_ETR: (@KelSolaar)
      • Name: ASTMG173_ETR
    • colour.plotting.ASTM_G_173_GLOBAL_TILT: (@KelSolaar)
      • Name: ASTMG173_GLOBAL_TILT
    • colour.plotting.plot_single_sd_colour_quality_scale_bars: (@KelSolaar)
      • Signature: plot_single_sd_colour_quality_scale_bars(sd, method='NIST CQS 9.0', **kwargs)
    • colour.plotting.plot_multi_sds_colour_quality_scales_bars: (@KelSolaar)
      • Signature: plot_multi_sds_colour_quality_scales_bars(sds, method='NIST CQS 9.0', **kwargs)
    • colour.plotting.plot_planckian_locus_in_chromaticity_diagram_CIE1931: (@KelSolaar)
      • Signature: plot_planckian_locus_in_chromaticity_diagram_CIE1931(illuminants=None, annotate_parameters=None, chromaticity_diagram_callable_CIE1931=plot_chromaticity_diagram_CIE1931, planckian_locus_callable_CIE1931=plot_planckian_locus_CIE1931, **kwargs)
    • colour.plotting.plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS: (@KelSolaar)
      • Signature: plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(illuminants=None, annotate_parameters=None, chromaticity_diagram_callable_CIE1960UCS=plot_chromaticity_diagram_CIE1960UCS, planckian_locus_callable_CIE1960UCS=plot_planckian_locus_CIE1960UCS, **kwargs)

    colour.recovery

    • colour.recovery.XYZ_to_sd_Meng2015: (@KelSolaar)
      • Signature: XYZ_to_sd_Meng2015(XYZ, cmfs=STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer'].copy().align(DEFAULT_SPECTRAL_SHAPE_MENG_2015), illuminant=sd_ones(DEFAULT_SPECTRAL_SHAPE_MENG_2015), optimisation_parameters=None)

    colour.temperature

    • colour.xy_to_CCT: (@KelSolaar)
      • Signature: xy_to_CCT(xy, method='CIE Illuminant D Series')
    • colour.CCT_to_xy: (@KelSolaar)
      • Signature: CCT_to_xy(CCT, method='CIE Illuminant D Series')