Пример #1
0
def find_tracks(n=-1, maxdist=20, giveup=10, cut=False):
    sys.setrecursionlimit(max(sys.getrecursionlimit(), 2*giveup))

    trackids = -np.ones(data.shape, dtype=int)
    if n==-1:
        n = np.count_nonzero(data['f']==0)
        print "number of particles:", n

    if cut:
        bgimage = locdir + prefix + '_0001.tif'
        from os.path import isfile
        if not isfile(bgimage):
            bgimage = raw_input('Please give the path to an image '
                                'from this dataset to identify boundary\n')
        C, R = helpy.circle_click(bgimage)
        margin = S if S>1 else R/16.9 # assume 6mm particles if S not specified
        rs = np.hypot(data['x'] - C[0], data['y'] - C[1])
        cut = rs > R - margin

    print "seeking tracks"
    for i in range(len(data)):
        trackids[i] = find_closest(data[i], trackids,
                                   maxdist=maxdist, giveup=giveup, cut=cut)

    # save the data record array and the trackids array
    print "saving track data"
    # Michael used the data['lab'] field (as line[3] for line in data) to store
    # trackids. I'll keep doing that:
    assert len(data) == len(trackids), "too few/many trackids"
    assert np.allclose(data['id'], np.arange(len(data))), "gap in particle id"
    data['lab'] = trackids
    #data = data[trackids < n] # michael did this to "crop out extra tracks"

    stubs = np.where(np.bincount(trackids+1)[1:] < args.stub)[0]
    if verbose: print "removing {} stubs".format(len(stubs))
    stubs = np.in1d(trackids, stubs)
    trackids[stubs] = -1
    return trackids
Пример #2
0
def find_tracks(pdata, maxdist=20, giveup=10, n=0, cut=False, stub=0):
    """ Track dots from frame-to-frame, giving each particle a unique and
        persistent id, called the trackid.

        parameters
        ----------
        pdata : the main positions data array
        maxdist : maximal separation in pixels between a particles current
            and previous position. i.e., the maximum distance a particle is
            allowed to travel to be considered part of the same track
            A good choice for this value is the size of one particle.
        giveup : maximal number of frames to recurse over seeking the parent
        n : the number of particles to track, useful if you wish to have one
            track per physical particle. Not useful if you want tracks to be
            cut when the particle hits the boundary
        cut : whether or not to cut tracks (assign a new trackid to the same
            physical particle) when the particle nears or hits the boundary
            if True, it requires either args.boundary or for user to click on
            an image to mark the center and boundary. Particle at the boundary
            (between two tracks) will have track id of -1
        stub : minimal length of a track for it to be kept. trackids of any
            track with length less than `stub` will be set to -1

        returns
        -------
        trackids : an array of length `len(pdata)`, giving the track id number
            for each point in data. Any point not belonging to any track has a
            track id of -1
    """
    from sys import setrecursionlimit, getrecursionlimit
    setrecursionlimit(max(getrecursionlimit(), 2*giveup))

    trackids = -np.ones(pdata.shape, dtype=int)
    if n is True:
        # use the mode of number of particles per frame
        # np.argmax(np.bincount(x)) == mode(x)
        n = np.argmax(np.bincount(np.bincount(pdata['f'])))
        print "Found {n} particles, will use {n} longest tracks".format(n=n)

    if cut:
        if args.boundary:
            print "cutting at supplied boundary"
            x0, y0, R = args.boundary
        elif 'track_cut_boundary' in meta:
            print "cutting at previously saved boundary"
            x0, y0, R = meta['track_cut_boundary']
        else:
            not_found = ('Please give the path to a tiff image '
                         'from this dataset to identify boundary\n')
            bgimage = helpy.find_first_frame([locdir, prefix], err=not_found)
            x0, y0, R = helpy.circle_click(bgimage)
            print "cutting at selected boundary (x0, y0, r):", x0, y0, R
        # assume 6mm particles if S not specified
        mm = R/101.6 # R = 4 in = 101.6 mm
        margin = S if S>1 else 6*mm
        meta['track_cut_boundary'] = (x0, y0, R)
        meta['track_cut_margin'] = margin
        print 'Cutting with margin {:.1f} pix = {:.1f} mm'.format(margin, margin/mm)
        rs = np.hypot(pdata['x'] - x0, pdata['y'] - y0)
        cut = rs > R - margin

    print "seeking tracks"
    for i in xrange(len(pdata)):
        # This must remain a simple loop because trackids gets modified and
        # passed into the function with each iteration
        trackids[i] = find_closest(pdata.item(i), trackids,
                                   maxdist=maxdist, giveup=giveup, cut=cut)

    if verbose:
        assert len(pdata) == len(trackids), "too few/many trackids"
        assert np.allclose(pdata['id'], np.arange(len(pdata))), "gap in particle id"

    if n or stub > 0:
        track_lens = np.bincount(trackids+1)[1:]
    if n:
        stubs = np.argsort(track_lens)[:-n] # all but the longest n
    elif stub > 0:
        stubs = np.where(track_lens < stub)[0]
        if verbose: print "removing {} stubs".format(len(stubs))
    if n or stub > 0:
        stubs = np.in1d(trackids, stubs)
        trackids[stubs] = -1
    return trackids
