def test_nan_polar_to_cartesian(self): """ Tests :func:`colour.algebra.coordinates.transformations.\ polar_to_cartesian` definition nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = set(permutations(cases * 3, r=2)) for case in cases: a_i = np.array(case) polar_to_cartesian(a_i)
def final_opponent_signals(C_L, h_L): """ Returns the final opponent signals :math:`A_L` and :math:`B_L`. Parameters ---------- C_L : numeric or array_like Correlate of *colourfulness* :math:`C_L`. h_L : numeric or array_like Correlate of *hue* :math:`h_L` in degrees. Returns ------- ndarray Final opponent signals :math:`A_L` and :math:`B_L`. Examples -------- >>> C_L = 0.0183832899143 >>> h_L = 229.46357270858391 >>> final_opponent_signals(C_L, h_L) # doctest: +ELLIPSIS array([-0.0119478..., -0.0139711...]) """ AB_L = polar_to_cartesian(tstack([C_L, np.radians(h_L)])) return AB_L
def LCHuv_to_Luv(LCHuv): """ Converts from *CIE LCHuv* colourspace to *CIE Luv* colourspace. Parameters ---------- LCHuv : array_like *CIE LCHuv* colourspace array. Returns ------- ndarray *CIE Luv* colourspace array. Notes ----- - Input / output :math:`L^*` is in domain / range [0, 100]. Examples -------- >>> LCHuv = np.array([37.98562910, 28.83419279, 182.69946404]) >>> LCHuv_to_Luv(LCHuv) # doctest: +ELLIPSIS array([ 37.9856291..., -28.8021959..., -1.3580070...]) """ L, C, H = tsplit(LCHuv) u, v = tsplit(polar_to_cartesian(tstack((C, np.radians(H))))) Luv = tstack((L, u, v)) return Luv
def test_n_dimensional_polar_to_cartesian(self): """ Test :func:`colour.algebra.coordinates.transformations.\ polar_to_cartesian` definition n-dimensional arrays support. """ a_i = np.array([3.16227766, 0.32175055]) a_o = polar_to_cartesian(a_i) a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) np.testing.assert_almost_equal(polar_to_cartesian(a_i), a_o, decimal=7) a_i = np.reshape(a_i, (2, 3, 2)) a_o = np.reshape(a_o, (2, 3, 2)) np.testing.assert_almost_equal(polar_to_cartesian(a_i), a_o, decimal=7)
def final_opponent_signals(C_L: FloatingOrArrayLike, h_L: FloatingOrArrayLike) -> NDArray: """ Return the final opponent signals :math:`A_L` and :math:`B_L`. Parameters ---------- C_L Correlate of *colourfulness* :math:`C_L`. h_L Correlate of *hue* :math:`h_L` in degrees. Returns ------- :class:`numpy.ndarray` Final opponent signals :math:`A_L` and :math:`B_L`. Examples -------- >>> C_L = 0.0183832899143 >>> h_L = 229.46357270858391 >>> final_opponent_signals(C_L, h_L) # doctest: +ELLIPSIS array([-0.0119478..., -0.0139711...]) """ AB_L = polar_to_cartesian(tstack([as_float_array(C_L), np.radians(h_L)])) return AB_L
def LCHab_to_Lab(LCHab): """ Converts from *CIE LCHab* colourspace to *CIE Lab* colourspace. Parameters ---------- LCHab : array_like *CIE LCHab* colourspace array. Returns ------- ndarray *CIE Lab* colourspace array. Notes ----- - *Lightness* :math:`L^*` is in domain [0, 100]. Examples -------- >>> LCHab = np.array([37.98562910, 24.03845422, 190.58923377]) >>> LCHab_to_Lab(LCHab) # doctest: +ELLIPSIS array([ 37.9856291..., -23.6290768..., -4.4174661...]) """ L, C, H = tsplit(LCHab) a, b = tsplit(polar_to_cartesian(tstack((C, np.radians(H))))) Lab = tstack((L, a, b)) return Lab
def final_opponent_signals(C_L, h_L): """ Returns the final opponent signals :math:`A_L` and :math:`B_L`. Parameters ---------- C_L : numeric or array_like Correlate of *colourfulness* :math:`C_L`. h_L : numeric or array_like Correlate of *hue* :math:`h_L` in degrees. Returns ------- ndarray Final opponent signals :math:`A_L` and :math:`B_L`. Examples -------- >>> C_L = 0.0183832899143 >>> h_L = 229.46357270858391 >>> final_opponent_signals(C_L, h_L) # doctest: +ELLIPSIS array([-0.0119478..., -0.0139711...]) """ AB_L = polar_to_cartesian(tstack([C_L, np.radians(h_L)])) return AB_L
def LCHuv_to_Luv(LCHuv): """ Converts from *CIE L\\*C\\*Huv* colourspace to *CIE L\\*u\\*v\\** colourspace. Parameters ---------- LCHuv : array_like *CIE L\\*C\\*Huv* colourspace array. Returns ------- ndarray *CIE L\\*u\\*v\\** colourspace array. Notes ----- +------------+-----------------------+-----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ | ``LCHuv`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``C`` : [0, 100] | ``C`` : [0, 1] | | | | | | | ``uv`` : [0, 360] | ``uv`` : [0, 1] | +------------+-----------------------+-----------------+ +------------+-----------------------+-----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ | ``Luv`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``u`` : [-100, 100] | ``u`` : [-1, 1] | | | | | | | ``v`` : [-100, 100] | ``v`` : [-1, 1] | +------------+-----------------------+-----------------+ References ---------- :cite:`CIETC1-482004m` Examples -------- >>> LCHuv = np.array([41.52787529, 98.44997950, 10.38816348]) >>> LCHuv_to_Luv(LCHuv) # doctest: +ELLIPSIS array([ 41.5278752..., 96.8362605..., 17.7521014...]) """ L, C, H = tsplit(LCHuv) u, v = tsplit( polar_to_cartesian(tstack([C, np.radians(to_domain_degrees(H))]))) Luv = tstack([L, u, v]) return Luv
def LCHuv_to_Luv(LCHuv): """ Converts from *CIE L\\*C\\*Huv* colourspace to *CIE L\\*u\\*v\\** colourspace. Parameters ---------- LCHuv : array_like *CIE L\\*C\\*Huv* colourspace array. Returns ------- ndarray *CIE L\\*u\\*v\\** colourspace array. Notes ----- +------------+-----------------------+-----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ | ``LCHuv`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``C`` : [0, 100] | ``C`` : [0, 1] | | | | | | | ``uv`` : [0, 360] | ``uv`` : [0, 1] | +------------+-----------------------+-----------------+ +------------+-----------------------+-----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+=======================+=================+ | ``Luv`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``u`` : [-100, 100] | ``u`` : [-1, 1] | | | | | | | ``v`` : [-100, 100] | ``v`` : [-1, 1] | +------------+-----------------------+-----------------+ References ---------- :cite:`CIETC1-482004m` Examples -------- >>> LCHuv = np.array([41.52787529, 98.44997950, 10.38816348]) >>> LCHuv_to_Luv(LCHuv) # doctest: +ELLIPSIS array([ 41.5278752..., 96.8362605..., 17.7521014...]) """ L, C, H = tsplit(LCHuv) u, v = tsplit( polar_to_cartesian(tstack([C, np.radians(to_domain_degrees(H))]))) Luv = tstack([L, u, v]) return Luv
def LCHab_to_Lab(LCHab): """ Converts from *CIE L\\*C\\*Hab* colourspace to *CIE L\\*a\\*b\\** colourspace. Parameters ---------- LCHab : array_like *CIE L\\*C\\*Hab* colourspace array. Returns ------- ndarray *CIE L\\*a\\*b\\** colourspace array. Notes ----- +-------------+-----------------------+-----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +=============+=======================+=================+ | ``LCHab`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``C`` : [0, 100] | ``C`` : [0, 1] | | | | | | | ``ab`` : [0, 360] | ``ab`` : [0, 1] | +-------------+-----------------------+-----------------+ +-------------+-----------------------+-----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +=============+=======================+=================+ | ``Lab`` | ``L`` : [0, 100] | ``L`` : [0, 1] | | | | | | | ``a`` : [-100, 100] | ``a`` : [-1, 1] | | | | | | | ``b`` : [-100, 100] | ``b`` : [-1, 1] | +-------------+-----------------------+-----------------+ References ---------- :cite:`CIETC1-482004m` Examples -------- >>> LCHab = np.array([41.52787529, 59.12425901, 27.08848784]) >>> LCHab_to_Lab(LCHab) # doctest: +ELLIPSIS array([ 41.5278752..., 52.6385830..., 26.9231792...]) """ L, C, H = tsplit(LCHab) a, b = tsplit( polar_to_cartesian(tstack([C, np.radians(to_domain_degrees(H))]))) Lab = tstack([L, a, b]) return Lab
def test_polar_to_cartesian(self): """ Tests :func:`colour.algebra.coordinates.transformations.\ polar_to_cartesian` definition. """ np.testing.assert_almost_equal( polar_to_cartesian(np.array([0.32175055, 1.08574654])), np.array([0.15001697, 0.28463718]), decimal=7) np.testing.assert_almost_equal( polar_to_cartesian(np.array([1.68145355, 1.05578119])), np.array([0.82819662, 1.46334425]), decimal=7) np.testing.assert_almost_equal( polar_to_cartesian(np.array([-0.14626640, 1.23829030])), np.array([-0.04774323, -0.13825500]), decimal=7)
def JMh_CIECAM02_to_UCS_Luo2006(JMh, coefficients): """ Converts from *CIECAM02* :math:`JMh` correlates array to one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. The :math:`JMh` correlates array is constructed using the CIECAM02 correlate of *Lightness* :math:`J`, the *CIECAM02* correlate of *colourfulness* :math:`M` and the *CIECAM02* *Hue* angle :math:`h` in degrees. Parameters ---------- JMh : array_like *CIECAM02* correlates array :math:`JMh`. coefficients : array_like Coefficients of one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces. Returns ------- ndarray *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. Examples -------- >>> from colour.appearance import ( ... CIECAM02_VIEWING_CONDITIONS, ... XYZ_to_CIECAM02) >>> XYZ = np.array([19.01, 20.00, 21.78]) >>> XYZ_w = np.array([95.05, 100.00, 108.88]) >>> L_A = 318.31 >>> Y_b = 20.0 >>> surround = CIECAM02_VIEWING_CONDITIONS['Average'] >>> specification = XYZ_to_CIECAM02( ... XYZ, XYZ_w, L_A, Y_b, surround) >>> JMh = (specification.J, specification.M, specification.h) >>> JMh_CIECAM02_to_UCS_Luo2006( # doctest: +ELLIPSIS ... JMh, COEFFICIENTS_UCS_LUO2006['CAM02-LCD']) array([ 54.9043313..., -0.0845039..., -0.0685483...]) """ J, M, h = tsplit(JMh) _K_L, c_1, c_2 = tsplit(coefficients) J_p = ((1 + 100 * c_1) * J) / (1 + c_1 * J) M_p = (1 / c_2) * np.log(1 + c_2 * M) a_p, b_p = tsplit(polar_to_cartesian(tstack((M_p, np.radians(h))))) return tstack((J_p, a_p, b_p))
def JCh_to_Jab(JCh: ArrayLike) -> NDArray: """ Convert from *JCh* colour representation to *Jab* colour representation. This definition is used to perform conversion from *CIE L\\*C\\*Hab* colourspace to *CIE L\\*a\\*b\\** colourspace and for other similar conversions. It implements a generic transformation from the correlates of *Lightness* :math:`J`, chroma :math:`C` and hue angle :math:`h` to *Lightness* :math:`J`, :math:`a` and :math:`b` opponent colour dimensions. Parameters ---------- JCh *JCh* colour representation array. Returns ------- :class:`numpy.ndarray` *Jab* colour representation array. Notes ----- +-------------+-----------------------+-----------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +=============+=======================+=================+ | ``JCh`` | ``J`` : [0, 100] | ``J`` : [0, 1] | | | | | | | ``C`` : [0, 100] | ``C`` : [0, 1] | | | | | | | ``h`` : [0, 360] | ``h`` : [0, 1] | +-------------+-----------------------+-----------------+ +-------------+-----------------------+-----------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +=============+=======================+=================+ | ``Jab`` | ``J`` : [0, 100] | ``J`` : [0, 1] | | | | | | | ``a`` : [-100, 100] | ``a`` : [-1, 1] | | | | | | | ``b`` : [-100, 100] | ``b`` : [-1, 1] | +-------------+-----------------------+-----------------+ References ---------- :cite:`CIETC1-482004m` Examples -------- >>> JCh = np.array([41.52787529, 59.12425901, 27.08848784]) >>> JCh_to_Jab(JCh) # doctest: +ELLIPSIS array([ 41.5278752..., 52.6385830..., 26.9231792...]) """ L, C, H = tsplit(JCh) a, b = tsplit( polar_to_cartesian(tstack([C, np.radians(to_domain_degrees(H))]))) Jab = tstack([L, a, b]) return Jab
def JMh_CIECAM02_to_UCS_Luo2006(JMh: ArrayLike, coefficients: ArrayLike) -> NDArray: """ Convert from *CIECAM02* :math:`JMh` correlates array to one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. The :math:`JMh` correlates array is constructed using the CIECAM02 correlate of *Lightness* :math:`J`, the *CIECAM02* correlate of *colourfulness* :math:`M` and the *CIECAM02* *Hue* angle :math:`h` in degrees. Parameters ---------- JMh *CIECAM02* correlates array :math:`JMh`. coefficients Coefficients of one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces. Returns ------- :class:`numpy.ndarray` *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. Notes ----- +------------+------------------------+------------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+========================+==================+ | ``JMh`` | ``J`` : [0, 100] | ``J`` : [0, 1] | | | | | | | ``M`` : [0, 100] | ``M`` : [0, 1] | | | | | | | ``h`` : [0, 360] | ``h`` : [0, 1] | +------------+------------------------+------------------+ +------------+------------------------+------------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+========================+==================+ | ``Jpapbp`` | ``Jp`` : [0, 100] | ``Jp`` : [0, 1] | | | | | | | ``ap`` : [-100, 100] | ``ap`` : [-1, 1] | | | | | | | ``bp`` : [-100, 100] | ``bp`` : [-1, 1] | +------------+------------------------+------------------+ Examples -------- >>> from colour.appearance import ( ... VIEWING_CONDITIONS_CIECAM02, ... XYZ_to_CIECAM02) >>> XYZ = np.array([19.01, 20.00, 21.78]) >>> XYZ_w = np.array([95.05, 100.00, 108.88]) >>> L_A = 318.31 >>> Y_b = 20.0 >>> surround = VIEWING_CONDITIONS_CIECAM02['Average'] >>> specification = XYZ_to_CIECAM02( ... XYZ, XYZ_w, L_A, Y_b, surround) >>> JMh = (specification.J, specification.M, specification.h) >>> JMh_CIECAM02_to_UCS_Luo2006(JMh, COEFFICIENTS_UCS_LUO2006['CAM02-LCD']) ... # doctest: +ELLIPSIS array([ 54.9043313..., -0.0845039..., -0.0685483...]) """ J, M, h = tsplit(JMh) J = to_domain_100(J) M = to_domain_100(M) h = to_domain_degrees(h) _K_L, c_1, c_2 = tsplit(coefficients) J_p = ((1 + 100 * c_1) * J) / (1 + c_1 * J) M_p = (1 / c_2) * np.log1p(c_2 * M) a_p, b_p = tsplit(polar_to_cartesian(tstack([M_p, np.radians(h)]))) Jpapbp = tstack([J_p, a_p, b_p]) return from_range_100(Jpapbp)
def JMh_CIECAM02_to_UCS_Luo2006(JMh, coefficients): """ Converts from *CIECAM02* :math:`JMh` correlates array to one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. The :math:`JMh` correlates array is constructed using the CIECAM02 correlate of *Lightness* :math:`J`, the *CIECAM02* correlate of *colourfulness* :math:`M` and the *CIECAM02* *Hue* angle :math:`h` in degrees. Parameters ---------- JMh : array_like *CIECAM02* correlates array :math:`JMh`. coefficients : array_like Coefficients of one of the *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces. Returns ------- ndarray *Luo et al. (2006)* *CAM02-LCD*, *CAM02-SCD*, or *CAM02-UCS* colourspaces :math:`J'a'b'` array. Notes ----- +------------+------------------------+--------------------+ | **Domain** | **Scale - Reference** | **Scale - 1** | +============+========================+====================+ | ``JMh`` | ``J`` : [0, 100] | ``J`` : [0, 1] | | | | | | | ``M`` : [0, 100] | ``M`` : [0, 1] | | | | | | | ``h`` : [0, 360] | ``h`` : [0, 1] | +------------+------------------------+--------------------+ +------------+------------------------+--------------------+ | **Range** | **Scale - Reference** | **Scale - 1** | +============+========================+====================+ | ``Jpapbp`` | ``Jp_1`` : [0, 100] | ``Jp_1`` : [0, 1] | | | | | | | ``ap_1`` : [-100, 100] | ``ap_1`` : [-1, 1] | | | | | | | ``bp_1`` : [-100, 100] | ``bp_1`` : [-1, 1] | +------------+------------------------+--------------------+ Examples -------- >>> from colour.appearance import ( ... CIECAM02_VIEWING_CONDITIONS, ... XYZ_to_CIECAM02) >>> XYZ = np.array([19.01, 20.00, 21.78]) >>> XYZ_w = np.array([95.05, 100.00, 108.88]) >>> L_A = 318.31 >>> Y_b = 20.0 >>> surround = CIECAM02_VIEWING_CONDITIONS['Average'] >>> specification = XYZ_to_CIECAM02( ... XYZ, XYZ_w, L_A, Y_b, surround) >>> JMh = (specification.J, specification.M, specification.h) >>> JMh_CIECAM02_to_UCS_Luo2006(JMh, COEFFICIENTS_UCS_LUO2006['CAM02-LCD']) ... # doctest: +ELLIPSIS array([ 54.9043313..., -0.0845039..., -0.0685483...]) """ J, M, h = tsplit(JMh) J = to_domain_100(J) M = to_domain_100(M) h = to_domain_degrees(h) _K_L, c_1, c_2 = tsplit(coefficients) J_p = ((1 + 100 * c_1) * J) / (1 + c_1 * J) M_p = (1 / c_2) * np.log(1 + c_2 * M) a_p, b_p = tsplit(polar_to_cartesian(tstack([M_p, np.radians(h)]))) Jpapbp = tstack([J_p, a_p, b_p]) return from_range_100(Jpapbp)