Skip to content

Commit

Permalink
Merge branch 'feature/idt_improvements' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar committed Mar 4, 2021
2 parents b93e961 + 59253fd commit e9c8834
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 12 deletions.
66 changes: 54 additions & 12 deletions colour/characterisation/aces_it.py
Expand Up @@ -476,7 +476,10 @@ def normalise_illuminant(illuminant, sensitivities):
return illuminant * k


def training_data_sds_to_RGB(training_data, sensitivities, illuminant):
def training_data_sds_to_RGB(training_data,
sensitivities,
illuminant,
additional_data=False):
"""
Converts given training data to *RGB* tristimulus values using given
illuminant and given camera *RGB* spectral sensitivities.
Expand All @@ -489,11 +492,14 @@ def training_data_sds_to_RGB(training_data, sensitivities, illuminant):
Camera *RGB* spectral sensitivities.
illuminant : SpectralDistribution
Illuminant spectral distribution.
additional_data : bool, optional
If *True*, the white balance multipliers are returned.
Returns
-------
ndarray
Training data *RGB* tristimulus values.
ndarray or tuple
Training data *RGB* tristimulus values or tuple of training data *RGB*
tristimulus values and white balance multipliers.
Examples
--------
Expand Down Expand Up @@ -533,10 +539,16 @@ def training_data_sds_to_RGB(training_data, sensitivities, illuminant):
sensitivities.values)
RGB *= RGB_w

return RGB
if additional_data:
return RGB, RGB_w
else:
return RGB


def training_data_sds_to_XYZ(training_data, cmfs, illuminant):
def training_data_sds_to_XYZ(training_data,
cmfs,
illuminant,
chromatic_adaptation_transform='CAT02'):
"""
Converts given training data to *CIE XYZ* tristimulus values using given
illuminant and given standard observer colour matching functions.
Expand All @@ -549,6 +561,12 @@ def training_data_sds_to_XYZ(training_data, cmfs, illuminant):
Standard observer colour matching functions.
illuminant : SpectralDistribution
Illuminant spectral distribution.
chromatic_adaptation_transform : unicode, optional
**{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02 Brill 2008',
'Bianco 2010', 'Bianco PC 2010', None}**,
*Chromatic adaptation* transform, if *None* no chromatic adaptation is
performed.
Returns
-------
Expand Down Expand Up @@ -597,7 +615,8 @@ def training_data_sds_to_XYZ(training_data, cmfs, illuminant):
XYZ_w *= 1 / XYZ_w[1]

M_CAT = matrix_chromatic_adaptation_VonKries(
XYZ_w, xy_to_XYZ(RGB_COLOURSPACE_ACES2065_1.whitepoint))
XYZ_w, xy_to_XYZ(RGB_COLOURSPACE_ACES2065_1.whitepoint),
chromatic_adaptation_transform)

XYZ = vector_dot(M_CAT, XYZ)

Expand Down Expand Up @@ -706,7 +725,9 @@ def matrix_idt(sensitivities,
cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer'].copy()
.align(SPECTRAL_SHAPE_RAWTOACES),
optimisation_factory=optimisation_factory_rawtoaces_v1,
optimisation_kwargs=None):
optimisation_kwargs=None,
chromatic_adaptation_transform='CAT02',
additional_data=False):
"""
Computes an *Input Device Transform* (IDT) matrix for given camera *RGB*
spectral sensitivities, illuminant, training data, standard observer colour
Expand All @@ -729,11 +750,22 @@ def matrix_idt(sensitivities,
optimisation colour model function.
optimisation_kwargs : dict_like, optional
Parameters for :func:`scipy.optimize.minimize` definition.
chromatic_adaptation_transform : unicode, optional
**{'CAT02', 'XYZ Scaling', 'Von Kries', 'Bradford', 'Sharp',
'Fairchild', 'CMCCAT97', 'CMCCAT2000', 'CAT02 Brill 2008',
'Bianco 2010', 'Bianco PC 2010', None}**,
*Chromatic adaptation* transform, if *None* no chromatic adaptation is
performed.
additional_data : bool, optional
If *True*, the *XYZ* and *RGB* tristimulus values and the white balance
multipliers are returned.
Returns
-------
ndarray
*Input Device Transform* (IDT) matrix.
ndarray or tuple
*Input Device Transform* (IDT) matrix or tuple of
*Input Device Transform* (IDT) matrix, *XYZ* and *RGB* tristimulus
values and white balance multipliers.
References
----------
Expand Down Expand Up @@ -793,8 +825,15 @@ def matrix_idt(sensitivities,

illuminant = normalise_illuminant(illuminant, sensitivities)

RGB = training_data_sds_to_RGB(training_data, sensitivities, illuminant)
XYZ = training_data_sds_to_XYZ(training_data, cmfs, illuminant)
if additional_data:
RGB, RGB_w = training_data_sds_to_RGB(training_data, sensitivities,
illuminant, additional_data)
else:
RGB = training_data_sds_to_RGB(training_data, sensitivities,
illuminant)

XYZ = training_data_sds_to_XYZ(training_data, cmfs, illuminant,
chromatic_adaptation_transform)

objective_function, XYZ_to_optimization_colour_model = (
optimisation_factory())
Expand All @@ -809,4 +848,7 @@ def matrix_idt(sensitivities,
(RGB, XYZ_to_optimization_colour_model(XYZ)),
**optimisation_settings).x.reshape([3, 3])

return M
if additional_data:
return M, XYZ, RGB, RGB_w
else:
return M
84 changes: 84 additions & 0 deletions colour/characterisation/tests/test_aces_it.py
Expand Up @@ -478,6 +478,15 @@ def test_training_data_sds_to_RGB(self):
]),
decimal=7)

np.testing.assert_almost_equal(
training_data_sds_to_RGB(
training_data,
MSDS_CANON_EOS_5DMARK_II,
SDS_ILLUMINANTS['D55'],
additional_data=True)[-1],
np.array([2.34141541, 1.00000000, 1.51633759]),
decimal=7)


class TestTrainingDataSdsToXYZ(unittest.TestCase):
"""
Expand Down Expand Up @@ -726,6 +735,40 @@ def test_training_data_sds_to_XYZ(self):
]),
decimal=7)

