Esempio n. 1
0
 def test_ipt(self, getvars):
     S, spds, rfls, xyz, xyzw = getvars
     labw = lx.xyz_to_ipt(xyzw)
     lab = lx.xyz_to_ipt(xyz)
     xyzw_ = lx.ipt_to_xyz(labw)
     xyz_ = lx.ipt_to_xyz(lab)
     assert np.isclose(xyz, xyz_).all()
     assert np.isclose(xyzw, xyzw_).all()
Esempio n. 2
0
 def to_ipt(self, cieobs=_CIEOBS, xyzw=None, M=None):
     """ 
     Convert XYZ tristimulus values to IPT color coordinates.
      
     | I: Lightness axis, P, red-green axis, T: yellow-blue axis.
      
     Args:
         :xyzw: 
             | None or ndarray with xyz values of white point, optional
             | None defaults to xyz of CIE D65 using the :cieobs: observer.
         :cieobs: 
             | luxpy._CIEOBS, optional
             | CMF set to use when calculating xyzw for rescaling Mxyz2lms 
             | (only when not None).
         :M: 
             | None, optional
             | None defaults to conversion matrix determined by :cieobs:
         
     Returns:
         :ipt: 
             | luxpy.LAB with .value field that is a ndarray
             | with IPT color coordinates
         
     Note: 
         :xyz: is assumed to be under D65 viewing conditions!! 
         | If necessary perform chromatic adaptation !!
     """
     return LAB(value=xyz_to_ipt(self.value, cieobs=cieobs, xyzw=xyzw, M=M),
                relative=self.relative,
                dtype='ipt',
                cieobs=cieobs,
                xyzw=xyzw,
                M=M)
Esempio n. 3
0
def spd_to_mcri(SPD, D=0.9, E=None, Yb=20.0, out='Rm', wl=None):
    """
    Calculates the MCRI or Memory Color Rendition Index, Rm
    
    Args: 
        :SPD: 
            | ndarray with spectral data (can be multiple SPDs, 
              first axis are the wavelengths)
        :D: 
            | 0.9, optional
            | Degree of adaptation.
        :E: 
            | None, optional
            | Illuminance in lux 
            |  (used to calculate La = (Yb/100)*(E/pi) to then calculate D 
            |  following the 'cat02' model). 
            | If None: the degree is determined by :D:
            |  If (:E: is not None) & (:Yb: is None):  :E: is assumed to contain 
               the adapting field luminance La (cd/m²).
        :Yb: 
            | 20.0, optional
            | Luminance factor of background. (used when calculating La from E)
            | If None, E contains La (cd/m²).
        :out: 
            | 'Rm' or str, optional
            | Specifies requested output (e.g. 'Rm,Rmi,cct,duv') 
        :wl: 
            | None, optional
            | Wavelengths (or [start, end, spacing]) to interpolate the SPDs to. 
            | None: default to no interpolation   
    
    Returns:
        :returns: 
            | float or ndarray with MCRI Rm for :out: 'Rm'
            | Other output is also possible by changing the :out: str value.        
          
    References:
        1. `K.A.G. Smet, W.R. Ryckaert, M.R. Pointer, G. Deconinck, P. Hanselaer,(2012)
        “A memory colour quality metric for white light sources,” 
        Energy Build., vol. 49, no. C, pp. 216–225.
        <http://www.sciencedirect.com/science/article/pii/S0378778812000837>`_
    """
    SPD = np2d(SPD)

    if wl is not None:
        SPD = spd(data=SPD, interpolation=_S_INTERP_TYPE, kind='np', wl=wl)

    # unpack metric default values:
    avg, catf, cieobs, cri_specific_pars, cspace, ref_type, rg_pars, sampleset, scale = [
        _MCRI_DEFAULTS[x] for x in sorted(_MCRI_DEFAULTS.keys())
    ]
    similarity_ai = cri_specific_pars['similarity_ai']
    Mxyz2lms = cspace['Mxyz2lms']
    scale_fcn = scale['fcn']
    scale_factor = scale['cfactor']
    sampleset = eval(sampleset)

    # A. calculate xyz:
    xyzti, xyztw = spd_to_xyz(SPD, cieobs=cieobs['xyz'], rfl=sampleset, out=2)
    if 'cct' in out.split(','):
        cct, duv = xyz_to_cct(xyztw,
                              cieobs=cieobs['cct'],
                              out='cct,duv',
                              mode='lut')

    # B. perform chromatic adaptation to adopted whitepoint of ipt color space, i.e. D65:
    if catf is not None:
        Dtype_cat, F, Yb_cat, catmode_cat, cattype_cat, mcat_cat, xyzw_cat = [
            catf[x] for x in sorted(catf.keys())
        ]

        # calculate degree of adaptationn D:
        if E is not None:
            if Yb is not None:
                La = (Yb / 100.0) * (E / np.pi)
            else:
                La = E
            D = cat.get_degree_of_adaptation(Dtype=Dtype_cat, F=F, La=La)
        else:
            Dtype_cat = None  # direct input of D

        if (E is None) and (D is None):
            D = 1.0  # set degree of adaptation to 1 !
        if D > 1.0: D = 1.0
        if D < 0.6: D = 0.6  # put a limit on the lowest D

        # apply cat:
        xyzti = cat.apply(xyzti,
                          cattype=cattype_cat,
                          catmode=catmode_cat,
                          xyzw1=xyztw,
                          xyzw0=None,
                          xyzw2=xyzw_cat,
                          D=D,
                          mcat=[mcat_cat],
                          Dtype=Dtype_cat)
        xyztw = cat.apply(xyztw,
                          cattype=cattype_cat,
                          catmode=catmode_cat,
                          xyzw1=xyztw,
                          xyzw0=None,
                          xyzw2=xyzw_cat,
                          D=D,
                          mcat=[mcat_cat],
                          Dtype=Dtype_cat)

    # C. convert xyz to ipt and split:
    ipt = xyz_to_ipt(
        xyzti, cieobs=cieobs['xyz'], M=Mxyz2lms
    )  #input matrix as published in Smet et al. 2012, Energy and Buildings
    I, P, T = asplit(ipt)

    # D. calculate specific (hue dependent) similarity indicators, Si:
    if len(xyzti.shape) == 3:
        ai = np.expand_dims(similarity_ai, axis=1)
    else:
        ai = similarity_ai
    a1, a2, a3, a4, a5 = asplit(ai)
    mahalanobis_d2 = (a3 * np.power((P - a1), 2.0) + a4 * np.power(
        (T - a2), 2.0) + 2.0 * a5 * (P - a1) * (T - a2))
    if (len(mahalanobis_d2.shape) == 3) & (mahalanobis_d2.shape[-1] == 1):
        mahalanobis_d2 = mahalanobis_d2[:, :, 0].T
    Si = np.exp(-0.5 * mahalanobis_d2)

    # E. calculate general similarity indicator, Sa:
    Sa = avg(Si, axis=0, keepdims=True)

    # F. rescale similarity indicators (Si, Sa) with a 0-1 scale to memory color rendition indices (Rmi, Rm) with a 0 - 100 scale:
    Rmi = scale_fcn(np.log(Si), scale_factor=scale_factor)
    Rm = np2d(scale_fcn(np.log(Sa), scale_factor=scale_factor))

    # G. calculate Rg (polyarea of test / polyarea of memory colours):
    if 'Rg' in out.split(','):
        I = I[
            ...,
            None]  #broadcast_shape(I, target_shape = None,expand_2d_to_3d = 0)
        a1 = a1[:, None] * np.ones(
            I.shape
        )  #broadcast_shape(a1, target_shape = None,expand_2d_to_3d = 0)
        a2 = a2[:, None] * np.ones(
            I.shape
        )  #broadcast_shape(a2, target_shape = None,expand_2d_to_3d = 0)
        a12 = np.concatenate(
            (a1, a2), axis=2
        )  #broadcast_shape(np.hstack((a1,a2)), target_shape = ipt.shape,expand_2d_to_3d = 0)
        ipt_mc = np.concatenate((I, a12), axis=2)
        nhbins, normalize_gamut, normalized_chroma_ref, start_hue = [
            rg_pars[x] for x in sorted(rg_pars.keys())
        ]

        Rg = jab_to_rg(ipt,
                       ipt_mc,
                       ordered_and_sliced=False,
                       nhbins=nhbins,
                       start_hue=start_hue,
                       normalize_gamut=normalize_gamut)

    if (out != 'Rm'):
        return eval(out)
    else:
        return Rm
