Esempio n. 1
0
                                    dc_a,
                                    dc_b,
                                    simisize=simisize,
                                    similim=similim)
    stopwatch += time()

    print("\t{} matches made".format(len(nodes1)))
    print("\tDone in {0:.3f}s\n".format(stopwatch))

#%% Detect silhouette key points
if dosilhouette:
    print("Detecting silhouette points ...")

    stopwatch = -time()
    base = np.row_stack((nodes0[4:], nodes1)) if docorners else nodes0[4:]
    sp_a = algo.spawn(Ea, base[:, [0, 1]], spawnpoints, r_min=simisize)
    sp_b = algo.spawn(Eb, base[:, [2, 3]], spawnpoints, r_min=simisize)
    sp_at = algo.swirl(sp_a, com_a, com_b)
    stopwatch += time()

    print("\t{} silhouette points in A".format(len(sp_a)))
    print("\t{} silhouette points in B".format(len(sp_b)))
    print("\tDone in {0:.3f}s\n".format(stopwatch))

#%% Match key points
if dosilhouette:
    print("Matching silhouette points ...")

    n_spawn = int(spawnpoints / 2)
    stopwatch = -time()
Esempio n. 2
0
#%% Center of mass
print("Center of mass computation ...\n\t", end="")

stopwatch = -time()
com = algo.commie(S)
stopwatch += time()
print("\tDone in {0:.3f}s\n".format(stopwatch))

#%% Detect silhouette key points
print("Detecting silhouette points ...", end="")

stopwatch = -time()
nodes0 = algo.seed(*E.shape, com, com)
base = nodes0[4:]
sp = algo.spawn(E, base[:, [0, 1]], spawnpoints, r_min=simisize)
stopwatch += time()

print("\t{} silhouette points".format(len(sp)))
print("\tDone in {0:.3f}s\n".format(stopwatch))

###########
# Cactify #
###########

#%% Mini center of mass evaluation for each evaluation point
print("Cactification ... ", end="")

stopwatch = -time()
h, w = K.shape[:2]
vv = np.zeros(sp.shape)
Esempio n. 3
0
else:
    Ga = algo.desaturate(Da, cutoff=cutoff)
    Gb = algo.desaturate(Db, cutoff=cutoff)
print("done")

# Center of mass determines translation
print("A ", end="")
com_a = algo.commie(Sa)
print("B ", end="")
com_b = algo.commie(Sb)
base = np.array([[com_a['x'], com_a['y'], com_b['x'], com_b['y']]])

# Detect key points
target = int(np.floor(min([Ea.sum(), Eb.sum()]) * keyfill))
print("Picking key points ... ", end="")
kp_a = algo.spawn(Ea, base[:, [0, 1]], target, r_min=detail)
kp_b = algo.spawn(Eb, base[:, [2, 3]], target, r_min=detail)
print("done")

# Match key points
print("Matching key points ... ", end="")
stopwatch = -time()
extractor = BRIEF(patch_size=patch_size, sigma=0)

extractor.extract(Ga, kp_a[:, [1, 0]])
dc_a = extractor.descriptors

extractor.extract(Gb, kp_b[:, [1, 0]])
dc_b = extractor.descriptors

