Source code for TimeTrack
# CellTracking.py
# By MW, Jun 2013
# GPLv3+
#
# Class managing a timetrack, an abstract object handling up timepoints
import logging, cv2, imp, numpy
[docs]class TimeTrack :
def __init__(self) :
self.times = []
self.pols = []
[docs] def get_bounds(self) :
"""Returns a tuple containing the first frame and the last frame
of the polygon, as defined by the set_begin and the set_end function
"""
print 'not implemented, please have a look at Cell.get_bounds'
[docs] def set_begin(self, t) :
"""Set the beginning of the track. It removes all timepoint before
the given time"""
if len(self.times)==1 :
self.times[0] = t
while (self.times[0] < t) and (len(self.times)>1) :
self.times.pop(0)
self.pols.pop(0)
[docs] def set_end(self, t) :
"""Set the end of the track. It removes all timepoint after
the given time"""
if len(self.times)==1 :
self.times[0] = t
while (self.times[-1] > t) and (len(self.times)>1) :
self.times.pop(-1)
self.pols.pop(-1)
[docs] def add_timepoint(self, time, pol) :
"""Add a polygon at a given time"""
ex = self.get_index(time) # Check if the timepoint exists and get its index
if ex[0] : # Edit it
self.pols[ex[1]] = pol
else :# Create it
self.times.insert(ex[1], time)
self.pols.insert(ex[1], pol)
[docs] def del_timepoint(self, time) :
ex = self.get_index(time)
if not ex[0] :
logging.error('The timepoint %s cannot be removed because it does not exist.', time)
else :
self.times.pop(ex[1])
self.pols.pop(ex[1])
[docs] def get_polygon(self, time) :
ex = self.get_index(time)
if ex[0] :
return self.pols[ex[1]]
elif self.times != [] :
if ex[1] == len(self.times) :
return self.pols[-1]
elif ex[1] == 0 :
return self.pols[0]
else : # We have to interpolate the polygon
t1 = self.times[ex[1]-1]
t2 = self.times[ex[1]]
pol1 = self.pols[ex[1]-1]
pol2 = self.pols[ex[1]]
pol = []
for i in range(len(pol1)) :
point = []
for coord in range(len(pol1[0])) : # Iterate over x and y
#print pol1[i][coord]
#print (pol2[i][coord]-pol1[i][coord])
#print (t2-time)/(t2-float(t1))
point.append(pol1[i][coord]+
(pol2[i][coord]-pol1[i][coord])*
(time-t1)/(t2-float(t1)) )
pol.append(tuple(point))
return pol
else :
logging.error('No timepoint instanciated, cannot interpolate.')
[docs] def add_point(self, time, pos, point) :
"""Function that add a point in the polygon"""
ex = self.get_index(time)
if not ex[0] :
logging.error("Cannot add a point to a frame that does not exist. Please create it before")
else :
for i in range(len(self.times)) :
t = self.times[i]
if t != time :
pol = self.pols[i]
if pos == 0 :
p1 = pol[-1]
p2 = pol[0]
else :
p1 = pol[pos-1]
p2 = pol[pos]
p = []
for coord in range(len(p1)) :
p.append((p2[coord]-p1[coord])*0.5)
self.pols[i].insert(pos, p)
else :
self.pols[i].insert(pos, tuple(point))
[docs] def get_index(self, time) :
if time in self.times :
return (True, self.times.index(time))
elif self.times == [] :
return (False, 0)
else :
i = 0
while (i<len(self.times)) and (self.times[i] < time) :
i+=1
return (False, i)
[docs] def get_center(self, t) :
p = self.get_polygon(t)
return numpy.array(p).mean(axis=0)
[docs] def move_point(self, selected, coord, t) :
coord = numpy.array(coord)
pol = numpy.array(self.get_polygon(t))
oldpol = pol.copy()
if selected == 'center' :
center = numpy.array(self.get_center(t)) # getting point
tr = coord-center
pol += tr
#print "translating cell"
elif type(selected) == int :
pol[selected] = coord
#print "moving a time point"
else :
return None
self.add_timepoint(t, pol)
return pol-oldpol
[docs] def translate(self, v, t) :
pol = numpy.array(self.get_polygon(t))
self.add_timepoint(t, pol+v)
[docs] def get_save_dict(self) :
dic = {}
dic['times'] = {'descr' : 'A list conaining the times of the key frames', 'value' : self.times}
dic['pols'] = {'descr' : 'A list conaining the polygons for each key frame', 'value' : self.pols}
return {'descr' : 'A timetrack object, usually used to save a moving polygon', 'value' : dic}
[docs] def load_save_dict(self, dic) :
self.times = dic['value']['times']['value']
self.pols = dic['value']['pols']['value']