示例#1
0
def rgb2hsi(rgb: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert RGB to Hue Saturation Intensity
    
    :param rgb: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(rgb.shape, 3)
    big_m, little_m, chroma = _compute_chroma(rgb, axis)

    inds = construct_component_inds(axis, rgb.ndim, 3)

    hsi = np.zeros(rgb.shape)
    hsi[inds[0]] = _compute_rgb_hue(rgb, big_m, little_m, chroma, axis)
    hsi[inds[2]] = np.mean(rgb, axis=axis, keepdims=True)

    i_nz = hsi[inds[2]] != 0  # type: np.ndarray
    if little_m.ndim < i_nz.ndim:
        # This only happens in the 1D case
        little_m = little_m[slice(None), np.newaxis]
    if np.any(i_nz):
        hsi[inds[1]][i_nz] = 1 - little_m[i_nz] / hsi[inds[2]][i_nz]

    return hsi
示例#2
0
def hsl2rgb(hsl: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert from Hue Saturation Lightness (HSL) to RGB
    
    :type hsl: np.ndarray
    :param hsl: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(hsl.shape, 3)

    inds = construct_component_inds(axis, hsl.ndim, 3)

    chroma = ((1. - np.abs(2. * hsl[inds[2]] - 1.)) * hsl[inds[1]]
              )  # type: np.ndarray

    h_prime = hsl[inds[0]] / 60.
    x = chroma * (1 - np.abs(np.mod(h_prime, 2) - 1))
    rgb1 = _compute_rgb1(hsl.shape, inds, h_prime, x, chroma)

    little_m = hsl[inds[2]] - chroma / 2.
    if little_m.ndim > rgb1.ndim:
        # This only happens if hsl is 1-D
        return rgb1 + little_m[0]
    else:
        return rgb1 + little_m
示例#3
0
def xyz2xyy(xyz: np.ndarray,
            *,
            axis: int = None,
            illuminant: Illuminant = None,
            observer: Observer = None) -> np.ndarray:
    """
    Convert XYZ to xyY
    
    :param xyz: 
    :param axis: 
    :param illuminant: 
    :param observer: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(xyz.shape, 3)
    if illuminant is None:
        illuminant = get_default_illuminant()
    if observer is None:
        observer = get_default_observer()
    inds = construct_component_inds(axis, xyz.ndim, 3)

    denominator = np.sum(xyz, axis, keepdims=True)
    nzd = denominator != 0

    xyy = np.zeros(xyz.shape)
    if np.any(nzd):
        xyy[inds[0]][nzd] = xyz[inds[0]][nzd] / denominator[nzd]
        xyy[inds[1]][nzd] = xyz[inds[1]][nzd] / denominator[nzd]
    xyy[inds[2]] = xyz[inds[1]]
    if not np.all(nzd):
        # For any point that is pure black (X=Y=Z=0), give it the
        # chromaticity of the white point of the specified illuminant and
        # observer.
        white_point = illuminant.get_white_point(observer)
        # to prevent infinite recursion, ensure that the white point is
        # non-black
        if white_point[1] > 0:
            zd = np.logical_not(nzd)
            white_point_xyy = xyz2xyy(white_point,
                                      illuminant=illuminant,
                                      observer=observer)
            xyy[inds[0]][zd] = white_point_xyy[0]
            xyy[inds[1]][zd] = white_point_xyy[1]
    return xyy
示例#4
0
def lab2lch(lab: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert L*a*b* to LCh
    
    :param lab: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(lab.shape, 3)

    inds = construct_component_inds(axis, lab.ndim, 3)

    lch = np.zeros(lab.shape)

    lch[inds[0]] = lab[inds[0]]
    lch[inds[1]] = np.sqrt(lab[inds[1]]**2 + lab[inds[2]]**2)
    lch[inds[2]] = np.mod(
        (180 / np.pi) * np.arctan2(lab[inds[2]], lab[inds[1]]), 360.)

    return lch
示例#5
0
def rgb2hcy(rgb: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert from RGB to Hue, Chroma, Luma (Y'_601)
    
    :param rgb: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(rgb.shape, 3)

    big_m, little_m, chroma = _compute_chroma(rgb, axis)

    inds = construct_component_inds(axis, rgb.ndim, 3)

    hcy = np.zeros(rgb.shape)
    hcy[inds[0]] = _compute_rgb_hue(rgb, big_m, little_m, chroma, axis)
    hcy[inds[1]] = chroma
    hcy[inds[2]] = 0.299 * rgb[inds[0]] + 0.587 * rgb[inds[1]] + 0.114 * rgb[
        inds[2]]

    return hcy
示例#6
0
def xyy2xyz(xyy, *, axis: int = None) -> np.ndarray:
    """
    converts from xyY to XYZ
    
    :param xyy: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(xyy.shape, 3)

    inds = construct_component_inds(axis, len(xyy.shape), 3)

    # Determine where y iz 0 so we don't divide by it
    nzy = np.nonzero(xyy[inds[1]])
    xyz = np.zeros(xyy.shape)

    xyz[inds[0]][nzy] = xyy[inds[0]][nzy] * xyy[inds[2]][nzy] / xyy[
        inds[1]][nzy]
    xyz[inds[1]][nzy] = xyy[inds[2]][nzy]
    xyz[inds[2]][nzy] = ((1 - xyy[inds[0]][nzy] - xyy[inds[1]][nzy]) *
                         xyy[inds[2]][nzy] / xyy[inds[1]][nzy])
    return xyz
示例#7
0
def hcy2rgb(hcy: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    
    :param hcy: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(hcy.shape, 3)

    inds = construct_component_inds(axis, hcy.ndim, 3)

    h_prime = hcy[inds[0]] / 60.
    x: np.ndarray = hcy[inds[1]] * (1 - np.abs(np.mod(h_prime, 2) - 1))
    rgb1 = _compute_rgb1(hcy.shape, inds, h_prime, x, hcy[inds[1]])
    little_m: np.ndarray = hcy[inds[2]] - (
        0.299 * rgb1[inds[0]] + 0.587 * rgb1[inds[1]] + 0.114 * rgb1[inds[2]])

    if little_m.ndim > rgb1.ndim:
        # This only happens in the 1D case
        return rgb1 + little_m[0]
    else:
        return rgb1 + little_m
示例#8
0
def hsv2rgb(hsv: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert from HSV to RGB
    :param hsv: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(hsv.shape, 3)

    inds = construct_component_inds(axis, hsv.ndim, 3)

    chroma = hsv[inds[1]] * hsv[inds[2]]
    h_prime = hsv[inds[0]] / 60.
    x = chroma * (1. - np.abs(np.mod(h_prime, 2.) - 1))  # type: np.ndarray
    rgb1 = _compute_rgb1(hsv.shape, inds, h_prime, x, chroma)
    little_m = hsv[inds[2]] - chroma

    if little_m.ndim > rgb1.ndim:
        # This only happens in the 1D case
        return rgb1 + little_m[0]
    else:
        return rgb1 + little_m
示例#9
0
def lab2xyzr(lab: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert LAB to normalized XYZ
    
    :param lab: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(lab.shape, 3)

    inds = construct_component_inds(axis, len(lab.shape), 3)
    fxyz = np.zeros(lab.shape)
    fxyz[inds[1]] = (lab[inds[0]] + 16) / 116
    fxyz[inds[0]] = lab[inds[1]] / 500 + fxyz[inds[1]]
    fxyz[inds[2]] = fxyz[inds[1]] - lab[inds[2]] / 200

    is_small = fxyz <= (LAB_EPS**(1.0 / 3.0))
    is_big = np.logical_not(is_small)
    xyzr = np.zeros(lab.shape)
    xyzr[is_big] = fxyz[is_big]**3.0
    xyzr[is_small] = (116 * fxyz[is_small] - 16) / LAB_KAPPA
    return xyzr
示例#10
0
def rgb2hsv(rgb: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert from RGB to Hue Saturation Value (HSV)
    
    :param rgb: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(rgb.shape, 3)

    big_m, little_m, chroma = _compute_chroma(rgb, axis)

    inds = construct_component_inds(axis, rgb.ndim, 3)

    hsv = np.zeros(rgb.shape)
    hsv[inds[0]] = _compute_rgb_hue(rgb, big_m, little_m, chroma, axis)
    hsv[inds[2]] = big_m

    big_m_nz = big_m != 0
    hsv[inds[1]][big_m_nz] = chroma[big_m_nz] / big_m[big_m_nz]

    return hsv
示例#11
0
def _compute_rgb_hue(rgb: np.ndarray, big_m, little_m, chroma,
                     axis: int) -> np.ndarray:
    """ Compute the RGB Hue. This is the same for HSV and HSL """
    inds = construct_component_inds(axis, rgb.ndim, 3)
    r = rgb[inds[0]]
    g = rgb[inds[1]]
    b = rgb[inds[2]]
    if chroma.ndim < r.ndim:
        # this will only happen when chroma is 1-D
        chroma = chroma[(slice(None), np.newaxis)]
    ch_is_nz = chroma != 0.
    m_is_r = np.logical_and(big_m == r, ch_is_nz)
    m_is_g = np.logical_and(big_m == g, ch_is_nz)
    m_is_b = np.logical_and(big_m == b, ch_is_nz)

    h_prime = np.zeros(r.shape)
    if np.any(m_is_r):
        h_prime[m_is_r] = np.mod((g[m_is_r] - b[m_is_r]) / chroma[m_is_r] + 6.,
                                 6.)
    if np.any(m_is_g):
        h_prime[m_is_g] = (b[m_is_g] - r[m_is_g]) / chroma[m_is_g] + 2.
    if np.any(m_is_b):
        h_prime[m_is_b] = (r[m_is_b] - g[m_is_b]) / chroma[m_is_b] + 4.
    return 60. * h_prime
示例#12
0
def hsi2rgb(hsi: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert Hue Saturation Intensity (HSI) to RGB
    
    :param hsi: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(hsi.shape, 3)

    inds = construct_component_inds(axis, hsi.ndim, 3)

    h_prime = hsi[inds[0]] / 60.
    z = 1 - np.abs(np.mod(h_prime, 2.) - 1)
    chroma = 3 * hsi[inds[2]] * hsi[inds[1]] / (1 + z)  # type: np.ndarray
    x = chroma * z
    rgb1 = _compute_rgb1(hsi.shape, inds, h_prime, x, chroma)
    little_m = hsi[inds[2]] * (1 - hsi[inds[1]])  # type: np.ndarray
    if little_m.ndim > rgb1.ndim:
        # This only happens in the 1D case
        return rgb1 + little_m[0]
    else:
        return rgb1 + little_m
示例#13
0
def rgb2hsl(rgb: np.ndarray, *, axis: int = None) -> np.ndarray:
    """
    Convert RGB to Hue Saturation Lightness
    :param rgb: 
    :param axis: 
    :return: 
    """
    if axis is None:
        axis = get_matching_axis(rgb.shape, 3)
    big_m, little_m, chroma = _compute_chroma(rgb, axis)

    inds = construct_component_inds(axis, rgb.ndim, 3)

    hsl = np.zeros(rgb.shape)
    hsl[inds[0]] = _compute_rgb_hue(rgb, big_m, little_m, chroma, axis)
    l = 0.5 * (big_m + little_m)
    hsl[inds[2]] = l

    l_lt_one = l < 1.
    if np.any(l_lt_one):
        hsl[inds[1]][l_lt_one] = ((big_m[l_lt_one] - little_m[l_lt_one]) /
                                  (1. - np.abs(2 * l[l_lt_one] - 1)))

    return hsl