Beispiel #1
0
def _cri_ref_i(cct,
               wl3=_WL,
               ref_type='iestm30',
               mix_range=[4000, 5000],
               cieobs='1931_2',
               force_daylight_below4000K=False,
               n=None,
               daylight_locus=None):
    """
    Calculates a reference illuminant spectrum based on cct 
    for color rendering index calculations.
    """
    if mix_range is None:
        mix_range = _CRI_REF_TYPES[ref_type]
    if (cct < mix_range[0]) | (ref_type == 'BB'):
        return blackbody(cct, wl3, n=n)
    elif (cct > mix_range[0]) | (ref_type == 'DL'):
        return daylightphase(
            cct,
            wl3,
            force_daylight_below4000K=force_daylight_below4000K,
            cieobs=cieobs,
            daylight_locus=daylight_locus)
    else:
        SrBB = blackbody(cct, wl3, n=n)
        SrDL = daylightphase(
            cct,
            wl3,
            verbosity=None,
            force_daylight_below4000K=force_daylight_below4000K,
            cieobs=cieobs,
            daylight_locus=daylight_locus)
        cmf = _CMF[cieobs]['bar'] if isinstance(cieobs, str) else cieobs
        wl = SrBB[0]
        ld = getwld(wl)

        SrBB = 100.0 * SrBB[1] / np.array(np.sum(SrBB[1] * cmf[2] * ld))
        SrDL = 100.0 * SrDL[1] / np.array(np.sum(SrDL[1] * cmf[2] * ld))
        Tb, Te = float(mix_range[0]), float(mix_range[1])
        cBB, cDL = (Te - cct) / (Te - Tb), (cct - Tb) / (Te - Tb)
        if cBB < 0.0:
            cBB = 0.0
        elif cBB > 1:
            cBB = 1.0
        if cDL < 0.0:
            cDL = 0.0
        elif cDL > 1:
            cDL = 1.0

        Sr = SrBB * cBB + SrDL * cDL
        Sr[Sr == float('NaN')] = 0.0
        Sr = np.vstack((wl, (Sr / Sr[_POS_WL560])))

        return Sr
Beispiel #2
0
def calculate_lut(ccts=None, cieobs=None, add_to_lut=True):
    """
    Function that calculates LUT for the ccts stored in 
    ./data/cctluts/cct_lut_cctlist.dat or given as input argument.
    Calculation is performed for CMF set specified in cieobs. 
    Adds a new (temprorary) field to the _CCT_LUT dict.
    
    Args:
        :ccts: 
            | ndarray or str, optional
            | list of ccts for which to (re-)calculate the LUTs.
            | If str, ccts contains path/filename.dat to list.
        :cieobs: 
            | None or str, optional
            | str specifying cmf set.
            
    Returns:
        :returns: 
            | ndarray with cct and duv.
        
    Note:
        Function changes the global variable: _CCT_LUT!
    """
    if ccts is None:
        ccts = getdata('{}cct_lut_cctlist.dat'.format(_CCT_LUT_PATH))
    elif isinstance(ccts, str):
        ccts = getdata(ccts)

    Yuv = np.ones((ccts.shape[0], 2)) * np.nan
    for i, cct in enumerate(ccts):
        Yuv[i, :] = xyz_to_Yuv(
            spd_to_xyz(blackbody(cct, wl3=[360, 830, 1]), cieobs=cieobs))[:,
                                                                          1:3]
    u = Yuv[:, 0, None]  # get CIE 1960 u
    v = (2.0 / 3.0) * Yuv[:, 1, None]  # get CIE 1960 v
    cctuv = np.hstack((ccts, u, v))
    if add_to_lut == True:
        _CCT_LUT[cieobs] = cctuv
    return cctuv