matches = match_descriptors(dc_a, dc_b)
Esempio n. 4
0
def trajectory(settings, m, recycle=False, thread=None, X=None, Y=None,
               Ka=None, Kb=None, Ea=None, Eb=None, com_a=None, com_b=None,
               kp_a=None, kp_b=None, dc_a=None, dc_b=None):
    """
    Figure out node trajectories for the given morph sequence *m*,
    based on silhouette map and corner descriptors.
    
    Two temporary analysis files are generated:
         - nodes.csv node trajectory coordinates.
         - move.png  node trajectory chart.
    
    Usage
    -----
    >>> nodes, Ka, Kb, com_a, com_b = trajectory(settings, m, recycle, thread)
    
    Parameters
    ----------
    recycle : bool, optional
        If set to True and if output exists from a previous run,
        then that will be recycled.
    thread : object, optional
        Send status reports back through this channel,
        presumably a PyQt Qthread activated by the grapical user interface.
        This can be any object though, as long as it contains:
            - *abort*. A boolean status flag (True/False) that signals whether
              the user has had enough, and pressed a cancel button or such.
            - *report*. A progress report signal.
              Must have a method *emit* that accepts strings
              (which will either an image file name or one-line status report).
    
    Returns
    -------
    None in case of user abort,
    node trajectory coordinate array otherwise.
    
    Notes
    -----
    If silhouette map and corner keypoint coordinates are not available,
    then *silhouette* and *cornercatch* will be called to create these.
    """
    
    # Tell everyone about the fantastic voyage we are about to embark upon
    if count_morphs(settings) > 1:
        label = ' for morph {}'.format(m + 1)
    else:
        label = ''
    shoutout(msg='Detecting trajectories' + label, thread=thread)
    
    # Start the timer
    stopwatch = -time()

    # Key frame indices and output files
    a, b     = morph_key_indices(settings, m)
    folder_m = path.join(settings['temppath'], 'm{0:03d}'.format(m + 1))
    folder_a = path.join(settings['temppath'], 'k{0:03d}'.format(a + 1))
    folder_b = path.join(settings['temppath'], 'k{0:03d}'.format(b + 1))
    f1       = path.join(folder_m, 'move.png')
    f2       = path.join(folder_m, 'nodes.csv')
    
    # Assemble the settings
    s = settings['traject']
    docorners    = s['corners'   ][m]
    dosilhouette = s['silhouette'][m]
    arc          = s['arc'       ][m]
    spin         = s['spin'      ][m] and arc
    similim      = s['similim'   ][m] * 1e-2
    maxmove      = s['maxmove'   ][m] * 1e-2
    maxpoints    = s['maxpoints' ][m]
    neighbours   = s['neighbours'][m]
    
    # Detect silhouette of key frame A
    if Ka is None or Ea is None or com_a is None:
        msg = 'Extracting silhouette for key {}'.format(a + 1)
        shoutout(msg=msg, thread=thread)
        result = silhouette(settings, a, K=Ka, X=X, Y=Y, recycle=True)
        fsa, Ka, Ea, com_a = result
        shoutout(img=fsa, thread=thread)
        if thread and thread.abort: return
    
    # Detect silhouette of key frame B
    if Kb is None or Eb is None or com_b is None:
        msg = 'Extracting silhouette for key {}'.format(b + 1)
        shoutout(msg, thread=thread)
        result = silhouette(settings, b, K=Kb, X=X, Y=Y, recycle=True)
        fsb, Kb, Eb, com_b = result
        shoutout(img=fsb, thread=thread)
        if thread and thread.abort: return
    
    # Catch corners
    if docorners:
        shoutout('Catching corners for key {}'.format(a + 1), thread=thread)
        fca, kp_a, dc_a = cornercatch(settings, a, K=Ka, recycle=True)
        shoutout(img=fca, thread=thread)
        if thread and thread.abort: return

        shoutout('Catching corners for key {}'.format(b + 1), thread=thread)
        fcb, kp_b, dc_b = cornercatch(settings, b, K=Kb, recycle=True)
        shoutout(img=fcb, thread=thread)
        if thread and thread.abort: return
    
    # Nothing can beat the need for shear speed
    if recycle and path.isfile(f1) \
               and path.isfile(f2):
        shoutout(img=f1, thread=thread)
        nodes = loadit(f2)
        return nodes, Ka, Kb, com_a, com_b
    
    # Convert detail zone units from promille to pixels
    # FIXME: Remove this after testing new traject detail setting
    #se       = settings['edge'  ]
    #detail   = 0.5 * se['detail'][a] * 1e-3 + \
    #           0.5 * se['detail'][b] * 1e-3
    detail = settings['traject']['detail'][m] * 1e-3
    simisize = max(int(np.ceil(max(Ka.shape[:2]) * detail)) + 1, 4)
    
    # Show the nitty gritty details
    print(timestamp() + 'Similim  = {} %'   .format(s['similim'][m]))
    print(timestamp() + 'Detail   = {0:.3f}'.format(detail))
    print(timestamp() + 'Simisize = {} px'  .format(simisize))

    # Start with the foundation;
    # The four screen corners and center of mass
    if dosilhouette:
        if Ea is None: Ea = loadit(path.join(folder_a, 'edgy.png'))
        if Eb is None: Eb = loadit(path.join(folder_b, 'edgy.png'))
        
        if com_a is None: com_a = loadit(path.join(folder_a, 'com.json'))
        if com_b is None: com_b = loadit(path.join(folder_b, 'com.json'))
        
        nodes0 = algo.seed(*Ka.shape[:2], com_a, com_b)
        if not spin: com_a['a'], com_b['a'] = 0, 0
        
    else:
        nodes0 = algo.seed(*Ka.shape[:2])
        com_a  = dict(x=0, y=0, r=0, a=0.0)
        com_b  = dict(x=0, y=0, r=0, a=0.0)

    # Use CoM as repellant for edge nodes
    base = nodes0[4:]
    if thread and thread.abort: return
    
    # Match corners
    if docorners:
        shoutout('Matching corners' + label, thread=thread)
        if Ka is None: Ka = algo.load_rgba(settings['keyframes'][a])
        if Kb is None: Kb = algo.load_rgba(settings['keyframes'][b])
        
        catcher = settings['edge']['cornercatcher']
        catch_a = path.join(folder_a, catcher[a].lower())
        catch_b = path.join(folder_b, catcher[b].lower())
        
        if kp_a is None: kp_a = loadit(catch_a + '.csv')
        if kp_b is None: kp_b = loadit(catch_b + '.csv')
        if dc_a is None: dc_a = loadit(catch_a + '.png')
        if dc_b is None: dc_b = loadit(catch_b + '.png')
        
        nodes1, simi1 = algo.matchpoint(Ka, Kb, kp_a, kp_b, dc_a, dc_b,
                                        simisize=simisize, similim=similim)
        
        base = np.row_stack((base, nodes1))
        if thread and thread.abort: return
    
    # Extract and match silhouette key points
    if dosilhouette:
        shoutout('Matching silhouettes' + label, thread=thread)
        spawnpoints = min(1000, *settings['traject']['maxpoints'])
        
        sp_a = algo.spawn(Ea, base[:, [0, 1]], spawnpoints, r_min=simisize)
        sp_b = algo.spawn(Eb, base[:, [2, 3]], spawnpoints, r_min=simisize)
        n_half = int(spawnpoints / 2)
        
        nodes2, simi2 = algo.proximatch(Ka, Kb, Ea, sp_a, sp_b, com_a, com_b,
                                        neighbours=neighbours, n=n_half,
                                        simisize=simisize, similim=similim)
        
        nodes3, simi3 = algo.proximatch(Kb, Ka, Eb, sp_b, sp_a, com_b, com_a,
                                        neighbours=neighbours, n=n_half,
                                        simisize=simisize, similim=similim)
        
        try:
            nodes4 = np.row_stack((nodes2, nodes3[:, [2, 3, 0, 1]]))
            simi4 = np.append(simi2, simi3)
        except IndexError:
            nodes4, simi4 = nodes2, simi2
        if thread and thread.abort: return
    
    # Combine the results. One big happy family!
    if dosilhouette and docorners:
        nodez = np.row_stack((nodes1, nodes4))
        simiz = np.append(simi1, simi4)
    elif dosilhouette:
        nodez, simiz = nodes4, simi4
    elif docorners:
        nodez, simiz = nodes1, simi1
    else:
        nodez = []
    
    # Combine duplicates
    if len(nodez):
        shoutout('Combining duplicate trajectories' + label, thread=thread)
        nodez, simiz = algo.gettogether(nodez, simiz, simisize)
    
    # Discard excessive moves
    if len(nodez):
        shoutout('Discarding excessive moves' + label, thread=thread)
        diago = np.ceil(np.sqrt(Ka.shape[0] ** 2 + \
                                Ka.shape[1] ** 2))
        
        lim   = int(maxmove * diago)        
        keep  = algo.notsofast(nodez, lim, com_a, com_b)
        nodez = nodez[keep]
        simiz = simiz[keep]
        
        # Are we doing sensible things in this joint?
        print(timestamp() + 'Max move = {} px'.format(lim))
        if thread and thread.abort: return
    
    # In case of crossing paths discard the longest trajectory
    if len(nodez):
        shoutout('Discarding crossing paths' + label, thread=thread)
        keep = np.zeros_like(nodez, dtype=bool)
        repeat = 1
        while np.any(~keep) and repeat <= 10:
            if thread and thread.abort: return
            keep    = algo.straightenup(nodez)
            nodez   = nodez[keep]
            simiz   = simiz[keep]
            repeat += 1
    
    # Cherry pick nodes with the highest similarity score
    if len(nodez) > maxpoints:
        shoutout('Cherry picking' + label, thread=thread)
        seq   = np.argsort(simiz)[::-1]
        nodez = nodez[seq][:maxpoints]
        simiz = simiz[seq][:maxpoints]
    
    # Pack it all together into one cozy bundle
    if len(nodes0) and len(nodez):
        nodes = np.row_stack((nodes0, nodez))
    elif len(nodes0):
        nodes = nodes0
    else:
        nodes = nodez
    
    # Save the harvest
    saveit(nodes, f2)
    if thread and thread.abort: return
    
    # Fade to gray baby
    shoutout('Making trajectory chart' + label, thread=thread)
    channel_a = settings['edge']['channel'][a]
    channel_b = settings['edge']['channel'][b]
    if channel_a.lower().startswith('a'): channel_a = 'lightness'
    if channel_b.lower().startswith('a'): channel_b = 'lightness'
    Ga = algo.desaturate(Ka, channel_a)
    Gb = algo.desaturate(Kb, channel_b)
    
    # Produce a tingly trajectory chart       
    fig = algo.big_figure('MuddyMorph - Trajectories', *Ga.shape)
    if arc:
        comp_a, comp_b = com_a, com_b
    else:
        comp_a, comp_b = None, None
    try:
        tweens = settings['motion']['inbetweens'][m]
    except IndexError:
        tweens = algo.most_frequent_value(settings['motion']['inbetweens'])
    algo.movemap(Ga, Gb, nodes, comp_a, comp_b, tweens=tweens)
    plt.axis('off')
    plt.savefig(f1, **chartopts)
    plt.close(fig)
    
    # Our work here is done
    stopwatch += time()
    msg = 'Trajectory extraction took ' + duration(stopwatch)
    shoutout(msg, f1, thread)
    return nodes, Ka, Kb, com_a, com_b
