Source code for Cell_gtk

# CellTracking.py
# By MW, Jun 2013
# GPLv3+
#
# Class managing the display of a cell instance
import logging, cv2, numpy, gtk

[docs]class GtkCell : """A generic class for handling cell creation (get polygon as successive clicks)""" def __init__(self, cells, state) : self.state = state self.cells = cells self.eps = 7 # A distance in pixels self.points = [] self.closed = False self.type = 'pol' self.cell = None self.panel = None self.selected = False self.r_panel = None self.radiobutton = None # The button on the cell l_panel self.radiobutton_none = None # The widget to select to uselect all self.visible = True self.selected_handle = None
[docs] def get_selected(self) : return self.selected
[docs] def set_r_panel(self, panel) : self.r_panel = panel
[docs] def set_selected(self, sel) : logging.debug("cell %s %s", self.get_name(), ['unselected', 'selected'][sel]) self.selected = sel self.radiobutton.set_active(sel) self.radiobutton.set_sensitive(self.visible) if not self.visible and sel: self.radiobutton_none.set_active(True)
[docs] def get_name(self) : """Return the name of the cell""" if self.closed : return self.cell.get_name() else : logging.warning("Trying to get the name of a temporary cell") return "TMP cell"
[docs] def rb_toggled(self, active) : self.selected = active if active : if self.r_panel.get_child() != None : self.r_panel.remove(self.r_panel.get_child()) l = gtk.Label('testbabou!'+self.get_name()) l.show() self.r_panel.add_with_viewport(l)
[docs] def get_panel(self, rb, rb_none) : """Return the panel to manage a cell rb is the radiobutton instance determining which cell is selected""" # Create expander and header self.panel = gtk.Expander(label="Cell: "+self.get_name()) self.radiobutton = rb self.radiobutton_none = rb header_cb = gtk.CheckButton("Show") header_cb.set_active(self.visible) header_cb.connect('clicked', self.show_evt) box = gtk.HBox() box.pack_start(header_cb, fill=False, expand=False) box.pack_start(gtk.VSeparator(), expand=False, fill=False) box.pack_start(self.panel, fill=False, expand=False) box.show_all() # Fill panel l = gtk.Label('Not implemented yer!') l.show() self.panel.add(l) #self.panel.set_label_widget(header) return box
[docs] def show_evt(self, evt) : self.visible = evt.get_active() self.set_selected(evt.get_active())
[docs] def unclick(self) : """Function called when the user click is released""" self.selected_handle = None
[docs] def click(self, tup) : """Function that receive a click from the viewer. This function returns True if the click lies inside the cell (core or reference polygon) In theory, the coordinates already have been converted""" if self.visible : i = self.state.get_subclass('player').get_current_index() in_c = self.cell.is_point_in_cell(tup, i) in_r = self.cell.is_point_in_ref(tup, i) if self.selected_handle == None : self.selected_handle = self.cell.is_point_on_cell_handle(tup, i) if self.selected_handle == None : self.selected_handle = self.cell.is_point_on_ref_handle(tup, i) if in_c or in_r or (self.selected_handle != None): # Select cell logging.debug("%s selected", str(self.get_name())) # update clickable panel ##self.radiobutton.set_active(True) ##self.selected = True self.set_selected(True) return True else : #unselect cell logging.debug("%s unselected", str(self.get_name())) self.set_selected(False) ##self.selected = False ##self.radiobutton.set_active(False) return False return False
[docs] def move(self, tup) : """Function called when the cell is selected and the user tries to drag'n'drop it""" #print 'moving point %s' % self.selected_handle # Get selected feature # Update according to the selected feature
[docs] def get_type(self) : """Return the cell type ('pol' for instance)""" return self.type
[docs] def add_point(self, tup) : if not self.closed : if (len(self.points)>=1) and (self.dist(self.points[0], tup)<self.eps) : self.close() # Close the polygon return False # erase tmp_cell else : self.points.append(tup) print "point added: %s" % str(tup) else : logging.warning("Trying to add a point to a closed polygon")
[docs] def reset_polygon(self) : self.points = [] self.state.get_subclass('player').set_current_frame(None) # updating display
[docs] def close(self) : """Function that close the polygon and create a new cell instance instead""" n = self.cells.get_name() # Get an unused name self.cell = self.cells.new_cell(str(n)) i = self.state.get_subclass('player').get_current_index() self.cell.reset_polygon(self.points, i) self.closed = True
[docs] def dist(self, p1, p2) : s = 0 for i in range(len(p1)) : s += (p1[i]-p2[i])**2 return s**0.5
[docs] def draw_polygon(self, im) : """Draw the polygon on the image :param im: the image to draw on. :param type: a numpy matrix (x*y*3) :returns: numpy matrix -- the output image""" if self.visible : if self.closed : i = self.state.get_subclass('player').get_current_index() points = self.cell.cell_pol.get_polygon(i) if self.selected : color = (255,0,0) else : color = (0,0,255) else : points = self.points color = (255,0,0) tuplist = points if len(tuplist)==1 : # Draw first point if necessary p = tuplist[0] cv2.circle(im, (int(p[0]), int(p[1])), 3, color=color) # Draw polygon #if self.points != [] : # Not sure whether this is required... if points != [] : cv2.polylines(im, [numpy.array(tuplist, dtype=numpy.int32)], self.closed, color=color) if self.closed : center = numpy.array(tuplist).mean(axis=0) cv2.circle(im,tuple(numpy.int_(center)), 5, color=color) for p in tuplist : cv2.circle(im, (int(p[0]), int(p[1])), 3, color=color) coord = (int(tuplist[0][0]), int(tuplist[0][1])-3) cv2.putText(im, self.get_name(), coord, cv2.FONT_HERSHEY_PLAIN, fontScale=1,color=color) return im
[docs]class GtkRect(GtkCell) : """A generic class to handle polygons as untilted rectangles""" def __init__(self, cells, state) : self.state = state TmpCell.__init__(self, cells)
[docs]class GtkRect_ct(GtkRect) : def __init__(self, cells, state) : self.state = state TmpCell.__init__(self, cells)
[docs]class GtkRect_tp(GtkRect) : def __init__(self, cells, state) : self.state = state TmpCell.__init__(self, cells)