Пример #3
0
        sizes.update({
            'corner': {
                'max_ecc': args.cecc,
                'min_area': args.cmin or int(ckern_area // 2),
                'max_area': args.cmax or int(ckern_area * 2 + 1),
                'kern': args.ckern,
                'thresh': args.cthresh
            }
        })
    dots = sorted(sizes)
    meta.update(
        {dot + '_' + k: v
         for dot in dots for k, v in sizes[dot].iteritems()})

    if args.boundary is not None:
        args.boundary = args.boundary or helpy.circle_click(first)
        meta.update(boundary=args.boundary)

    def snapshot(desc, im, **kwargs):
        global snapshot_num, imprefix
        if args.save:
            fname = '{}_{:02d}_{}.png'.format(imprefix, snapshot_num, desc)
            plt.imsave(fname, im, **kwargs)
        else:
            fig, ax = plt.subplots()
            ax.imshow(im,
                      title=os.path.basename(imprefix) + '_' + desc,
                      **kwargs)
        snapshot_num += 1

    def plot_points(pts,
Пример #4
0
                        'thresh': args.thresh}}
    if args.ckern:
        args.both = True
    if args.both:
        ckern_area = np.pi*args.ckern**2
        sizes.update({'corner': {'max_ecc': args.cecc,
                                 'min_area': args.cmin or int(ckern_area//2),
                                 'max_area': args.cmax or int(ckern_area*2 + 1),
                                 'kern': args.ckern,
                                 'thresh': args.cthresh}})
    dots = sorted(sizes)
    meta.update({dot + '_' + k: v
                 for dot in dots for k, v in sizes[dot].iteritems()})

    if args.boundary is not None:
        args.boundary = args.boundary or helpy.circle_click(first)
        meta.update(boundary=args.boundary)

    def snapshot(desc, im, **kwargs):
        global snapshot_num, imprefix
        if args.save:
            fname = '{}_{:02d}_{}.png'.format(imprefix, snapshot_num, desc)
            plt.imsave(fname, im, **kwargs)
        else:
            fig, ax = plt.subplots()
            ax.imshow(im, title=os.path.basename(imprefix)+'_'+desc, **kwargs)
        snapshot_num += 1

    def plot_points(pts, img, name='', s=10, c='r', cmap=None,
                    vmin=None, vmax=None, cbar=False):
        global snapshot_num, imprefix
Пример #5
0
    if args.ckern:
        args.both = True
    if args.both:
        ckern_area = np.pi*args.ckern**2
        if args.cmin == -1: args.cmin = ckern_area/2
        if args.cmax == -1: args.cmax = 2*ckern_area
        thresh.update({'corner':
                        {'max_ecc' : args.cecc,
                         'min_area': args.cmin,
                         'max_area': args.cmax,
                         'kern'   : args.ckern}})
    dots = sorted(thresh)

    if args.select:
        co, ro = helpy.circle_click(filenames[0])

    def plot_positions(savebase, level, pts, labels, convolved=None,):
        cm = pl.cm.prism_r
        pl.clf()
        labels_mask = labels.astype(float)
        labels_mask[labels_mask==0] = np.nan
        pl.imshow(labels_mask, cmap=cm, interpolation='nearest')
        ax = pl.gca()
        xl, yl = ax.get_xlim(), ax.get_ylim()
        if level > 1:
            ptsarr = np.asarray(pts)
            pl.scatter(ptsarr[:,1], ptsarr[:,0], s=10, c='r')#ptsarr[:,2], cmap=cm)
            pl.xlim(xl); pl.ylim(yl)
        savename = savebase + '_POSITIONS.png'
        if args.verbose: print 'saving positions image to', savename
Пример #6
0
 kern_area = np.pi * args.kern**2
 size = {
     'center': {
         'max_ecc': args.ecc,
         'min_area': args.min or int(kern_area // 2),
         'max_area': args.max or int(kern_area * 2 + 1),
         'kern': float(args.kern),
         'thresh': args.thresh,
         'convex': args.convex
     }
 }
 meta.update({k: v for k, v in size['center'].iteritems()})
 #initialize boundary
 boundary = meta.get('boundary')
 if boundary is None or boundary == [0.0] * 3:
     boundary = helpy.circle_click(first)
 meta.update(boundary=boundary)
 helpy.save_meta(prefix, meta)
 x0, y0, R0 = boundary
 #initialize model for machine leanring
 device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
 # load category network
 net_cat = ClassNet()
 net_cat.load_state_dict(torch.load(args.cpath))
 net_cat.eval()
 net_cat.to(device)
 # load orientation network
 net = ConvNet()
 net.load_state_dict(torch.load(args.opath))
 net.eval()
 net.to(device)
Пример #7
0
def find_tracks(maxdist=20, giveup=10, n=0, cut=False, stub=0):
    """ Track dots from frame-to-frame, giving each particle a unique and
        persistent id, called the trackid.

        parameters
        ----------
        maxdist : maximal separation in pixels between a particles current
            and previous position. i.e., the maximum distance a particle is
            allowed to travel to be considered part of the same track
            A good choice for this value is the size of one particle.
        giveup : maximal number of frames to recurse over seeking the parent
        n : the number of particles to track, useful if you wish to have one
            track per physical particle. Not useful if you want tracks to be
            cut when the particle hits the boundary
        cut : whether or not to cut tracks (assign a new trackid to the same
            physical particle) when the particle nears or hits the boundary
            if True, it requires either args.center or for user to click on an
            image to mark the center and boundary. Particle at the boundary
            (between two tracks) will have track id of -1
        stub : minimal length of a track for it to be kept. trackids of any
            track with length less than `stub` will be set to -1

        accesses
        --------
        data : the main data array

        modifies
        --------
        data : replaces the `data['lab']` field with the values from `trackids`

        returns
        -------
        trackids : an array of length `len(data)`, giving the track id number
            for each point in data. Any point not belonging to any track has a
            track id of -1
    """
    from sys import setrecursionlimit, getrecursionlimit
    setrecursionlimit(max(getrecursionlimit(), 2*giveup))

    trackids = -np.ones(data.shape, dtype=int)
    if n is True:
        # use the mode of number of particles per frame
        # np.argmax(np.bincount(x)) == mode(x)
        n = np.argmax(np.bincount(np.bincount(data['f'])))
        print "Found {n} particles, will use {n} longest tracks".format(n=n)

    if cut:
        if args.center:
            C = args.center[:2]
            R = args.center[2]
        else:
            from glob import glob
            bgimage = glob(locdir + prefix + "*.tif")
            if not bgimage:
                bgimage = glob(locdir + prefix + "/*.tif")
            if not bgimage:
                bgimage = glob(locdir + '../' + prefix + "/*.tif")
            if not bgimage:
                bgimage = raw_input('Please give the path to a tiff image '
                                    'from this dataset to identify boundary\n')
            else:
                bgimage = bgimage[0]
                print 'Opening', bgimage
            C, R = helpy.circle_click(bgimage)
            print "Boundary:", C, R
        margin = S if S>1 else R/16.9 # assume 6mm particles if S not specified
        rs = np.hypot(data['x'] - C[0], data['y'] - C[1])
        cut = rs > R - margin

    print "seeking tracks"
    for i in range(len(data)):
        trackids[i] = find_closest(data[i], trackids,
                                   maxdist=maxdist, giveup=giveup, cut=cut)

    if verbose:
        assert len(data) == len(trackids), "too few/many trackids"
        assert np.allclose(data['id'], np.arange(len(data))), "gap in particle id"

    if n or stub > 0:
        track_lens = np.bincount(trackids+1)[1:]
    if n:
        stubs = np.argsort(track_lens)[:-n] # all but the longest n
    elif stub > 0:
        stubs = np.where(track_lens < stub)[0]
        if verbose: print "removing {} stubs".format(len(stubs))
    if n or stub > 0:
        stubs = np.in1d(trackids, stubs)
        trackids[stubs] = -1
    # Michael used the data['lab'] field (as line[3] for line in data) to store
    # trackids. I'll keep doing that:
    data['lab'] = trackids
    return trackids