Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Implement support for "Numpy" 1.24.0. #1087

Merged
merged 2 commits into from
Dec 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions BIBLIOGRAPHY.bib
Original file line number Diff line number Diff line change
Expand Up @@ -2132,12 +2132,6 @@ @misc{Lindbloom2009d
year = 2009,
howpublished = {http://www.brucelindbloom.com/Eqn\_xyY\_to\_XYZ.html},
}
@misc{Lindbloom2009e,
title = {Delta {{E}} ({{CIE}} 2000)},
author = {Lindbloom, Bruce},
year = 2009,
howpublished = {http://brucelindbloom.com/Eqn\_DeltaE\_CIE2000.html},
}
@misc{Lindbloom2009f,
title = {Delta {{E}} ({{CMC}})},
author = {Lindbloom, Bruce},
Expand Down
19 changes: 10 additions & 9 deletions colour/characterisation/correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from colour.hints import ArrayLike, Any, Literal, NDArrayFloat, Union
from colour.utilities import (
CanonicalMapping,
as_float,
as_float_array,
as_int,
closest,
Expand Down Expand Up @@ -414,9 +415,9 @@ def polynomial_expansion_Finlayson2015(
if root_polynomial_expansion:
return tstack(
[
R,
G,
B,
as_float(R),
as_float(G),
as_float(B),
spow(R * G, 1 / 2),
spow(G * B, 1 / 2),
spow(R * B, 1 / 2),
Expand All @@ -441,9 +442,9 @@ def polynomial_expansion_Finlayson2015(
if root_polynomial_expansion:
return tstack(
[
R,
G,
B,
as_float(R),
as_float(G),
as_float(B),
spow(R * G, 1 / 2),
spow(G * B, 1 / 2),
spow(R * B, 1 / 2),
Expand Down Expand Up @@ -484,9 +485,9 @@ def polynomial_expansion_Finlayson2015(
if root_polynomial_expansion:
return tstack(
[
R,
G,
B,
as_float(R),
as_float(G),
as_float(B),
spow(R * G, 1 / 2),
spow(G * B, 1 / 2),
spow(R * B, 1 / 2),
Expand Down
24 changes: 12 additions & 12 deletions colour/characterisation/tests/test_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,8 @@ def test_nan_matrix_colour_correction_Cheung2004(self): # pragma: no cover
matrix_colour_correction_Cheung2004` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down Expand Up @@ -790,8 +790,8 @@ def test_nan_matrix_colour_correction_Finlayson2015(
matrix_colour_correction_Finlayson2015` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down Expand Up @@ -888,8 +888,8 @@ def test_nan_matrix_colour_correction_Vandermonde(
matrix_colour_correction_Vandermonde` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down Expand Up @@ -966,8 +966,8 @@ def test_nan_colour_correction_Cheung2004(self): # pragma: no cover
colour_correction_Cheung2004` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down Expand Up @@ -1051,8 +1051,8 @@ def test_nan_colour_correction_Finlayson2015(self): # pragma: no cover
colour_correction_Finlayson2015` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down Expand Up @@ -1130,8 +1130,8 @@ def test_nan_colour_correction_Vandermonde(self): # pragma: no cover
colour_correction_Vandermonde` definition nan support.
"""

# NOTE: Hangs on "Linux".
if platform.system() == "Linux":
# NOTE: Hangs on "macOS" and "Linux".
if platform.system() in ("Darwin", "Linux"):
return

cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
Expand Down
135 changes: 83 additions & 52 deletions colour/difference/delta_e.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
- :cite:`Lindbloom2003c` : Lindbloom, B. (2003). Delta E (CIE 1976).
Retrieved February 24, 2014, from
http://brucelindbloom.com/Eqn_DeltaE_CIE76.html
- :cite:`Lindbloom2009e` : Lindbloom, B. (2009). Delta E (CIE 2000).
Retrieved February 24, 2014, from
http://brucelindbloom.com/Eqn_DeltaE_CIE2000.html
- :cite:`Lindbloom2009f` : Lindbloom, B. (2009). Delta E (CMC). Retrieved
February 24, 2014, from http://brucelindbloom.com/Eqn_DeltaE_CMC.html
- :cite:`Lindbloom2011a` : Lindbloom, B. (2011). Delta E (CIE 1994).
Expand All @@ -34,6 +31,10 @@
- :cite:`Melgosa2013b` : Melgosa, M. (2013). CIE / ISO new standard:
CIEDE2000. http://www.color.org/events/colorimetry/\
Melgosa_CIEDE2000_Workshop-July4.pdf
- :cite:`Sharma2005b` : Sharma, G., Wu, W., & Dalal, E. N. (2005). The
CIEDE2000 color-difference formula: Implementation notes, supplementary
test data, and mathematical observations. Color Research & Application,
30(1), 21-30. doi:10.1002/col.20070
- :cite:`Mokrzycki2011` : Mokrzycki, W., & Tatol, M. (2011). Color difference
Delta E - A survey. Machine Graphics and Vision, 20, 383-411.
"""
Expand Down Expand Up @@ -292,7 +293,7 @@ def delta_E_CIE2000(

References
----------
:cite:`Lindbloom2009e`, :cite:`Melgosa2013b`
:cite:`Melgosa2013b`, :cite:`Sharma2005b`

Examples
--------
Expand All @@ -314,72 +315,102 @@ def delta_E_CIE2000(
k_C = 1
k_H = 1

l_bar_prime = 0.5 * (L_1 + L_2)
C_1_ab = np.hypot(a_1, b_1)
C_2_ab = np.hypot(a_2, b_2)

c_1 = np.hypot(a_1, b_1)
c_2 = np.hypot(a_2, b_2)
C_bar_ab = (C_1_ab + C_2_ab) / 2
C_bar_ab_7 = C_bar_ab**7

c_bar = 0.5 * (c_1 + c_2)
c_bar7 = c_bar**7
G = 0.5 * (1 - np.sqrt(C_bar_ab_7 / (C_bar_ab_7 + 25**7)))

g = 0.5 * (1 - np.sqrt(c_bar7 / (c_bar7 + 25**7)))
a_p_1 = (1 + G) * a_1
a_p_2 = (1 + G) * a_2

a_1_prime = a_1 * (1 + g)
a_2_prime = a_2 * (1 + g)
c_1_prime = np.hypot(a_1_prime, b_1)
c_2_prime = np.hypot(a_2_prime, b_2)
c_bar_prime = 0.5 * (c_1_prime + c_2_prime)
C_p_1 = np.hypot(a_p_1, b_1)
C_p_2 = np.hypot(a_p_2, b_2)

h_p_1 = np.where(
np.logical_and(b_1 == 0, a_p_1 == 0),
0,
np.degrees(np.arctan2(b_1, a_p_1)) % 360,
)
h_p_2 = np.where(
np.logical_and(b_2 == 0, a_p_2 == 0),
0,
np.degrees(np.arctan2(b_2, a_p_2)) % 360,
)

h_1_prime = np.degrees(np.arctan2(b_1, a_1_prime)) % 360
h_2_prime = np.degrees(np.arctan2(b_2, a_2_prime)) % 360
delta_L_p = L_2 - L_1

delta_C_p = C_p_2 - C_p_1

h_p_2_s_1 = h_p_2 - h_p_1
C_p_1_m_2 = C_p_1 * C_p_2
delta_h_p = np.select(
[
C_p_1_m_2 == 0,
np.fabs(h_p_2_s_1) <= 180,
h_p_2_s_1 > 180,
h_p_2_s_1 < -180,
],
[
0,
h_p_2_s_1,
h_p_2_s_1 - 360,
h_p_2_s_1 + 360,
],
)

h_bar_prime = np.where(
np.fabs(h_1_prime - h_2_prime) <= 180,
0.5 * (h_1_prime + h_2_prime),
(0.5 * (h_1_prime + h_2_prime + 360)),
delta_H_p = 2 * np.sqrt(C_p_1_m_2) * np.sin(np.deg2rad(delta_h_p / 2))

L_bar_p = (L_1 + L_2) / 2

C_bar_p = (C_p_1 + C_p_2) / 2

a_h_p_1_s_2 = np.fabs(h_p_1 - h_p_2)
h_p_1_a_2 = h_p_1 + h_p_2
h_bar_p = np.select(
[
C_p_1_m_2 == 0,
a_h_p_1_s_2 <= 180,
np.logical_and(a_h_p_1_s_2 > 180, h_p_1_a_2 < 360),
np.logical_and(a_h_p_1_s_2 > 180, h_p_1_a_2 >= 360),
],
[
h_p_1_a_2,
h_p_1_a_2 / 2,
(h_p_1_a_2 + 360) / 2,
(h_p_1_a_2 - 360) / 2,
],
)

t = (
T = (
1
- 0.17 * np.cos(np.deg2rad(h_bar_prime - 30))
+ 0.24 * np.cos(np.deg2rad(2 * h_bar_prime))
+ 0.32 * np.cos(np.deg2rad(3 * h_bar_prime + 6))
- 0.20 * np.cos(np.deg2rad(4 * h_bar_prime - 63))
- 0.17 * np.cos(np.deg2rad(h_bar_p - 30))
+ 0.24 * np.cos(np.deg2rad(2 * h_bar_p))
+ 0.32 * np.cos(np.deg2rad(3 * h_bar_p + 6))
- 0.20 * np.cos(np.deg2rad(4 * h_bar_p - 63))
)

h = h_2_prime - h_1_prime
delta_h_prime = np.where(h_2_prime <= h_1_prime, h - 360, h + 360)
delta_h_prime = np.where(np.fabs(h) <= 180, h, delta_h_prime)
delta_theta = 30 * np.exp(-(((h_bar_p - 275) / 25) ** 2))

delta_L_prime = L_2 - L_1
delta_C_prime = c_2_prime - c_1_prime
delta_H_prime = (
2
* np.sqrt(c_1_prime * c_2_prime)
* np.sin(np.deg2rad(0.5 * delta_h_prime))
)
C_bar_p_7 = C_bar_p**7
R_C = 2 * np.sqrt(C_bar_p_7 / (C_bar_p_7 + 25**7))

s_L = 1 + (
(0.015 * (l_bar_prime - 50) * (l_bar_prime - 50))
/ np.sqrt(20 + (l_bar_prime - 50) * (l_bar_prime - 50))
)
s_C = 1 + 0.045 * c_bar_prime
s_H = 1 + 0.015 * c_bar_prime * t
L_bar_p_2 = (L_bar_p - 50) ** 2
S_L = 1 + ((0.015 * L_bar_p_2) / np.sqrt(20 + L_bar_p_2))

delta_theta = 30 * np.exp(
-((h_bar_prime - 275) / 25) * ((h_bar_prime - 275) / 25)
)
S_C = 1 + 0.045 * C_bar_p

c_bar_prime7 = c_bar_prime**7
S_H = 1 + 0.015 * C_bar_p * T

r_C = np.sqrt(c_bar_prime7 / (c_bar_prime7 + 25**7))
r_T = -2 * r_C * np.sin(np.deg2rad(2 * delta_theta))
R_T = -np.sin(np.deg2rad(2 * delta_theta)) * R_C

d_E = np.sqrt(
(delta_L_prime / (k_L * s_L)) ** 2
+ (delta_C_prime / (k_C * s_C)) ** 2
+ (delta_H_prime / (k_H * s_H)) ** 2
+ (delta_C_prime / (k_C * s_C)) * (delta_H_prime / (k_H * s_H)) * r_T
(delta_L_p / (k_L * S_L)) ** 2
+ (delta_C_p / (k_C * S_C)) ** 2
+ (delta_H_p / (k_H * S_H)) ** 2
+ R_T * (delta_C_p / (k_C * S_C)) * (delta_H_p / (k_H * S_H))
)

return as_float(d_E)
Expand Down
48 changes: 43 additions & 5 deletions colour/difference/tests/test_delta_e.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def test_delta_E_CIE2000(self):
np.array([100.00000000, 21.57210357, 272.22819350]),
np.array([100.00000000, 8.32281957, -73.58297716]),
),
68.23094879,
68.23111251,
places=7,
)

Expand Down Expand Up @@ -285,7 +285,7 @@ def test_delta_E_CIE2000(self):
np.array([50.00000000, 8.32281957, -73.58297716]),
textiles=True,
),
70.63198003,
70.63213819,
places=7,
)

Expand Down Expand Up @@ -353,6 +353,44 @@ def test_delta_E_CIE2000_Sharma2004(self):
:cite:`Sharma2005b`
"""

# NOTE: The 14th test case is excluded as "Numpy" 1.24.0 introduced
# numerical differences between "Linux" and "macOS / Windows" with the
# "np.arctan2" definition :
#
# | Ubuntu | macOS / Windows |
# C_1_ab | 2.490000200803205 | 2.490000200803205 |
# C_2_ab | 2.490000200803205 | 2.490000200803205 |
# C_bar_ab | 2.490000200803205 | 2.490000200803205 |
# C_bar_ab_7 | 593.465770158617033 | 593.465770158617033 |
# G | 0.499844088629080 | 0.499844088629080 |
# a_p_1 | -0.001499844088629 | -0.001499844088629 |
# a_p_2 | 0.001499844088629 | 0.001499844088629 |
# C_p_1 | 2.490000451713271 | 2.490000451713271 |
# C_p_2 | 2.490000451713271 | 2.490000451713271 |
# h_p_1 | 90.034511938077543 | 90.034511938077557 | <--
# h_p_2 | 270.034511938077571 | 270.034511938077571 |
# delta_L_p | 0.000000000000000 | 0.000000000000000 |
# delta_C_p | 0.000000000000000 | 0.000000000000000 |
# h_p_2_s_1 | 180.000000000000028 | 180.000000000000000 | <--
# C_p_1_m_2 | 6.200102249532291 | 6.200102249532291 |
# delta_h_p | -179.999999999999972 | 180.000000000000000 | <--
# delta_H_p | -4.980000903426540 | 4.980000903426541 | <--
# L_bar_p | 50.000000000000000 | 50.000000000000000 |
# C_bar_p | 2.490000451713271 | 2.490000451713271 |
# a_h_p_1_s_2 | 180.000000000000028 | 180.000000000000000 | <--
# h_p_1_a_2 | 360.069023876155143 | 360.069023876155143 |
# h_bar_p | 0.034511938077571 | 180.034511938077571 |
# T | 1.319683185432364 | 0.977862082189372 | <--
# delta_theta | 0.000000000000000 | 0.000016235458767 | <--
# C_bar_p_7 | 593.466188771459770 | 593.466188771459770 |
# R_C | 0.000623645703630 | 0.000623645703630 |
# L_bar_p_2 | 0.000000000000000 | 0.000000000000000 |
# S_L | 1.000000000000000 | 1.000000000000000 |
# S_C | 1.112050020327097 | 1.112050020327097 |
# S_H | 1.049290175917675 | 1.036523155395472 | <--
# R_T | -0.000000000000000 | -0.000000000353435 | <--
# d_E | 4.746066453039259 | 4.804524508211768 | <--

Lab_1 = np.array(
[
[50.0000, 2.6772, -79.7751],
Expand All @@ -368,7 +406,7 @@ def test_delta_E_CIE2000_Sharma2004(self):
[50.0000, 2.4900, -0.0010],
[50.0000, 2.4900, -0.0010],
[50.0000, -0.0010, 2.4900],
[50.0000, -0.0010, 2.4900],
# [50.0000, -0.0010, 2.4900],
[50.0000, -0.0010, 2.4900],
[50.0000, 2.5000, 0.0000],
[50.0000, 2.5000, 0.0000],
Expand Down Expand Up @@ -407,7 +445,7 @@ def test_delta_E_CIE2000_Sharma2004(self):
[50.0000, -2.4900, 0.0011],
[50.0000, -2.4900, 0.0012],
[50.0000, 0.0009, -2.4900],
[50.0000, 0.0010, -2.4900],
# [50.0000, 0.0010, -2.4900],
[50.0000, 0.0011, -2.4900],
[50.0000, 0.0000, -2.5000],
[73.0000, 25.0000, -18.0000],
Expand Down Expand Up @@ -446,7 +484,7 @@ def test_delta_E_CIE2000_Sharma2004(self):
7.2195,
7.2195,
4.8045,
4.8045,
# 4.8045,
4.7461,
4.3065,
27.1492,
Expand Down
Loading