Coverage for colour/difference/stress.py: 100%
25 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
1"""
2Standardized Residual Sum of Squares (STRESS) Index
3===================================================
5Define the *Kruskal's Standardized Residual Sum of Squares (:math:`STRESS`)*
6index:
8- :func:`colour.index_stress_Garcia2007`: :math:`STRESS` index computation
9 according to *García, Huertas, Melgosa and Cui (2007)* method.
10- :func:`colour.index_stress`: *lightness* :math:`STRESS` index computation
11 using the specified method.
13References
14----------
15- :cite:`Garcia2007` : García, P. A., Huertas, R., Melgosa, M., & Cui, G.
16 (2007). Measurement of the relationship between perceived and computed
17 color differences. Journal of the Optical Society of America A, 24(7),
18 1823. doi:10.1364/JOSAA.24.001823
19"""
21from __future__ import annotations
23import typing
25import numpy as np
27from colour.algebra import sdiv, sdiv_mode
29if typing.TYPE_CHECKING:
30 from colour.hints import ArrayLike, Literal, NDArrayFloat
32from colour.utilities import CanonicalMapping, as_float, as_float_array, validate_method
34__author__ = "Colour Developers"
35__copyright__ = "Copyright 2013 Colour Developers"
36__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
37__maintainer__ = "Colour Developers"
38__email__ = "colour-developers@colour-science.org"
39__status__ = "Production"
41__all__ = [
42 "index_stress_Garcia2007",
43 "INDEX_STRESS_METHODS",
44 "index_stress",
45]
48def index_stress_Garcia2007(d_E: ArrayLike, d_V: ArrayLike) -> NDArrayFloat:
49 """
50 Compute the *Kruskal's Standardized Residual Sum of Squares
51 (:math:`STRESS`)* index according to the *García, Huertas, Melgosa and
52 Cui (2007)* method.
54 Parameters
55 ----------
56 d_E
57 Computed colour difference array :math:`\\Delta E`.
58 d_V
59 Computed colour difference array :math:`\\Delta V`.
61 Returns
62 -------
63 :class:`numpy.ndarray`
64 :math:`STRESS` index.
66 References
67 ----------
68 :cite:`Garcia2007`
70 Examples
71 --------
72 >>> d_E = np.array([2.0425, 2.8615, 3.4412])
73 >>> d_V = np.array([1.2644, 1.2630, 1.8731])
74 >>> index_stress_Garcia2007(d_E, d_V) # doctest: +ELLIPSIS
75 0.1211709...
76 """
78 d_E = as_float_array(d_E)
79 d_V = as_float_array(d_V)
81 with sdiv_mode():
82 F_1 = sdiv(np.sum(d_E**2), np.sum(d_E * d_V))
84 stress = np.sqrt(sdiv(np.sum((d_E - F_1 * d_V) ** 2), np.sum(F_1**2 * d_V**2)))
86 return as_float(stress)
89INDEX_STRESS_METHODS: CanonicalMapping = CanonicalMapping(
90 {
91 "Garcia 2007": index_stress_Garcia2007,
92 }
93)
94INDEX_STRESS_METHODS.__doc__ = """
95Supported *Standardized Residual Sum of Squares* (*STRESS*) index
96computation methods.
98References
99----------
100:cite:`Garcia2007`
101"""
104def index_stress(
105 d_E: ArrayLike,
106 d_V: ArrayLike,
107 method: Literal["Garcia 2007"] | str = "Garcia 2007",
108) -> NDArrayFloat:
109 """
110 Compute *Kruskal's Standardized Residual Sum of Squares*
111 (:math:`STRESS`) index using the specified method
113 Parameters
114 ----------
115 d_E
116 Computed colour difference array :math:`\\Delta E`.
117 d_V
118 Computed colour difference array :math:`\\Delta V`.
119 method
120 Computation method.
122 Returns
123 -------
124 :class:`numpy.ndarray`
125 :math:`STRESS` index.
127 References
128 ----------
129 :cite:`Garcia2007`
131 Examples
132 --------
133 >>> d_E = np.array([2.0425, 2.8615, 3.4412])
134 >>> d_V = np.array([1.2644, 1.2630, 1.8731])
135 >>> index_stress(d_E, d_V) # doctest: +ELLIPSIS
136 0.1211709...
137 """
139 method = validate_method(method, tuple(INDEX_STRESS_METHODS))
141 function = INDEX_STRESS_METHODS[method]
143 return function(d_E, d_V)