Skip to content

PR: Implement support for "Camera RGB Sensitivities Recovery" using "Jiang, Liu, Gu and Süsstrunk (2013)" method.#1002

Merged
KelSolaar merged 5 commits intodevelopfrom
feature/jiang2013
Jul 2, 2022
Merged

PR: Implement support for "Camera RGB Sensitivities Recovery" using "Jiang, Liu, Gu and Süsstrunk (2013)" method.#1002
KelSolaar merged 5 commits intodevelopfrom
feature/jiang2013

Conversation

@KelSolaar
Copy link
Copy Markdown
Member

@KelSolaar KelSolaar commented Jun 27, 2022

Summary

This PR implements support for Camera RGB Sensitivities Recovery using Jiang, Liu, Gu and Süsstrunk (2013) method.
It, finally, integrates the related work from GSoC 2021 by Cedric @villirion Dollet and closes #803. This PR also supersedes #851.

I have computed the Eigen values (6 only) for the Dyer et al. (2017) (RAW to ACES) spectral database and included them in the colour.recovery.datasets.dyer2017 module.

Here is an example usage from scratch using all the available definitions:

import colour
import colour_datasets
import matplotlib.pyplot as plt

SHAPE = colour.SpectralShape(400, 700, 10)

DATABASE_CAMERA_SENSITIVITIES = colour_datasets.load(
    "Camera Spectral Sensitivity Database - Jiang et al. (2013)"
)
DATABASE_AMPAS_CAMERA_SENSITIVITIES = colour_datasets.load(
    "RAW to ACES Utility Data - Dyer et al. (2017)"
)

DATABASE = {
    camera: msds.copy().align(SHAPE)
    for camera, msds in DATABASE_AMPAS_CAMERA_SENSITIVITIES["camera"].items()
}

(RED_W, GREEN_W, BLUE_W), (RED_V, GREEN_V, BLUE_V) = colour.recovery.PCA_Jiang2013(
    DATABASE, 6, True
)

plt.plot(np.array(RED_W) * np.array(RED_V))
plt.plot(np.array(GREEN_W) * np.array(GREEN_V))
plt.plot(np.array(BLUE_W) * np.array(BLUE_V))
plt.show()

K = 0.01
ILLUMINANT = colour.SDS_ILLUMINANTS["D50"].copy().align(SHAPE).normalise()
CAMERA_SENSITIVITIES = (
    DATABASE_CAMERA_SENSITIVITIES["Canon 1DMarkIII"].copy().align(SHAPE)
)

MSDS_REFLECTANCES = colour.characterisation.read_training_data_rawtoaces_v1()
REFLECTANCES = np.transpose(MSDS_REFLECTANCES.copy().align(SHAPE).values)[
    np.newaxis, ...
]

RGB_REFLECTANCES_REFERENCE = np.squeeze(
    colour.msds_to_XYZ(
        REFLECTANCES,
        method="Integration",
        cmfs=CAMERA_SENSITIVITIES,
        illuminant=ILLUMINANT,
        k=K,
        shape=SHAPE,
    )
)

colour.plotting.plot_multi_colour_swatches(
    colour.cctf_encoding(RGB_REFLECTANCES_REFERENCE),
    columns=REFLECTANCES.shape[1] // 10,
)

colour.plotting.plot_multi_sds(MSDS_REFLECTANCES, legend=False)

BASIS_FUNCTIONS = np.transpose(np.array([RED_W, GREEN_W, BLUE_W]))

MSDS_CAMERA = colour.recovery.RGB_to_msds_camera_sensitivities_Jiang2013(
    RGB_REFLECTANCES_REFERENCE,
    ILLUMINANT,
    MSDS_REFLECTANCES,
    basis_functions=BASIS_FUNCTIONS,
)

plt.plot(
    CAMERA_SENSITIVITIES.signals[CAMERA_SENSITIVITIES.labels[0]].values,
    label="Red Reference",
)
plt.plot(MSDS_CAMERA.signals["red"].values, "--", label="Red Reconstructed")
plt.plot(
    CAMERA_SENSITIVITIES.signals[CAMERA_SENSITIVITIES.labels[1]].values,
    label="Green Reference",
)
plt.plot(MSDS_CAMERA.signals["green"].values, "--", label="Green Reconstructed")
plt.plot(
    CAMERA_SENSITIVITIES.signals[CAMERA_SENSITIVITIES.labels[2]].values,
    label="Blue Reference",
)
plt.plot(MSDS_CAMERA.signals["blue"].values, "--", label="Blue Reconstructed")
plt.legend()
plt.show()

RGB_REFLECTANCES_TEST = np.squeeze(
    colour.msds_to_XYZ(
        REFLECTANCES,
        method="Integration",
        cmfs=MSDS_CAMERA,
        illuminant=ILLUMINANT,
        k=K,
        shape=SHAPE,
    )
)

colour.plotting.plot_multi_colour_swatches(
    colour.cctf_encoding(RGB_REFLECTANCES_TEST),
    columns=REFLECTANCES.shape[1] // 10,
)

print(
    np.median(
        colour.delta_E(
            colour.convert(RGB_REFLECTANCES_TEST, "CIE XYZ", "CIE Lab"),
            colour.convert(RGB_REFLECTANCES_REFERENCE, "CIE XYZ", "CIE Lab"),
        )
    )
)

print(
    np.max(
        colour.delta_E(
            colour.convert(RGB_REFLECTANCES_TEST, "CIE XYZ", "CIE Lab"),
            colour.convert(RGB_REFLECTANCES_REFERENCE, "CIE XYZ", "CIE Lab"),
        )
    )
)

6 Eigen Values

image

Reference Reflectances

image

Reference RGB Values from Reflectances

image

Recovered Sensitivities

image

Test RGB Values from Reflectances

image

Delta E Mean & Max

0.0112354575593
0.036650877434

Preflight

Code Style and Quality

  • Unit tests have been implemented and passed.
  • Mypy static checking has been run and passed.
  • Pre-commit hooks have been run and passed.
  • [N/A] New transformations have been added to the Automatic Colour Conversion Graph.
  • New transformations have been exported to the relevant namespaces, e.g. colour, colour.models.

Documentation

  • New features are documented along with examples if relevant.
  • The documentation is Sphinx and numpydoc compliant.

@coveralls
Copy link
Copy Markdown

coveralls commented Jun 27, 2022

Coverage Status

Coverage increased (+0.006%) to 99.859% when pulling e6eb666 on feature/jiang2013 into 052a9ed on develop.

@KelSolaar KelSolaar force-pushed the feature/jiang2013 branch from 7e655b4 to e6eb666 Compare June 28, 2022 06:42
@KelSolaar
Copy link
Copy Markdown
Member Author

Merging this one!

@KelSolaar KelSolaar merged commit b663d83 into develop Jul 2, 2022
@KelSolaar KelSolaar deleted the feature/jiang2013 branch July 2, 2022 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement support for "What is the Space of Spectral Sensitivity Functions for Digital Color Cameras".

2 participants