def firebp(n, w1, w2, Del): """[h,rs,be] = firebp(n,w1,w2,Del); Bandpass linear phase FIR filter design with specified ripple sizes. - the derivative of the frequency response amplitude at w1 is set equal to the negative derivative of the amplitude at w2 - author : Ivan Selesnick, Rice University, Dec 94 parameters h : filter of length 2*n+1 rs : reference set upon convergence be : band edges of h w1 : first half-magnitude frequency w2 : second half-magnitude frequency w1 < w2, w1,w2 should be in the interval (0,pi) Del : [ripple size in first stopband, passband, second stopband] subprograms needed localmax, frefine, firfbe EXAMPLE n = 23; w1 = 0.14 * 2*pi; w2 = 0.34 * 2*pi; Del = [0.01 0.03 0.01]; [h,rs,be] = firebp(n,w1,w2,Del); """ def rem(a, b): return a % b try: log2 except: def log2(a): return log(a, 2) def mp(t, lngth): #minus_plus vector [-1 1 -1 ... (-1)^lngth] assert isinstance(lngth, int), 'Length argument to mp must be an integer. ' assert isinstance(t,str) and t in ['vview_d','vview_f'],\ "type argument must be 'vview_d' or 'vview_f'" retview = create(t, lngth).fill(1.0) retview[:lngth:2].fill(-1.0) return retview def diff(a): assert 'pyJvsip' in repr(a), 'diff only works with pyJvsip views' assert 'vview' in a.type, 'diff only works with vector views' if a.length > 1: retview = a[1:a.length] - a[:a.length - 1] return retview else: return None def srmp(t, s, e): assert isinstance(e, int) and isinstance( s, int), 'start and end must be intergers' assert e > s, 'simple ramps alwasy go up; end > start ' return pv.create(t, e - s + 1).ramp(s, 1) def coscoef(rs, n, V, Y): f = {'vview_d': 'mview_d', 'vview_f': 'mview_f'} m = rs.length + 1 y = pv.create(Y.type, m) y[:Y.length] = Y y[m - 1] = 0.0 A = pv.create(f[y.type], m, y.length) a = A[:rs.length, :n + 1] a = pv.outer(1, rs, pv.create(rs.type, n + 1).ramp(0, 1), a).cos at = A.rowview(m - 1) A.rowview(m - 1)[:] = V[:] return A.luSolve(y) # ------------------ initialize constants --------------------------- assert 'pyJvsip' in repr(Del) and Del.type in ['vview_f','vview_d'],\ "last argument is a vector view of type 'vview_f' or 'vview_d'" t = Del.type L = int(pow(2, int(ceil(log2(10 * n))))) w = pv.create(t, L + 1).ramp(0, pi / float(L)) # frequency axis N = n - 2 # number of _non-specified interpolation points SN = 1e-8 # Small Number (stopping criterion) H0 = pv.create(t, 2 * (L + 1 - n) + 2 * n - 2).fill(0.0) V = pv.create(t, n + 1).ramp(0, 1) V *= V.empty.ramp(0, w1).sin + V.empty.ramp(0, w2).sin ideal = Del.empty.fill(0.0) ideal[1] = 1.0 up = ideal + Del lo = ideal - Del D1 = 0.5 # half-magnitude value at w1 D2 = 0.5 # half-magnitude value at w2 PF = False # PF : flag : Plot Figures # ------------------ initialize reference set ---------------------------- # n1 : number of reference frequencies in first stopband # n2 : number of reference frequencies in passband # n3 : number of reference frequencies in second stopband n2 = int(round(N * (w2 - w1) / pi)) if rem(n2, 2) == 0: n2 = n2 - 1 n1 = int(floor((N - n2) * w1 / (pi - (w2 - w1)))) n3 = N - n2 - n1 rs = pv.create(t, n1 + n2 + n3 + 2) R1 = rs[0:n1].ramp(0, 1) R1 *= w1 / float(n1) R2 = rs[n1 + 1:n1 + 1 + n2].ramp(1, 1) R2 *= (w2 - w1) / float(n2 + 1) R2 += w1 R3 = rs[n1 + n2 + 2:n1 + n2 + 2 + n3].ramp(1, 1) R3 *= (pi - w2) / float(n3) R3 += w2 rs[n1] = w1 rs[n1 + 1 + n2] = w2 # ------------------ initialize interpolation values --------------------- Y = pv.create(t, n1 + n2 + n3 + 2).fill(0.0) if n1 % 2 == 0: Y[0:n1:2].fill(up[0]) Y[1:n1:2].fill(lo[0]) else: Y[0:n1:2].fill(lo[0]) Y[1:n1:2].fill(up[0]) Y[n1] = D1 o = n1 + 1 l = n1 + 1 + n2 Y[o:l:2].fill(up[1]) Y[o + 1:l:2].fill(lo[1]) Y[l] = D2 o = l + 1 l = o + n3 Y[o:l:2].fill(lo[2]) Y[o + 1:l:2].fill(up[2]) # begin looping Err = 1 while Err > SN: # --------------- calculate cosine coefficients ----------------------- a = coscoef(rs, n, V, Y) # --------------- calculate frequency response ------------------------ #H = real(fft([a(1);a(2:n+1)/2;Z;a(n+1:-1:2)/2])); H = H(1:L+1); attr = a.attrib ot = attr['offset'] lt = attr['length'] st = attr['stride'] ot += (lt - 1) * st st = -st attr['offset'] = ot attr['stride'] = st a_rev = a.cloneview a_rev.putattrib(attr) H0.fill(0.0) H0[0] = a[0] H0[1:lt] = a[1:] * 0.5 H0[H0.length - n:] = a_rev[:lt - 1] * 0.5 Hc = H0.rcfft H = Hc.realview[:L + 1].copy # --------------- determine local max and min ------------------------- v1 = localmax(H) v2 = localmax(H.copy.neg) if v1[0] < v2[0]: s = 0 else: s = 1 #ri = sortip([v1; v2]); ri = pv.create(H.type, v1.length + v2.length) ri[:v1.length] = v1 ri[v1.length:] = v2 ri.sortip() rs = (ri) * (pi / L) rs = frefine(a, rs) n1 = rs.llt(w1).sumval n2 = pv.bb_and(rs.lgt(w1), rs.llt(w2), pv.create('vview_bl', rs.length)).sumval n3 = rs.lgt(w2).sumval # --------------- calculate frequency response at local max and min --- Hr = rs.outer(srmp(rs.type, 0, n)).cos.prod(a) Id = pv.create(Del.type, n1 + n2 + n3) Dr = Id.empty Id[:n1].fill(ideal[0]) Id[n1:n1 + n2].fill(ideal[1]) Id[n1 + n2:].fill(ideal[2]) Dr[:n1].fill(Del[0]) Dr[n1:n1 + n2].fill(Del[1]) Dr[n1 + n2:].fill(Del[2]) Er = (Hr - Id) * Dr.recip # Plot Figures if PF is True if PF: figure(1) plot((w * (1. / pi)).list, H.list) hold(True) plot((rs * (1.0 / pi)).list, Hr.list, 'o') hold(False) axis([0, 1, -.2, 1.2]) figure(2) plot(Er.list) hold(True) plot(Er.list, 'o'), hold(False) pause(0.05) # --------------- calculate new interpolation points ----------------- Y = Id.empty if n1 % 2 == 0: Y[0:n1:2].fill(up[0]) Y[1:n1:2].fill(lo[0]) else: Y[0:n1:2].fill(lo[0]) Y[1:n1:2].fill(up[0]) Y[n1 + 1:n1 + n2:2].fill(lo[1]) Y[n1:n1 + n2:2].fill(up[1]) Y[n1 + n2 + 1::2].fill(up[2]) Y[n1 + n2::2].fill(lo[2]) # --------------- slim down the set of local max and min -------------- # --------------- to obtain new reference set of correct size --------- if (rs.length - N) == 1: # remove one frequency from the reference set if abs(Er[0] - Er[1]) < abs(Er[rs.length - 1] - Er[rs.length - 2]): I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] elif (rs.length - N) == 2: # remove two frequencies # remove either the two endpoints or remove two adjacent points in the ref. set k = (diff(Er) * (mp(Er.type, rs.length - 1) + s)).minvalindex + 1 if (k == 1) | (k == (rs.length - 1)): if k == 1: I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] if abs(Er[0] - Er[1]) < abs(Er[rs.length - 1] - Er[rs.length - 2]): I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] else: I = k del rs[I - 1] del Y[I - 1] del Er[I - 1] del rs[I - 1] del Y[I - 1] del Er[I - 1] elif (rs.length - N) == 3: # remove three frequencies # just use the code for (rs.length-N)==1, followed by the code for (rs.length-N)==2 if abs(Er[0] - Er[1]) < abs(Er[rs.length - 1] - Er[rs.length - 2]): I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] k = (diff(Er) * (mp(Er.type, rs.length - 1) + s)).minvalindex + 1 if (k == 1) or (k == (rs.length - 1)): if k == 1: I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] if abs(Er[0] - Er[1]) < abs(Er[rs.length - 1] - Er[rs.length - 2]): I = 1 s = s + 1 else: I = rs.length del rs[I - 1] del Y[I - 1] del Er[I - 1] else: I = k del rs[I - 1] del Y[I - 1] del Er[I - 1] del rs[I - 1] del Y[I - 1] del Er[I - 1] # END IF # calculate error Err = Er.maxmgval - 1 #max(abs(Er))-1 print(' Err = %20.15f\n' % Err) if Err > SN: # --------------- update new interpolation points --------------------- n1 = rs.llt(w1).sumval n2 = pv.bb_and(rs.lgt(w1), rs.llt(w2), pv.create('vview_bl', rs.length)).sumval n3 = rs.lgt(w2).sumval Y1 = Y[0:n1].copy Y2 = Y[n1:n1 + n2].copy Y3 = Y[n1 + n2:].copy Y = pv.create(Y1.type, n1 + n2 + n3 + 2) Y[0:n1] = Y1 Y[n1] = D1 Y[n1 + 1:n1 + n2 + 1] = Y2 Y[n1 + n2 + 1] = D2 Y[n1 + n2 + 2:] = Y3 # --------------- update new reference set ---------------------------- #rs = [rs(1:n1); w1; rs(n1+1:n1+n2); w2; rs(n1+n2+1:n1+n2+n3)] rst1 = rs[0:n1].copy rst2 = rs[n1:n1 + n2].copy rst3 = rs[n1 + n2:].copy rs = pv.create(rst1.type, rs.length + 2) rs[:n1] = rst1 rs[n1] = w1 rs[n1 + 1:n1 + n2 + 1] = rst2 rs[n1 + n2 + 1] = w2 rs[n1 + n2 + 2:] = rst3 #end while # ------------------ calculate band edges ---------------------------- be = firfbe(a, pv.listToJv(Del.type, [w1, w1, w2, w2]), pv.listToJv(Del.type, [up[0], lo[1], lo[1], up[2]])) # ------------------ calcuate filter coefficients ---------------------------- #h = [a(n+1:-1:2)/2; a(1); a(2:n+1)/2] a[1:] *= 0.5 atr = a[1:].attrib h = pv.create(Del.type, 2 * a.length - 1) h[a.length - 1] = a[0] h[a.length:] = a[1:] atr = a[1:].attrib atr['offset'] = atr['length'] atr['stride'] *= -1 a.putattrib(atr) h[:a.length] = a figure(1) plot((w * (1.0 / pi)).list, H.list) hold(True) plot((rs * (1.0 / pi)).list, Y.list, 'x') hold(False) axis([0, 1, -.2, 1.2]) xlabel('w') ylabel('H') title('Frequency Response Amplitude') return (h, rs, be)
def feature2D(img, Lambda, w, masscut=0, Imin=0, field=2, bandpass='******', verbose=True): # Written 7-29-03 by Maria Kilfoil # Finds and measures roughly circular 'features' within an image. # note: extent should be 2*w+1 in which w is the same as bpass. # CALLING SEQUENCE: # f = feature2D(image,lambda,diameter,masscut,Imin,field) # INPUTS: # img: (nx,ny) array which presumably contains some features worth finding # Lambda: length scale of noise to be filtered out, in pixels; typically 1 # w: a parameter which should be a little greater than the radius of the # largest features in the image. # Imin: (optional) Set this optional parameter to the minimum allowed value for the peak # brightness of a feature. Useful for limiting the number of spurious features in # noisy images. If set to 0 (default), the top 30# of the bright pixels # will be used. # masscut: (optional) Setting this parameter saves runtime by reducing the runtime wasted on # low mass 'noise' features. (default is 0, accept all.) # field: (optional) Set this parameter to 0 or 1 if image is actually just one (odd or even) field of an interlaced # (e.g. video) image. All the masks will then be constructed with a 2:1 aspect ratio. Otherwise # set to 2 for progressive scan cameras. # bandpass: (optional) Setting this parameter to 'bp' will run feature finding on the bandpassed image, while setting # it to 'raw' will run feature finding on the raw image. The default is 'raw'. # # NOT IMPLEMENTED: # separation: an optional parameter which specifies the minimum allowable separation # between feature centers. The default value is diameter+1. # # # OUTPUTS: # f(:,1): the x centroid positions, in pixels. # f(:,2): the y centroid positions, in pixels. # f(:,3): integrated brightness of the features. ("mass") # f(:,4): the square of the radius of gyration of the features. # (second moment of the "mass" distribution, where mass=intensity) # f(:,5): eccentricity, which should be zero for circularly symmetric features and # order one for very elongated images. # RESTRICTIONS: # To work properly, the image must consist of bright, circularly symmetric regions # on a roughly zero-valued background. To find dark features, the image should be # inverted and the background subtracted. If the image contains a large amount of # high spatial frequency noise, performance will be improved by first filtering the image. # BPASS will remove high spatial frequency noise, and subtract the image background. # Individual features should NOT overlap. # # MODIFICATION HISTORY: # This code is inspired by feature_stats2 written by # David G. Grier, U of Chicago, 1992. # Written by John C. Crocker, U of Chicago, optimizing # runtime and measurement error, 10/93. # Matlab version written by Maria L. Kilfoil 2003. # 10-18-07 Vincent Pelletier, Maria Kilfoil -- added masscut to Matlab version # June 2013 - Adpated for Python by Kevin Smith (Maria Kilfoil's Group) extent = 2. * w + 1 if (bandpass == 'bp'): image = bpass.bpass(img, Lambda, w) elif (bandpass == 'raw'): image = img else: image = img if extent % 2 == 0: print('Requires an odd extent. Adding 1...') extent = extent + 1 sz = image.shape nx = sz[1] ny = sz[0] # if n_params() eq 2 then sep = extent+1 sep = extent #Put a border around the image to prevent mask out-of-bounds #Only use the following 2 lines if you are not using bpass to do spatial filtering first. #Otherwise, image returned from bpass already had a border of w width a = image # Finding the local maxima loc = localmax.localmax(image, sep, field, Imin) if len(loc[0]) == 0 or loc[0][0] == -1: r = -1 return r x = [0] * len(loc[0]) y = [0] * len(loc[0]) for i in xrange(0, len(loc[0])): y[i] = int(loc[0][i]) x[i] = int(loc[1][i]) x = x - np.double(0) #convert to arrays y = y - np.double(0) nmax = len(loc[0]) m = np.zeros((1, len(loc[0])))[0] xl = x - (extent // 2) xh = xl + extent - 1 extent = int(extent) # Set up some masks rsq = create_mask.rsqd(extent, extent) t = create_mask.thetarr(extent) mask = np.less_equal(rsq, (extent / 2)**2) mask2 = np.ones((extent, 1)) * np.arange(1, extent + 1, 1) # checked mask2 = mask2 * mask mask3 = (rsq * mask) + (1 / 6) cen = int((extent - 1) / 2) cmask = np.cos(2 * t) * mask smask = np.sin(2 * t) * mask cmask[cen, cen] = 0.0 smask[cen, cen] = 0.0 suba = np.zeros((extent, extent, nmax)) xmask = mask2 ymask = mask2.T yl = y - (extent // 2) yh = yl + extent - 1 yscale = 1 ycen = cen # Estimate the mass for i in xrange(0, nmax): m[i] = (np.double(a[int(yl[i]):int(yh[i]) + 1, int(xl[i]):int(xh[i]) + 1]) * mask).sum() # remove features based on 'masscut' parameter b = (m > masscut).nonzero() nmax = len(b[0]) if nmax == 0: print('No feature found!') r = [] return r xl = xl[b] xh = xh[b] yl = yl[b] yh = yh[b] x = x[b] y = y[b] m = m[b] if verbose: print(str(nmax) + ' features found.') # Setup some result arrays xc = [0] * nmax - np.double(0) yc = [0] * nmax - np.double(0) rg = [0] * nmax - np.double(0) e = [0] * nmax - np.double(0) # Calculate feature centers for i in xrange(0, nmax): xc[i] = (np.double(a[int(yl[i]):int(yh[i]) + 1, int(np.fix(xl[i])):int(xh[i]) + 1]) * xmask).sum() yc[i] = (np.double(a[int(yl[i]):int(yh[i]) + 1, int(xl[i]):int(xh[i]) + 1]) * ymask).sum() x1 = x y1 = y # Correct for the 'offset' of the centroid masks xc = xc / m - ((extent + 1) / 2) yc = (yc / m - (extent + 1) / 2) / yscale # Update the positions and correct for the width of the 'border' x = x + xc - 0 * (extent // 2) y = (y + yc - 0 * (extent // 2)) * yscale x2 = x y2 = y # Construct the subarray and calculate the mass, squared radius of gyration, eccentricity for i in xrange(0, nmax): suba[:, :, i] = fracshift.fracshift( np.double(a[int(yl[i]):int(yh[i]) + 1, int(xl[i]):int(xh[i]) + 1]), -xc[i], -yc[i]) m[i] = (suba[:, :, i] * mask).sum() rg[i] = ((suba[:, :, i] * mask3).sum()) / m[i] tmp = np.sqrt((((suba[:, :, i] * cmask).sum())**2) + (((suba[:, :, i] * smask).sum())**2)) tmp2 = (m[i] - suba[cen, ycen, i] + 1e-6) e[i] = tmp / tmp2 for i in xrange(0, nmax): xc[i] = np.double(suba[:, :, i] * xmask).sum() yc[i] = np.double(suba[:, :, i] * ymask).sum() xc = xc / m - (extent + 1) / 2 yc = (yc / m - (extent + 1) / 2) / yscale # get mass center x3 = x2 + xc - 0 * (extent // 2) y3 = (y2 + yc - 0 * (extent // 2)) * yscale r_mat = np.zeros((nmax, 5)) r_mat[:, 0] = x3 # final x position r_mat[:, 1] = y3 # final y position r_mat[:, 2] = m # final integrated intensity r_mat[:, 3] = rg # final radius of gyration r_mat[:, 4] = e # final eccentricity # uncomment the following lines if you would like x1, y1, x2, and x3 to be stored # (these are the initial position and the position after the first iteration of centroid fitting). #r2_mat=np.zeros((nmax,4)) #### change to resize array #r_mat=np.hstack([r_mat,r2_mat]) #r_mat[:,5]=x1 #r_mat[:,6]=y1 #r_mat[:,7]=x2 #r_mat[:,8]=y2 r = r_mat return r
def firebp(n,w1,w2,Del): """[h,rs,be] = firebp(n,w1,w2,Del); Bandpass linear phase FIR filter design with specified ripple sizes. - the derivative of the frequency response amplitude at w1 is set equal to the negative derivative of the amplitude at w2 - author : Ivan Selesnick, Rice University, Dec 94 parameters h : filter of length 2*n+1 rs : reference set upon convergence be : band edges of h w1 : first half-magnitude frequency w2 : second half-magnitude frequency w1 < w2, w1,w2 should be in the interval (0,pi) Del : [ripple size in first stopband, passband, second stopband] subprograms needed localmax, frefine, firfbe EXAMPLE n = 23; w1 = 0.14 * 2*pi; w2 = 0.34 * 2*pi; Del = [0.01 0.03 0.01]; [h,rs,be] = firebp(n,w1,w2,Del); """ def rem(a,b): return a % b try: log2 except: def log2(a): return log(a,2) def mp(t,lngth): #minus_plus vector [-1 1 -1 ... (-1)^lngth] assert isinstance(lngth,int),'Length argument to mp must be an integer. ' assert isinstance(t,str) and t in ['vview_d','vview_f'],\ "type argument must be 'vview_d' or 'vview_f'" retview = create(t,lngth).fill(1.0) retview[:lngth:2].fill(-1.0) return retview def diff(a): assert 'pyJvsip' in repr(a),'diff only works with pyJvsip views' assert 'vview' in a.type, 'diff only works with vector views' if a.length > 1: retview = a[1:a.length] - a[:a.length - 1] return retview else: return None def srmp(t,s,e): assert isinstance(e,int) and isinstance(s,int),'start and end must be intergers' assert e > s, 'simple ramps alwasy go up; end > start ' return pv.create(t,e-s+1).ramp(s,1) def coscoef(rs,n,V,Y): f={'vview_d':'mview_d','vview_f':'mview_f'} m=rs.length + 1 y=pv.create(Y.type,m) y[:Y.length]=Y;y[m-1]=0.0 A=pv.create(f[y.type],m,y.length) a=A[:rs.length,:n+1] a=pv.outer(1,rs,pv.create(rs.type,n+1).ramp(0,1),a).cos at=A.rowview(m-1) A.rowview(m-1)[:]=V[:] return A.luSolve(y) # ------------------ initialize constants --------------------------- assert 'pyJvsip' in repr(Del) and Del.type in ['vview_f','vview_d'],\ "last argument is a vector view of type 'vview_f' or 'vview_d'" t=Del.type L = int(pow(2,int(ceil(log2(10*n))))) w = pv.create(t,L+1).ramp(0,pi/float(L)) # frequency axis N = n - 2 # number of _non-specified interpolation points SN = 1e-8 # Small Number (stopping criterion) H0 = pv.create(t,2*(L+1-n)+2*n-2).fill(0.0) V = pv.create(t,n+1).ramp(0,1);V *= V.empty.ramp(0,w1).sin + V.empty.ramp(0,w2).sin ideal = Del.empty.fill(0.0); ideal[1]=1.0 up = ideal + Del lo = ideal - Del D1 = 0.5 # half-magnitude value at w1 D2 = 0.5 # half-magnitude value at w2 PF = False # PF : flag : Plot Figures # ------------------ initialize reference set ---------------------------- # n1 : number of reference frequencies in first stopband # n2 : number of reference frequencies in passband # n3 : number of reference frequencies in second stopband n2 = int(round(N*(w2-w1)/pi)) if rem(n2,2) == 0: n2 = n2 - 1 n1 = int(floor((N-n2)*w1/(pi-(w2-w1)))) n3 = N-n2-n1 rs = pv.create(t,n1+n2+n3+2) R1 = rs[0:n1].ramp(0,1); R1 *= w1/float(n1) R2 = rs[n1+1:n1+1+n2].ramp(1,1);R2 *= (w2-w1)/float(n2+1);R2 += w1 R3 = rs[n1+n2+2:n1+n2+2+n3].ramp(1,1);R3 *= (pi-w2)/float(n3);R3 += w2 rs[n1]=w1; rs[n1+1+n2]=w2 # ------------------ initialize interpolation values --------------------- Y=pv.create(t,n1+n2+n3+2).fill(0.0) if n1 % 2 == 0: Y[0:n1:2].fill(up[0]);Y[1:n1:2].fill(lo[0]) else: Y[0:n1:2].fill(lo[0]);Y[1:n1:2].fill(up[0]) Y[n1]=D1;o=n1+1;l=n1+1+n2 Y[o:l:2].fill(up[1]);Y[o+1:l:2].fill(lo[1]) Y[l]=D2;o=l+1;l=o+n3 Y[o:l:2].fill(lo[2]);Y[o+1:l:2].fill(up[2]) # begin looping Err = 1 while Err > SN: # --------------- calculate cosine coefficients ----------------------- a = coscoef(rs,n,V,Y) # --------------- calculate frequency response ------------------------ #H = real(fft([a(1);a(2:n+1)/2;Z;a(n+1:-1:2)/2])); H = H(1:L+1); attr=a.attrib; ot=attr['offset'];lt=attr['length'];st=attr['stride']; ot+=(lt-1)*st; st=-st;attr['offset']=ot; attr['stride']=st a_rev=a.cloneview;a_rev.putattrib(attr) H0.fill(0.0);H0[0]=a[0];H0[1:lt]=a[1:]*0.5; H0[H0.length-n:]=a_rev[:lt-1]*0.5 Hc=H0.rcfft H=Hc.realview[:L+1].copy # --------------- determine local max and min ------------------------- v1 = localmax(H) v2 = localmax(H.copy.neg) if v1[0] < v2[0]: s = 0; else: s = 1; #ri = sortip([v1; v2]); ri=pv.create(H.type,v1.length+v2.length) ri[:v1.length]=v1;ri[v1.length:]=v2 ri.sortip() rs = (ri)*(pi/L) rs = frefine(a,rs) n1 = rs.llt(w1).sumval n2 = pv.bb_and(rs.lgt(w1), rs.llt(w2), pv.create('vview_bl',rs.length)).sumval n3 = rs.lgt(w2).sumval # --------------- calculate frequency response at local max and min --- Hr = rs.outer(srmp(rs.type,0,n)).cos.prod(a) Id=pv.create(Del.type,n1+n2+n3);Dr=Id.empty Id[:n1].fill(ideal[0]);Id[n1:n1+n2].fill(ideal[1]);Id[n1+n2:].fill(ideal[2]) Dr[:n1].fill(Del[0]);Dr[n1:n1+n2].fill(Del[1]);Dr[n1+n2:].fill(Del[2]) Er = (Hr - Id)*Dr.recip # Plot Figures if PF is True if PF: figure(1) plot((w*(1./pi)).list,H.list) hold(True) plot((rs*(1.0/pi)).list,Hr.list,'o') hold(False) axis([0, 1, -.2, 1.2]) figure(2) plot(Er.list) hold(True) plot(Er.list,'o'), hold(False) pause(0.05) # --------------- calculate new interpolation points ----------------- Y=Id.empty if n1 % 2 == 0: Y[0:n1:2].fill(up[0]);Y[1:n1:2].fill(lo[0]) else: Y[0:n1:2].fill(lo[0]);Y[1:n1:2].fill(up[0]) Y[n1+1:n1+n2:2].fill(lo[1]);Y[n1:n1+n2:2].fill(up[1]) Y[n1+n2+1::2].fill(up[2]);Y[n1+n2::2].fill(lo[2]) # --------------- slim down the set of local max and min -------------- # --------------- to obtain new reference set of correct size --------- if (rs.length-N) == 1: # remove one frequency from the reference set if abs(Er[0]-Er[1]) < abs(Er[rs.length-1]-Er[rs.length-2]): I = 1; s = s + 1; else: I = rs.length; del rs[I-1]; del Y[I-1]; del Er[I-1] elif (rs.length-N) == 2: # remove two frequencies # remove either the two endpoints or remove two adjacent points in the ref. set k = (diff(Er)*(mp(Er.type,rs.length-1)+s)).minvalindex+1; if (k == 1) | (k == (rs.length-1)): if k == 1: I = 1; s = s + 1 else: I = rs.length del rs[I-1]; del Y[I-1]; del Er[I-1] if abs(Er[0]-Er[1]) < abs(Er[rs.length-1]-Er[rs.length-2]): I = 1; s = s + 1; else: I = rs.length; del rs[I-1]; del Y[I-1]; del Er[I-1] else: I = k; del rs[I-1]; del Y[I-1]; del Er[I-1] del rs[I-1]; del Y[I-1]; del Er[I-1] elif (rs.length-N) == 3: # remove three frequencies # just use the code for (rs.length-N)==1, followed by the code for (rs.length-N)==2 if abs(Er[0]-Er[1]) < abs(Er[rs.length-1]-Er[rs.length-2]): I = 1; s = s + 1 else: I = rs.length del rs[I-1]; del Y[I-1]; del Er[I-1] k = (diff(Er)*(mp(Er.type,rs.length-1)+s)).minvalindex+1 if (k == 1) or (k == (rs.length-1)): if k == 1: I = 1; s = s + 1 else: I = rs.length; del rs[I-1]; del Y[I-1]; del Er[I-1] if abs(Er[0]-Er[1]) < abs(Er[rs.length-1]-Er[rs.length-2]): I = 1; s = s + 1 else: I = rs.length; del rs[I-1]; del Y[I-1]; del Er[I-1] else: I = k; del rs[I-1]; del Y[I-1]; del Er[I-1] del rs[I-1]; del Y[I-1]; del Er[I-1] # END IF # calculate error Err = Er.maxmgval-1 #max(abs(Er))-1 print(' Err = %20.15f\n'%Err) if Err > SN: # --------------- update new interpolation points --------------------- n1 = rs.llt(w1).sumval n2 = pv.bb_and(rs.lgt(w1), rs.llt(w2), pv.create('vview_bl',rs.length)).sumval n3 = rs.lgt(w2).sumval Y1 = Y[0:n1].copy Y2 = Y[n1:n1+n2].copy Y3 = Y[n1+n2:].copy Y = pv.create(Y1.type,n1+n2+n3+2) Y[0:n1]=Y1;Y[n1]=D1;Y[n1+1:n1+n2+1]=Y2;Y[n1+n2+1]=D2;Y[n1+n2+2:]=Y3 # --------------- update new reference set ---------------------------- #rs = [rs(1:n1); w1; rs(n1+1:n1+n2); w2; rs(n1+n2+1:n1+n2+n3)] rst1=rs[0:n1].copy;rst2=rs[n1:n1+n2].copy;rst3=rs[n1+n2:].copy rs=pv.create(rst1.type,rs.length+2) rs[:n1]=rst1;rs[n1]=w1;rs[n1+1:n1+n2+1]=rst2;rs[n1+n2+1]=w2;rs[n1+n2+2:]=rst3 #end while # ------------------ calculate band edges ---------------------------- be = firfbe(a,pv.listToJv(Del.type,[w1,w1,w2,w2]),pv.listToJv(Del.type,[up[0],lo[1],lo[1],up[2]])) # ------------------ calcuate filter coefficients ---------------------------- #h = [a(n+1:-1:2)/2; a(1); a(2:n+1)/2] a[1:]*=0.5 atr=a[1:].attrib h=pv.create(Del.type,2*a.length-1) h[a.length-1]=a[0] h[a.length:]=a[1:] atr=a[1:].attrib;atr['offset']=atr['length'];atr['stride']*=-1 a.putattrib(atr);h[:a.length]=a figure(1); plot((w*(1.0/pi)).list,H.list); hold(True); plot((rs*(1.0/pi)).list,Y.list,'x'); hold(False) axis([0, 1, -.2, 1.2]) xlabel('w'); ylabel('H'); title('Frequency Response Amplitude') return(h,rs,be)
data = data[0:9600] T = len(data)/float(fs) k = test * T chunk = 9600 amp, freq = calculatefft(fs, data) print T print len(data) print fs print k print np.amax(amp) print np.where(amp == np.amax(amp)) print freq[np.where(amp == np.amax(amp))] print localmax(amp, k) fs, data = read('training330.wav') for i in range(0, 3): print "SAMPLES" print"----------" tmpdata = data[i*chunk:i*chunk+chunk] amp, freq = calculatefft(fs, tmpdata) print k print np.amax(amp) print np.where(amp == np.amax(amp)) print freq[np.where(amp == np.amax(amp))] print localmax(amp, k) #data = data[0:9600]