Get Tracks

This example will explain how to retrieve tracks from a existing clickpoints database and use them for evaluation. The example database contains 68 images with track markers of 12 tracks.

[1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import clickpoints

# load the example data
clickpoints.loadExample("magnetic_tweezer")

Get all Tracks

We query all the tracks found in the database and iterate over them. For each track we get the points as an Nx2 array.

Be aware that this method does not handle well tracks with missing data points.

[2]:
# open database
with clickpoints.DataFile("track.cdb") as db:
    # get all tracks
    tracks = db.getTracks()

    # iterate over all tracks
    for track in tracks:
        print(track.type.name, track.points.shape)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)
tracks (68, 2)

Get Complete Track Array

We can also receive all the tracks of the database in one array. This is usually quicker for large databases than querying each track separately. The resulting array is (Number of tracks)x(Number of images)x2. If a track does not have a marker in one images, np.nan values are filled into the array.

[3]:
# open database
with clickpoints.DataFile("track.cdb") as db:
    data = db.getTracksNanPadded()
    print(data.shape)
(12, 68, 2)

Plot Track Displacement

Then we get all the tracks with getTracks(). In this example without any filtering, as we just want all the tracks available. We can iterate ofer the received object and access the Track objects. From them we can get the points and calculate their displacements with respect to their starting points.

[4]:
# open database
with clickpoints.DataFile("track.cdb") as db:
    # get all tracks
    tracks = db.getTracks()

    # iterate over all tracks
    for track in tracks:
        # get the points
        points = track.points
        # calculate the distance to the first point
        distance = np.linalg.norm(points[:, :] - points[0, :], axis=1)
        # plot the displacement
        plt.plot(track.frames, distance, "-o")

# label the axes
plt.xlabel("# frame")
plt.ylabel("displacement (pixel)");
../_images/examples_example_tracks_11_0.png

We can do the same with the complete track array, which is especially for large databases significantly faster than querying each track separately.

[5]:
# open database
with clickpoints.DataFile("track.cdb") as db:
    # get all tracks (tracks x images x 2)
    points = db.getTracksNanPadded()

# get the distance to the first point of each track
distance = np.linalg.norm(points[:, :, :] - points[:, 0:1, :], axis=2)

# plot the distances
plt.plot(distance.T, "-o")

# label the axes
plt.xlabel("# frame")
plt.ylabel("displacement (pixel)");
../_images/examples_example_tracks_13_0.png

Plot Track Trajectories

We can now use getImage() to get the first image of the sequence and load the data from this file. This can now be displayed with matplotlib. To draw the tracks, we itarate over the track list again and plot all the points, as well, as the starting point of the track for a visualisation of the tracks.

[6]:
# open database
with clickpoints.DataFile("track.cdb") as db:
    # get the first image
    im_entry = db.getImage(0)

    # we load the pixel data from the Image database entry
    im_pixel = im_entry.data

    # plot the image
    plt.imshow(im_pixel, cmap="gray")

    # iterate over all tracks
    for track in tracks:
        # get the points
        points = track.points
        # plot the beginning of the track
        cross, = plt.plot(points[0, 0], points[0, 1], '+', ms=14, mew=1)
        # plot the track with the same color
        plt.plot(points[:, 0], points[:, 1], lw=3, color=cross.get_color())
        # plot the track id with a little offset and the same color
        plt.text(points[0, 0]+5, points[0, 1]-5, "#%d" % track.id, color=cross.get_color(), fontsize=15)

# zoom into the image
plt.xlim(600, 800)
plt.ylim(400, 200);
../_images/examples_example_tracks_16_0.png

Creating Tracks

Here, we create a new database (open in write mode “w”, which creates a new database) and add all images we find in the current folder to it (setImage()).

To add tracks to the image, we first need to define a marker_type (setMarkerType()). Then we create track objects for all the tracks we want to create (setTrack()). For add track markers for each track for each image (setMarkers()). In this case for demonstration purposes, we just create random walk tracks.

[7]:
from pathlib import Path

# Fix the seed
np.random.seed(0)

# we want 10 tracks
N = 10

# open database
with clickpoints.DataFile("tracking.cdb", "w") as db:

    # add a marker type we want to use for adding track markers
    # it has the name "trajectories" and the color "#FF0000", e.g. red
    # make it a type for tracks markers (TYPE_Track)
    track_type = db.setMarkerType(name="trajectories", color="#FF0000", mode=db.TYPE_Track)

    # create the new tracks with the type
    # (Note, instead of giving the track type, we could also just provide its name "trajectories"
    tracks = []
    for i in range(N):
        track = db.setTrack(type=track_type)
        tracks.append(track)

    # Create initial positions
    points = np.random.rand(N, 2)


    # find all images in the folder and iterate over them
    for image_filename in Path(".").glob("frame*.jpg"):

        # add the image to the database
        im = db.setImage(image_filename)

        # Move the positions (in this case we just create random walk tracks)
        points += np.random.rand(N, 2)-0.5

        # Save the new positions
        db.setMarkers(image=im, x=points[:, 0], y=points[:, 1], track=tracks)