Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 215 additions & 0 deletions ivctrack/AniFrame.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
# -*- coding: utf-8 -*-
'''This file implements a frame allowing to verify the tracking through an animation (which can be saved).
'''
__author__ = ' De Almeida Luis <ldealmei@ulb.ac.be>'

#------generic imports------
from Tkinter import *
import tkFileDialog

#------specific imports------
import matplotlib
matplotlib.use('Tkagg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib.animation as anim

#------ivctrack toolbox imports------
from reader import ZipSource,Reader
from hdf5_read import get_hdf5_data

class AniFrame(Frame):
"""Frame displaying the results of the tracking as a video, and allowing to save it. Will NOT work if FFmpeg is not installed."""

def __init__(self,win,zip_filename):
Frame.__init__(self,win)

self.feat=[]
self.data = []

#----------------------------------------------------GUI IMPLEMENTATION-----------------------------------------

self.file_var=StringVar()
self.file_var.set('HDF5 File: ')
self.file_lbl=Label(self,textvariable=self.file_var)
self.file_lbl.grid(row=0,column=2,columnspan=2)

self.file_browse_button=Button(self,text='Browse',command=self.ask_open_and_load_file)
self.file_browse_button.grid(row=0,column=4)

self.soma_var=BooleanVar()
self.soma_check=Checkbutton(self,text='Soma',variable=self.soma_var)
self.soma_check.grid(column=0,row=1,columnspan=2)

self.halo_var=BooleanVar()
self.halo_check=Checkbutton(self,text='Halo',variable=self.halo_var)
self.halo_check.grid(column=0,row=2,columnspan=2)

self.trajectory_var=BooleanVar()
self.trajectory_check=Checkbutton(self,text='Trajectory',variable=self.trajectory_var)
self.trajectory_check.grid(column=0,row=3,columnspan=2)

self.play_button = Button(master=self, text='Preview',command=lambda:(self.play()))

self.save_button=Button(self,text='Save as..',command=lambda :(self.save()))

self.dpi_lbl=Label(self,text='Resolution (DPI)')
self.var_dpi=IntVar()
self.var_dpi.set(200)
self.dpi_entry=Entry(self,textvariable=self.var_dpi)

#-----Configuration of the tracking canvas------
self.f=plt.figure()
self.a=self.f.add_subplot(111)

self.frame_text=self.a.text(10,20,'')

self.canvas = FigureCanvasTkAgg(self.f, master=self)
self.canvas.show()
self.canvas.get_tk_widget().grid(row=1,column=2,rowspan=3,columnspan=3)

#------------------------------------------------------END-------------------------------------------------------------


#------import of the zip file & update of the canvas------
self.datazip_filename = zip_filename

self.reader = Reader(ZipSource(self.datazip_filename))
self.bg=self.reader.getframe()

self.im = self.a.imshow(self.bg,cmap=cm.gray)

self.a.set_xlim(0,len(self.bg[0,:]))
self.a.set_ylim(len(self.bg[:,0]),0)

#------MP4 writer------
self.writer=anim.writers['ffmpeg']
self.writer=self.writer(fps=5)


def ask_open_and_load_file(self):
self.file_opt={}
self.file_opt['filetypes'] = [('HDF5 file','.hdf5')]
self.file_opt['defaultextension'] ='.hdf5'
self.file_opt['title'] = 'Select a HDF5 file'

self.hdf5_filename=tkFileDialog.askopenfilename(**self.file_opt)
self.file_var.set('HDF5 File: {}'.format(self.hdf5_filename))

self.feat,self.data=get_hdf5_data(self.hdf5_filename,fields=['center','halo','soma'])
self.halo=[]
self.soma=[]
self.trajectory=[]

for k in range(len(self.data)):
self.halo.append(self.a.plot([],[],'o'))
self.soma.append(self.a.plot([],[]))
self.trajectory.append(self.a.plot([],[]))

self.play_button.grid(row=4,column=1)
self.save_button.grid(row=4,column=0)
self.dpi_lbl.grid(column=2,row=4)
self.dpi_entry.grid(column=3,row=4)


def play(self):

self.cell_ani = anim.FuncAnimation(fig=self.f, func=self.update_img,init_func=self.init_im,frames=self.reader.N(),blit=False)
self.canvas.show()
self.play_button.grid_forget()

def save(self):
"""Exports the animation to a MP4 file.
"""
self.file_opt={}
self.file_opt['filetypes'] = [('MP4 files','.mp4')]
self.file_opt['defaultextension'] ='.mp4'
self.file_opt['title'] = 'Save sequence as..'

soma=self.soma_var.get()
halo=self.halo_var.get()
trajectory=self.trajectory_var.get()

self.mp4_filename=tkFileDialog.asksaveasfilename(**self.file_opt)

with self.writer.saving(self.f,self.mp4_filename,self.var_dpi.get()):
self.reader.rewind()
for i in range(self.reader.N()):
print "Grabing frame ",i

self.bg=self.reader.getframe()
self.im.set_data(self.bg)
try:
self.reader.next()
except IndexError:
pass
if halo:
self.plot_halo(i)
if soma:
self.plot_soma(i)
if trajectory:
self.plot_trajectory(i)

self.frame_text.set_text(i)

self.writer.grab_frame()
print "Video correctly saved as ", self.mp4_filename


def update_img(self,frame):

self.reader.moveto(frame)
self.bg=self.reader.getframe()

self.im.set_data(self.bg)

if self.halo_var.get():
self.plot_halo(frame)
elif not self.halo_var.get():
for k in range(len(self.data)):
self.halo[k][0].set_data([],[])

if self.soma_var.get():
self.plot_soma(frame)
elif not self.soma_var.get():
for k in range(len(self.data)):
self.soma[k][0].set_data([],[])

if self.trajectory_var.get():
self.plot_trajectory(frame)
elif not self.trajectory_var.get():
for k in range(len(self.data)):
self.trajectory[k][0].set_data([],[])

self.frame_text.set_text(frame)

def init_im(self):
pass

def plot_halo(self,i):
k=0
for d in self.data:
t=d['halo']
x=t[i,:,0]
y=t[i,:,1]
self.halo[k][0].set_data(x,y)
k+=1

def plot_soma(self,i):
k=0
for d in self.data:
t=d['soma']
x=t[i,:,0]
y=t[i,:,1]
self.soma[k][0].set_data(x,y)
k+=1

def plot_trajectory(self,i):
k=0
for d in self.data:
t=d['center']
x=t[0:i,0]
y=t[0:i,1]
self.trajectory[k][0].set_data(x,y)
k+=1
170 changes: 170 additions & 0 deletions ivctrack/MainWindow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# -*- coding: utf-8 -*-
'''This file implements the menu frame of the GUI for the ivctrack module
'''
__author__ = ' De Almeida Luis <ldealmei@ulb.ac.be>'

#------generic imports------
from Tkinter import *
import tkFileDialog

#-------local imports------
from TrackingFrame import TrackingFrame
from PlotFrame import PlotFrame
from AniFrame import AniFrame
from MeasFrameV3 import MeasFrameV3



class MainFrame(Frame):

"""Main menu frame : The user can either start a new tracking or view results from previous trackings
The .zip file which contains the image sequences is linked to the menu window and can only be modified from there"""
def __init__(self,win):
Frame.__init__(self,win,width=700,height=700)
self.pack()

self.track_frame=None
self.plot_frame=None
self.meas_frame=None
self.ani_frame=None

self.menu_buttons=[]

self.datazip_filename=""

self.file_opt={}
self.file_opt['filetypes'] = [('ZIP file','.zip')]
self.file_opt['defaultextension'] ='.zip'
self.file_opt['title'] = 'Select a zipped sequence file'


#----------------------------------------------------GUI IMPLEMENTATION-----------------------------------------

self.track_button=Button(self,text='Start Tracking',command=lambda : self.track())
self.track_button.pack(fill='both')
self.menu_buttons.append(self.track_button)

self.plot_button=Button(self,text='Plot Results',command=lambda : self.plot())
self.plot_button.pack(fill='both')
self.menu_buttons.append(self.plot_button)

self.meas_button=Button(self,text='Measurements',command=lambda : self.measurements())
self.meas_button.pack(fill='both')
self.menu_buttons.append(self.meas_button)

self.ani_button=Button(self,text='Player',command=lambda : self.play())
self.ani_button.pack(fill='both')
self.menu_buttons.append(self.ani_button)

self.zip_var=StringVar()
self.change_zip_button=Button(self,textvariable=self.zip_var,command= lambda : self.change_zip())
self.menu_buttons.append(self.change_zip_button)

self.quit_button=Button(self,text='Quit',command=win.quit)
self.quit_button.pack(fill='both')
self.menu_buttons.append(self.quit_button)

self.back_button=Button(self,text='Back',command = lambda : self.back())

#------------------------------------------------------END-------------------------------------------------------------


def back(self):
"""Return to the menu window. """
try :
self.track_frame.pack_forget()
self.track_frame=None
except:
pass
try :
self.plot_frame.pack_forget()
self.plot_frame=None
except:
pass
try :
self.meas_frame.pack_forget()
self.meas_frame=None
except:
pass
try:
self.ani_frame.pack_forget()
self.ani_frame=None
except:
pass

self.back_button.pack_forget()
for button in self.menu_buttons:
button.pack(fill='both')

def track(self):
"""Method that transits from the menu to the tracking frame """
if self.datazip_filename=="":
self.change_zip()

self.track_frame=TrackingFrame(win,self.datazip_filename)

self.track_frame.pack()

for button in self.menu_buttons:
button.pack_forget()

self.back_button.pack(side='bottom')

def plot(self):
"""Method that transits from the menu to the plotting frame """

if self.datazip_filename=="":
self.change_zip()

self.plot_frame=PlotFrame(win,self.datazip_filename)

self.plot_frame.pack()

for button in self.menu_buttons:
button.pack_forget()

self.back_button.pack(side='bottom')

def measurements(self):
"""Method that transits from the menu to the frame that displays multiple measures"""

if self.datazip_filename=="":
self.change_zip()
self.meas_frame=MeasFrameV3(win,self.datazip_filename)

self.meas_frame.pack()

for button in self.menu_buttons:
button.pack_forget()

self.back_button.pack(side='bottom')

def play(self):
"""Method that transits from the menu to the frame that plays the tracking and allows to save it to .mp4"""
if self.datazip_filename=="":
self.change_zip()

self.ani_frame=AniFrame(win,self.datazip_filename)

self.ani_frame.pack()

for button in self.menu_buttons:
button.pack_forget()

self.back_button.pack(side='bottom')

def change_zip(self):
"""Method that allows the user to change the current sequence ZIP file """
self.datazip_filename=tkFileDialog.askopenfilename(**self.file_opt)
try:
self.zip_var.set("Change Zip File ({})".format(self.datazip_filename.rsplit('/')[-1]))
except AttributeError:
pass


if __name__== '__main__':

win=Tk()
win.wm_title('IVCTrack GUI')
root=MainFrame(win)
root.mainloop()
Loading