Example #1
0
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
Example #3
0
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)
Example #4
0
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]