def find_testlightFromRG(self, r, g): '''Returns -1 if not found (extra spectral or doesn't live on locus) ''' err = lambda r, g, lam: np.sqrt((r - self.rVal[lam]) ** 2 + (g - self.gVal[lam]) ** 2) # Check if point is extra spectral a = np.array([r, g]) - np.array([self.rVal[0], self.gVal[0]]) b = np.array([self.rVal[-1], self.gVal[-1]]) - np.array( [self.rVal[0], self.gVal[0]]) a = int(cart2pol(a[0], a[1])[0]) b = int(cart2pol(b[0], b[1])[0]) if a == b: return -1 # This point is extra spectral i = 0 startE = err(r, g, i) forward = True while forward: e = err(r, g, i) if startE < e and e < 0.05: forward = False else: startE = e if i + 1 > len(self.spectrum) - 1: return -1 # either extra spectral or not on spec locus i += 1 t0 = err(r, g, i) t1 = err(r, g, i - 1) e1 = t1 / (t1 + t0) # take a weighted averge of the points outLam = self.spectrum[i] * e1 + self.spectrum[i - 1] * (1 - e1) return outLam
def find_dominant_wl(self, rg, white=[1/3, 1/3]): '''Find the dominant wavelength from a given point within the chromaticity diagram. If extra spectral, returns str. ''' rg = np.asarray(rg) white = np.asarray(white) ## make sure both are len 3 vectors if len(rg) == 2: rgb = np.array([rg[0], rg[1], 1 - (rg.sum())]) else: rgb = rg if len(white) == 2: white = np.array([white[0], white[1], 1 - white.sum()]) point = rgb - white # make sure white point wasn't fed in if round(point[0], 2) == 0.0 and round(point[1] == 0.0, 2): return 0 neutral_points = self.find_spect_neutral(rgb, white) dom = None for i, neutral in enumerate(neutral_points): n = neutral - white[:2] a = int(cart2pol(n[0], n[1])[0]) b = int(cart2pol(point[0], point[1])[0]) if a == b: dom = self.find_testlightFromRG(neutral[0], neutral[1]) break # must be extra spectral: use complementary color if dom == -1: if i == 0: i = 1 if i == 1: i = 0 neutral = neutral_points[i] # return as negative number to indicate it is a complement dom = -1 * self.find_testlightFromRG(neutral[0], neutral[1]) elif dom == None: raise ValueError('dominant wavelength not found') return dom
def welch2d(x,L = None, over = 0.5, win = 2.0): """2D spectrum estimation using Welch's method. The spectrum of an image x is estimated using Welch's \ method of averaging modified periodograms. :param x: image :param L: section length :param over: amount of overlap, where 0<over<1, :param win: The window type \n 1 = Rectangular \n 2 = Hamming \n 3 = Hanning \n 4 = Bartlett \n 5 = Blackman \n :returns: Welch's estimate of the power spectrum, returned in decibels. .. note:: Modified from: M.H. Hayes. \ "Statistical Digital Signal Processing and Modeling" \ (John Wiley & Sons, 1996). """ xs, ys = x.shape x = RemoveMean(x) if L == None: L = xs if xs / ys != 1.0: raise ValueError('This is a stupid program. Dimensions need to be \ equal (len(x)=len(y))') if L < len(x[:,0]) / 2.0: raise ValueError('Length must be longer than 1/2 length of x') if (over >= 1) or (over < 0): raise ValueError('Overlap is invalid') n0 = (1.0 - over) * L n1 = np.array([1.0, 1.0]) - n0 n2 = np.array([L, L]) - n0 nsect = int(1.0 + np.floor((len(x) - L) /( n0))) Px = 0 for ix in range(0,nsect): n1[0] = n1[0] + n0 n2[0] = n2[0] + n0 for iy in range(0,nsect): n1[1] = n1[1] + n0 n2[1] = n2[1] + n0 Px += PowerSpectrum2(x[n1[0]:n2[0],n1[1]:n2[1]], win) / (nsect**2) xs, ys = Px.shape f2 = np.arange(-xs / 2.0, xs / 2.0) f1 = np.arange(-ys / 2.0, ys / 2.0) XX, YY = np.meshgrid(f1,f2) foo, r = dm.cart2pol(XX,YY) if np.mod(xs,2)==1 or np.mod(ys,2)==1: r = np.around(r)-1 else: r = np.around(r) r = np.array(r,dtype=int) ### need to possibly use a for loop. avg = dm.accum(r.flatten() + 1, Px.flatten() )[1:] / dm.accum(r.flatten() + 1)[1:] avg = avg[:(xs / 2 + 1)] return avg