Esempio n. 4
0
labw = lx.xyz_to_Yuv(xyzw)
lab = lx.xyz_to_Yuv(xyz)
xyzw_ = lx.Yuv_to_xyz(labw)
xyz_ = lx.Yuv_to_xyz(lab)

labw = lx.xyz_to_lab(xyzw, xyzw=xyzw[:1, :])
lab = lx.xyz_to_lab(xyz, xyzw=xyzw[:1, :])
xyzw_ = lx.lab_to_xyz(labw, xyzw=xyzw[:1, :])
xyz_ = lx.lab_to_xyz(lab, xyzw=xyzw[:1, :])

labw = lx.xyz_to_luv(xyzw, xyzw=xyzw)
lab = lx.xyz_to_luv(xyz, xyzw=xyzw)
xyzw_ = lx.luv_to_xyz(labw, xyzw=xyzw)
xyz_ = lx.luv_to_xyz(lab, xyzw=xyzw)

labw = lx.xyz_to_ipt(xyzw)
lab = lx.xyz_to_ipt(xyz)
xyzw_ = lx.ipt_to_xyz(labw)
xyz_ = lx.ipt_to_xyz(lab)

labw = lx.xyz_to_wuv(xyzw, xyzw=xyzw)
lab = lx.xyz_to_wuv(xyz, xyzw=xyzw)
xyzw_ = lx.wuv_to_xyz(labw, xyzw=xyzw)
xyz_ = lx.wuv_to_xyz(lab, xyzw=xyzw)

labw = lx.xyz_to_Vrb_mb(xyzw)
lab = lx.xyz_to_Vrb_mb(xyz)
xyzw_ = lx.Vrb_mb_to_xyz(labw)
xyz_ = lx.Vrb_mb_to_xyz(lab)

labw = lx.xyz_to_Ydlep(xyzw)