np.testing.assert_almost_equal(
training_data_sds_to_XYZ(
training_data,
MSDS_CMFS['CIE 1931 2 Degree Standard Observer'],
SDS_ILLUMINANTS['D55'],
chromatic_adaptation_transform='Bradford'),
np.array([
[0.11386557, 0.10185906, 0.06306965],
[0.38044920, 0.34846911, 0.23548776],
[0.17349711, 0.18690409, 0.31901794],
[0.10656174, 0.13314825, 0.06450454],
[0.24642109, 0.23388536, 0.40625776],
[0.30564803, 0.42194543, 0.41894818],
[0.38414010, 0.30337780, 0.05881558],
[0.13128440, 0.11682332, 0.35780551],
[0.28707604, 0.19200780, 0.12518610],
[0.08392779, 0.06409174, 0.12816180],
[0.34028525, 0.44190577, 0.10665985],
[0.46462806, 0.42722924, 0.07207641],
[0.07631823, 0.06018898, 0.26258457],
[0.14620929, 0.23222248, 0.09296807],
[0.20635082, 0.12152088, 0.04669974],
[0.57410962, 0.59968182, 0.08713069],
[0.30185180, 0.19675858, 0.28565273],
[0.14177898, 0.19541060, 0.36711242],
[0.86550834, 0.91247072, 0.88567193],
[0.55803077, 0.58853268, 0.59040518],
[0.34102300, 0.35952246, 0.36250826],
[0.18104563, 0.19123690, 0.19353274],
[0.08461039, 0.08944568, 0.09150425],
[0.03058222, 0.03200864, 0.03278183],
]),
decimal=7)


class TestOptimizationFactoryRawtoacesV1(unittest.TestCase):
"""
Expand Down Expand Up @@ -845,6 +888,47 @@ def test_matrix_idt(self):
rtol=0.0001,
atol=0.0001)

np.testing.assert_allclose(
matrix_idt(
MSDS_CANON_EOS_5DMARK_II,
SDS_ILLUMINANTS['D55'],
chromatic_adaptation_transform='Bradford'),
np.array([
[0.85020607, -0.01371074, 0.14907913],
[0.05074081, 1.12898863, -0.18800656],
[0.02095822, -0.20110079, 1.16769711],
]),
rtol=0.0001,
atol=0.0001)

_M, XYZ, RGB, RGB_w = matrix_idt(
MSDS_CANON_EOS_5DMARK_II,
SDS_ILLUMINANTS['D55'],
additional_data=True)

np.testing.assert_almost_equal(
XYZ[:5, ...],
np.array([
[0.01743160, 0.01794927, 0.01960625],
[0.08556139, 0.08957352, 0.09017387],
[0.74560311, 0.78175547, 0.78350814],
[0.19005289, 0.19950000, 0.20126062],
[0.56264334, 0.59145486, 0.58950505],
]))

np.testing.assert_almost_equal(
RGB[:5, ...],
np.array([
[0.02075823, 0.01968577, 0.02139352],
[0.08957758, 0.08919227, 0.08910910],
[0.78102307, 0.78019384, 0.77643020],
[0.19950000, 0.19950000, 0.19950000],
[0.58984787, 0.59040152, 0.58510766],
]))

np.testing.assert_almost_equal(
RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]))


if __name__ == '__main__':
unittest.main()

0 comments on commit e9c8834

Please sign in to comment.