def spd_to_COI_ASNZS1680(S=None,
                         tf=_COI_CSPACE,
                         cieobs=_COI_CIEOBS,
                         out='COI,cct',
                         extrapolate_rfl=False):
    """
    Calculate the Cyanosis Observation Index (COI) [ASNZS 1680.2.5-1995].
    
    Args:
        :S:
            | ndarray with light source spectrum (first column are wavelengths).
        :tf:
            | _COI_CSPACE, optional
            | Color space in which to calculate the COI.
            | Default is CIELAB.
        :cieobs: 
            | _COI_CIEOBS, optional
            | CMF set to use. 
            | Default is '1931_2'.
        :out: 
            | 'COI,cct' or str, optional
            | Determines output.
        :extrapolate_rfl:
            | False, optional
            | If False: 
            |  limit the wavelength range of the source to that of the standard
            |  reflectance spectra for the 50% and 100% oxygenated blood.
            
    Returns:
        :COI:
            | ndarray with cyanosis indices for input sources.
        :cct:
            | ndarray with correlated color temperatures.
            
    Note:
        Clause 7.2 of the ASNZS 1680.2.5-1995. standard mentions the properties
        demanded of the light source used in region where visual conditions 
        suitable to the detection of cyanosis should be provided:
        
            1. The correlated color temperature (CCT) of the source should be from 
            3300 to 5300 K.
                
            2. The cyanosis observation index should not exceed 3.3

    """

    if S is None:  #use default
        S = _CIE_ILLUMINANTS['F4']

    if extrapolate_rfl == False:  # _COI_RFL do not cover the full 360-830nm range.
        wl_min = _COI_RFL_BLOOD[0].min()
        wl_max = _COI_RFL_BLOOD[0].max()
        S = S[:, np.where((S[0] >= wl_min) & (S[0] <= wl_max))[0]]

    # Calculate reference spd:
    Sr = blackbody(4000, wl3=S[0])  # same wavelength range

    # Calculate xyz of blood under test source and ref. source:
    xyzt, xyzwt = spd_to_xyz(S,
                             rfl=_COI_RFL_BLOOD,
                             relative=True,
                             cieobs=cieobs,
                             out=2)
    xyzr, xyzwr = spd_to_xyz(Sr,
                             rfl=_COI_RFL_BLOOD,
                             relative=True,
                             cieobs=cieobs,
                             out=2)

    # Calculate color difference between blood under test and ref.
    DEi = deltaE.DE_cspace(xyzt, xyzr, xyzwt=xyzwt, xyzwr=xyzwr, tf=tf)

    # Calculate Cyanosis Observation Index:
    COI = np.nanmean(DEi, axis=0)[:, None]

    # Calculate cct, if requested:
    if 'cct' in out.split(','):
        cct, duv = xyz_to_cct(xyzwt, cieobs=cieobs, out=2)

    # manage output:
    if out == 'COI':
        return COI
    elif out == 'COI,cct':
        return COI, cct
    else:
        return eval(out)
    '_COI_RFL_BLOOD', '_COI_CIEOBS', '_COI_CSPACE', 'spd_to_COI_ASNZS1680'
]

# Reflectance spectra of 100% and 50% oxygenated blood
_COI_RFL_BLOOD = getdata(_PKG_PATH + _SEP + 'toolboxes' + _SEP +
                         'photbiochem' + _SEP + 'data' + _SEP +
                         'ASNZS_1680.2.5_1997_cyanosisindex_100_50.dat',
                         header=None,
                         kind='np',
                         verbosity=0).T

_COI_CIEOBS = '1931_2'  # default CMF set

_COI_CSPACE = 'lab'

_COI_REF = blackbody(4000, )


def spd_to_COI_ASNZS1680(S=None,
                         tf=_COI_CSPACE,
                         cieobs=_COI_CIEOBS,
                         out='COI,cct',
                         extrapolate_rfl=False):
    """
    Calculate the Cyanosis Observation Index (COI) [ASNZS 1680.2.5-1995].
    
    Args:
        :S:
            | ndarray with light source spectrum (first column are wavelengths).
        :tf:
            | _COI_CSPACE, optional