def xyz2lab(xyz_img, white_ref=whitepoint.D50): """Converts from XYZ to CIELAB (aka, L*a*b*). The white_ref is the whitepoint of the XYZ color space, and defaults to D50. Use any other whitepoint.WhitePoint object as a reference if needed. The whitepoint values whould be on the same order as the XYZ values. For example, if XYZ ranges from [0..1], the whitepoint should have values close to 1. """ #default is D50 whitepoint for XYZ colors; Lab is device independent assert(isinstance(xyz_img, numpy.ndarray)) #compute the XYZ relative to the whitepoint; note that this assumes the #whitepoint and the XYZ have the same scale. X, Y, Z = imageutils.split3(xyz_img) xr = X / white_ref.X yr = Y / white_ref.Y zr = Z / white_ref.Z #note: xr, yr, zr are scaled so that they are close to [0..1] range; #it is possible to have values >1, that's not an error. fy = lab_inverse_compand(yr) L = 116.0 * fy - 16.0 a = 500.0 * (lab_inverse_compand(xr) - fy) b = 200.0 * (fy - lab_inverse_compand(zr)) return imageutils.cat3(L, a, b)
def luv2lch(luv_img): """Converts CIELUV to a LCh representation. L: luminance C: chroma h: hue (in radians) """ assert(isinstance(luv_img, numpy.ndarray)) L, u, v = imageutils.split3(luv_img) C = numpy.sqrt(u**2 + v**2) h = numpy.arctan2(v, u) return imageutils.cat3(L, C, h)
def lab2xyz(lab_img, white_ref=whitepoint.D50): """Converts CIELAB's L*a*b* to XYZ. The white_ref is the whitepoint of the XYZ color space; use any whitepoint.WhitePoint object as a reference if needed. The default is D50. """ assert(isinstance(lab_img, numpy.ndarray)) L, a, b = imageutils.split3(lab_img) fy = (L + 16.) / 116. fx = a / 500. + fy fz = fy - b / 200. xr = _lab_finv(fx) zr = _lab_finv(fz) yr = _lab_yinv(L) return imageutils.cat3(xr * white_ref.X, yr * white_ref.Y, zr * white_ref.Z)
def luv2xyz(luv_img, white_ref=whitepoint.D50): """Converts CIELUV to XYZ. The white_ref is the whitepoint of the XYZ colorspace, and defaults to D50. Use any other whitepoint.WhitePoint object as needed. """ #equation from wikipedia->CIELUV assert(isinstance(luv_img, numpy.ndarray)) L, u, v = imageutils.split3(luv_img) f_a = lambda x: ((x + 16.) / 116.) ** 3. f_b = lambda x: x / _lab_kappa threshold = _lab_kappa * _lab_epsilon Y = white_ref.Y * _bilevel_func(L, f_a, f_b, threshold) u_ref = _uprime(*white_ref.XYZ) v_ref = _vprime(*white_ref.XYZ) uprime = _safe_divide(u, 13. * L) + u_ref vprime = _safe_divide(v, 13. * L) + v_ref X = Y * _safe_divide(9. * uprime, 4. * vprime) Z = Y * _safe_divide(12. - 3. * uprime - 20. * vprime, 4. * vprime) return imageutils.cat3(X, Y, Z)
def xyz2luv(xyz_img, white_ref=whitepoint.D50): """Converts XYZ to CIELUV (aka, L*u*v*). A whitepoint reference of D50 is assumed for the XYZ values. Any other whitepoint, as a whitepoint.WhitePoint object, can be used -- and should have the same scale as the XYZ values. """ assert(isinstance(xyz_img, numpy.ndarray)) X, Y, Z = imageutils.split3(xyz_img) yr = Y / white_ref.Y uprime = _uprime(X, Y, Z) vprime = _vprime(X, Y, Z) uprime_ref = _uprime(*white_ref.XYZ) vprime_ref = _vprime(*white_ref.XYZ) f_a = lambda y: 116. * y ** (1 / 3.) - 16. f_b = lambda y: y * _lab_kappa L = _bilevel_func(yr, f_a, f_b, _lab_epsilon) u = 13.0 * L * (uprime - uprime_ref) v = 13.0 * L * (vprime - vprime_ref) return imageutils.cat3(L, u, v)