Esempio n. 5
0
#%% Compute CoM
print("A ", end="")
com_a = algo.commie(Sa)
print("B ", end="")
com_b = algo.commie(Sb)
if not dorotate:
    com_a['a'] = 0
    com_b['a'] = 0
base = np.array([[com_a['x'], com_a['y'], com_b['x'], com_b['y']]])

#%% Detect key points
target = int(np.floor(min([Ea.sum(), Eb.sum()]) * keyfill))
print("Selecting up to {} key points ... ".format(target), end="")

kp_a = algo.spawn(Ea, base[:, [0, 1]], target, r_min=simisize)
kp_b = algo.spawn(Eb, base[:, [2, 3]], target, r_min=simisize)
kp_at = algo.swirl(kp_a, com_a, com_b)
print("done")

#%% Match key points
print("Matching key points ... ", end="")
stopwatch = -time()
nodes_ab, simi_ab = algo.proximatch(Ka,
                                    Kb,
                                    kp_a,
                                    kp_b,
                                    com_a,
                                    com_b,
                                    neighbours=neighbours,
                                    simisize=simisize,
Esempio n. 6
0
print("Edge detection ... ", end="")
D, S, E = algo.edgy(K,
                    channel   = se['channel'  ],
                    threshold = se['threshold'],
                    blur      = se['blur'     ],
                    dolines   = se['dolines'  ])
print("done")

# CoM detection
com  = algo.commie(S)
base = algo.seed(com, com, *S.shape)[:, :2]

# Pick edge points
print("Picking {} edge points ... ".format(n), end="")
stopwatch  = - time()
kp         = algo.spawn(E, base, n)
stopwatch += time()
print("done in {0:.0f} ms".format(stopwatch * 1000.))


##########
# Review #
##########

print("Plotting result ... ", end="")
plt.close('all')
fig = plt.figure(figsize=(14, 9))

# Show silhouette
plt.subplot(1, 2, 1)
algo.edgeplot(D, S, E)