Exemple #1
0
class click_yrange:
   '''An interactive yrange selector.  Given an axis and a starting
   y0 location, draw a full-width rectange that follows the mouise.
   Similar to click_window, but more appropriate for selecting out
   a y-range.'''

   def __init__(self, ax, y0):
      self.ax = ax
      self.y0 = y0
      x0,x1 = ax.get_xbound()
      self.rect = Rectangle((x0,y0), width=(x1-x0), height=0, alpha=0.1)
      ax.add_artist(self.rect)

   def connect(self):
      self.cidmotion = self.rect.figure.canvas.mpl_connect(
            'motion_notify_event', self.on_motion)

   def on_motion(self, event):
      # Have we left the axes?
      if event.inaxes != self.rect.axes:  return

      self.rect.set_height(event.ydata - self.y0)
      self.ax.figure.canvas.draw()

   def close(self):
      self.rect.figure.canvas.mpl_disconnect(self.cidmotion)
      self.rect.remove()
      self.ax.figure.canvas.draw()
      return(self.y0, self.rect.get_y()+self.rect.get_height())
Exemple #2
0
	def draw_rectangle(self, lower, upper, node):
		r = Rectangle(lower, upper[0] - lower[0], upper[1]-lower[1], 
			edgecolor='k',
			facecolor = (0,0,0))
		self.ax.add_patch(r)
		if node.is_leaf():
			rx, ry = r.get_xy()
			cx = rx + r.get_width()/2.0
			cy = ry + r.get_height()/2.0
			r.set_facecolor( node.get_colour())
			self.ax.annotate(node.get_weight(), (cx, cy), color=(0,0,0), fontsize = 10, ha='center', va='center')
			print node.name, rx, ry, cx, cy
Exemple #3
0
    def draw_rectangle(self, lower, upper, node):
        r = Rectangle( lower, upper[0]-lower[0], upper[1] - lower[1],
                   edgecolor='k',
                   facecolor= node.get_color(),
                   label=node.name)
        self.ax.add_patch(r)

        rx, ry = r.get_xy()
        rw = r.get_width()
        rh = r.get_height()
        cx = rx + rw/2.0
        cy = ry + rh/2.0
        if isinstance(node, PathNode):
            t = node.name
            if rw * 3 < rh:
                t += ", "
            else:
                t += "\n"
            t += str(node.size) + ", " + node.stype
            c='w'
            if rw < rh:
                o = "vertical"
            else:
                o = "horizontal"

        else:
            t = node.name
            if node.isfile:
                c='k'
                o = 45
            else:
                return
        self.ax.annotate(
                t,
                (cx,cy),
                color=c,
                weight='bold', ha='center', va='center',
                rotation=o
                )
Exemple #4
0
class CustomToolbar(NavToolbar):

    toolitems = NavToolbar.toolitems + (
        (None, None, None, None),
        ("ROI", "Select ROI", "selection", "_on_custom_select"),
    )

    def __init__(self, plotCanvas):
        # create the default toolbar
        NavToolbar.__init__(self, plotCanvas)
        self.selector = RectSelector(
            self.canvas.figure.axes[0], self.onSelect, button=[1, 3], minspanx=5, minspany=5  # don't use middle button
        )
        self.selector.set_active(True)
        self.ax = self.canvas.figure.axes[0]
        self.roi = None
        self.fixedSize = False
        if wx.Platform == "__WXMAC__":
            self.to_draw = Rectangle(
                (0, 0), 0, 1, visible=False, facecolor="yellow", edgecolor="black", alpha=0.5, fill=True
            )
            self.ax.add_patch(self.to_draw)
            self.background = None

    def _init_toolbar(self):
        self._parent = self.canvas.GetParent()

        self.wx_ids = {}
        for text, tooltip_text, image_file, callback in self.toolitems:
            if text is None:
                self.AddSeparator()
                continue
            self.wx_ids[text] = wx.NewId()
            try:
                bitmap = _load_bitmap(image_file + ".png")
            except IOError:
                bitmap = wx.Bitmap(image_file + ".png")
            if text in ["Pan", "Zoom", "ROI"]:
                self.AddCheckTool(self.wx_ids[text], bitmap, shortHelp=text, longHelp=tooltip_text)
            else:
                self.AddSimpleTool(self.wx_ids[text], bitmap, text, tooltip_text)
            bind(self, wx.EVT_TOOL, getattr(self, callback), id=self.wx_ids[text])

        self.ToggleTool(self.wx_ids["ROI"], True)
        self.Realize()

    def _set_markers(self):
        self.canvas.parentFrame.set_markers()

    def _update_view(self):
        NavToolbar._update_view(self)
        self._set_markers()
        # MacOS needs a forced draw to update plot
        if wx.Platform == "__WXMAC__":
            self.canvas.draw()

    def draw(self):
        self._set_markers()
        NavToolbar.draw(self)
        # MacOS needs a forced draw to update plot
        if wx.Platform == "__WXMAC__":
            self.canvas.draw()

    def zoom(self, ev):
        if wx.Platform == "__WXMAC__":
            self.ToggleTool(self.wx_ids["Zoom"], self.GetToolState(self.wx_ids["Zoom"]))
        NavToolbar.zoom(self, ev)

    def pan(self, ev):
        if wx.Platform == "__WXMAC__":
            self.ToggleTool(self.wx_ids["Pan"], self.GetToolState(self.wx_ids["Pan"]))
        NavToolbar.pan(self, ev)

    def press_zoom(self, ev):
        if wx.Platform == "__WXMAC__":
            self.update_background()
            self.to_draw.set_visible(True)
        NavToolbar.press_zoom(self, ev)

    def release_zoom(self, ev):
        if wx.Platform == "__WXMAC__":
            self.to_draw.set_visible(False)
        NavToolbar.release_zoom(self, ev)

    def draw_rubberband(self, event, x0, y0, x1, y1):
        # XOR does not work on MacOS ...
        if wx.Platform != "__WXMAC__":
            NavToolbar.draw_rubberband(self, event, x0, y0, x1, y1)
        else:
            if self.background is not None:
                self.canvas.restore_region(self.background)
            c0, c1 = self.ax.transData.inverted().transform([[x0, y0], [x1, y1]])
            l, b = c0
            r, t = c1
            self.to_draw.set_bounds(l, b, r - l, t - b)
            self.ax.draw_artist(self.to_draw)
            self.canvas.blit(self.ax.bbox)

    def update_background(self):
        """force an update of the background"""
        self.background = self.canvas.copy_from_bbox(self.ax.bbox)

    # Turn on selection
    # TODO: Proper handling of states, actual functionality.
    def _on_custom_select(self, evt):
        #        for id in ['Zoom','Pan']:
        #            self.ToggleTool(self.wx_ids[id], False)
        #        print('Select ROI: %s' % (self.GetToolState(self.wx_ids['ROI'])))
        #        self.ToggleTool(self.wx_ids['ROI'],
        #                self.GetToolState(self.wx_ids['ROI']) )
        self.toggle_selector()

    #        print('Select ROI: %s' % (self.GetToolState(self.wx_ids['ROI'])))

    def onSelect(self, eclick, erelease):
        "eclick and erelease are matplotlib events at press and release"
        #        print(' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata))
        #        print(' endposition   : (%f, %f)' % (erelease.xdata, erelease.ydata))
        #        print(' used button   : ', eclick.button)
        self.updateROI(
            min(eclick.xdata, erelease.xdata),
            min(eclick.ydata, erelease.ydata),
            abs(eclick.xdata - erelease.xdata),
            abs(eclick.ydata - erelease.ydata),
        )
        if self.canvas.parentFrame.fixedNumberCB.IsChecked():
            # We are working in the fixed-number mode
            # We need to find new roi for this center point
            # The handler will call the update ROI function for us.
            self.canvas.parentFrame.handleROIforN()

    def updateROI(self, x, y, w, h):
        if self.roi is None:
            # print('upd ROI:', x, y, w, h)
            self.roi = Rectangle((x, y), w, h, ls="solid", lw=2, color="r", fill=False, zorder=5)
            self.canvas.figure.axes[0].add_patch(self.roi)
        else:
            self.roi.set_bounds(x, y, w, h)
        self.updateCanvas()

    def toggle_selector(self):
        self.selector.set_active(not self.selector.active)

    def onFixedSize(self, ev):
        self.fixedSize = ev.IsChecked()
        self.updateCanvas()

    def onWidthChange(self, ev):
        if self.roi:
            x = self.roi.get_x()
            w = self.roi.get_width()
            nw = ev.GetValue()
            dw = {"C": (w - nw) / 2, "L": 0, "R": w - nw}[self.canvas.parentFrame.anchorRB.GetStringSelection()[0]]
            self.roi.set_x(x + dw)
            self.roi.set_width(nw)
            self.updateCanvas()

    def onHeightChange(self, ev):
        if self.roi:
            y = self.roi.get_y()
            h = self.roi.get_height()
            nh = ev.GetValue()
            dh = {"C": (h - nh) / 2, "B": 0, "T": h - nh}[self.canvas.parentFrame.anchorRB.GetStringSelection()[-1]]
            self.roi.set_y(y + dh)
            self.roi.set_height(nh)
            self.updateCanvas()

    def updateCanvas(self, redraw=True):
        if self.roi:
            self.canvas.parentFrame.showROI(
                self.roi.get_x(), self.roi.get_y(), self.roi.get_width(), self.roi.get_height()
            )
            self.canvas.parentFrame.setWH(self.roi.get_width(), self.roi.get_height())
            if self.fixedSize:
                self.selector.setSize(self.roi.get_width(), self.roi.get_height())
            else:
                self.selector.setSize()
        if redraw:
            self.draw()
Exemple #5
0
def handle_event():
    global command
    global command_meta
    global main_pic
    global history
    global patch
    global patches
    global click_handlers
    global G


    if command=="horizontal_line" or command=="vertical_line":
        h,w = main_pic.shape[:2]
        if patch is not None:
            w1,h1 = patch.get_xy()
            if command=="horizontal_line":
                line = Line(0,int(h1),w,int(h1), int(patch.get_height()), magenta)
            else:
                line = Line(int(w1),0,int(w1),h, int(patch.get_width()), magenta)
            main_pic = draw_line_on_picture(main_pic, line)
            patch=None
        else:
            if command=="horizontal_line":
                patch = Rectangle((0,0), w, 1, edgecolor='magenta', alpha=1)
            else:
                patch = Rectangle((0,0), 1, h, edgecolor='magenta', alpha=1)

    if command=="needle" or command=="angle_needle":
        G["needle"]["active"] = True
        just_added_patch = False
        if "pt1" in G["needle"] and "pt2" in G["needle"]: 
            if patch is None:
                print "Drawing needle patch"
                pt1 = G["needle"]["pt1"]
                pt2 = G["needle"]["pt2"]
                if command=="needle":
                    patch = Rectangle((pt1[0], pt1[1]), abs(pt2[0]-pt1[0]), abs(pt2[1]-pt1[1]), edgecolor='magenta', alpha=1, facecolor='magenta')
                else:
                    patch = Polygon(np.array([pt1, pt2, p(pt1), p(pt2)]), closed=False,
                            edgecolor='magenta', alpha=1, facecolor='magenta')
                    angle = get_angle(pt1, pt2)
                    print ("Angle :{}".format(angle)) 
                    # how to add text?
                just_added_patch = True

        if patch is not None and not just_added_patch:
            if isinstance(patch, Polygon):
                patches.append(patch)
                patch=None
            else:
                print "finalize"
                w1,h1 = patch.get_xy()
                w = patch.get_width()
                h = patch.get_height()

                if w>h:
                    print("horizontal patch")
                    line = Line(int(w1),int(h1),int(w1+w),int(h1), 3, magenta)
                else:
                    line = Line(int(w1),int(h1),int(w1),int(h1+h), 3, magenta)

                main_pic = draw_line_on_picture(main_pic, line)
            G["needle"] = {}

    if command == "divide":
        divide(command_meta.xdata, command_meta.ydata)
    if command == "brighten":
        main_pic = do_brighten(main_pic)
    if command == "mirror":
	main_pic = np.fliplr(main_pic)
    if command == "zoom":
        click_handlers = not click_handlers
    if command == "darken":
        main_pic = do_darken(main_pic)
    if command == "edge":
        main_pic = edge_detect(main_pic)
    if command == "resize_patch":
        if patch is not None:
            h = patch.get_height()
            w = patch.get_width()
            patch.set_width(int(w * 0.9))
            patch.set_height(int(h * 0.9))

    if command == "crop":
        if patch is not None:
            # apply patch
            # crop main_pic
            h = patch.get_height()
            w = patch.get_width()
            w1,h1 = patch.get_xy()
            main_pic = main_pic[slice(h1,h1+h),slice(w1,w1+w),slice(None)]
            patch=None

        else:
            # create patch
            # TODO: can read this from settings :))
            portrait_ratio = 14.8/20.8
            if orientation=="portrait":
                w_to_h = portrait_ratio
            else:
                w_to_h = 1.0/portrait_ratio
            shape = main_pic.shape
            border = 15
            hp = shape[0] - border
            wp = shape[1] - border

            if w_to_h * hp >wp:
                tw = wp
                th = wp / w_to_h 
            else:
                th = hp
                tw = w_to_h * hp
            print th,tw
            patch = Rectangle((0,0), tw, th, edgecolor='magenta', alpha=1, facecolor='none')
    if command == "undo":
        print "Undoing"
        print len(history)
        if len(history)>=2:
            main_pic,cmd = history[-2]
            print cmd
            history = history[:-1]

    if command!="undo":
        history.append((np.copy(main_pic),command))
    if command not in ["crop","horizontal_line","vertical_line","needle","angle_needle","resize_patch"]:
        patch = None
    command = None
    command_meta = None
    plot(patch=patch, click_handlers=click_handlers)
    if command is not None:
        handle_event()
Exemple #6
0
class StatsPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize)
        self.ztv_frame = self.GetTopLevelParent()
        self.ztv_frame.primary_image_panel.popup_menu_cursor_modes.append('Stats box')
        self.ztv_frame.primary_image_panel.available_cursor_modes['Stats box'] = {
                'set-to-mode':self.set_cursor_to_stats_box_mode,
                'on_button_press':self.on_button_press,
                'on_motion':self.on_motion,
                'on_button_release':self.on_button_release}
        self.textentry_font = wx.Font(14, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.FONTWEIGHT_LIGHT, False)

        self.stats_info = None
        
        self.last_string_values = {'x0':'', 'xsize':'', 'x1':'', 'y0':'', 'ysize':'', 'y1':''}
        self.stats_rect = Rectangle((0, 0), 10, 10, color='magenta', fill=False, zorder=100)
        # use self.stats_rect as where we store/retrieve the x0,y0,x1,y1
        # x0,y0,x1,y1 should be limited to range of 0 to shape-1
        # but, stats should be calculated over e.g. x0:x1+1  (so that have pixels to do stats on even if x0==x1)
        # and, width/height of stats_rect should always be >= 0
        
        values_sizer = wx.FlexGridSizer( 10, 5, 0, 0 )
        values_sizer.SetFlexibleDirection( wx.BOTH )
        values_sizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        self.low_static_text = wx.StaticText( self, wx.ID_ANY, u"Low", wx.DefaultPosition, wx.DefaultSize, wx.ALIGN_RIGHT )
        self.low_static_text.Wrap( -1 )
        values_sizer.Add(self.low_static_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 0)

        self.low_static_text = wx.StaticText( self, wx.ID_ANY, u"# pix", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.low_static_text.Wrap( -1 )
        values_sizer.Add(self.low_static_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 0)

        self.high_static_text = wx.StaticText( self, wx.ID_ANY, u"High", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.high_static_text.Wrap( -1 )
        values_sizer.Add(self.high_static_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 0)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        self.x_static_text = wx.StaticText( self, wx.ID_ANY, u"x", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.x_static_text.Wrap( -1 )
        values_sizer.Add(self.x_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 0)

        self.x0_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.x0_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.x0_textctrl, 0, wx.ALL, 2)
        self.x0_textctrl.Bind(wx.EVT_TEXT, self.x0_textctrl_changed)
        self.x0_textctrl.Bind(wx.EVT_TEXT_ENTER, self.x0_textctrl_entered)

        self.xsize_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                          wx.TE_PROCESS_ENTER)
        self.xsize_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.xsize_textctrl, 0, wx.ALL, 2)
        self.xsize_textctrl.Bind(wx.EVT_TEXT, self.xsize_textctrl_changed)
        self.xsize_textctrl.Bind(wx.EVT_TEXT_ENTER, self.xsize_textctrl_entered)

        self.x1_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.x1_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.x1_textctrl, 0, wx.ALL, 2)
        self.x1_textctrl.Bind(wx.EVT_TEXT, self.x1_textctrl_changed)
        self.x1_textctrl.Bind(wx.EVT_TEXT_ENTER, self.x1_textctrl_entered)

        self.npix_static_text = wx.StaticText( self, wx.ID_ANY, u"# pixels", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.npix_static_text.Wrap( -1 )
        values_sizer.Add(self.npix_static_text, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM, 0)

        self.y_static_text = wx.StaticText( self, wx.ID_ANY, u"y", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.y_static_text.Wrap( -1 )
        values_sizer.Add(self.y_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 0)

        self.y0_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.y0_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.y0_textctrl, 0, wx.ALL, 2)
        self.y0_textctrl.Bind(wx.EVT_TEXT, self.y0_textctrl_changed)
        self.y0_textctrl.Bind(wx.EVT_TEXT_ENTER, self.y0_textctrl_entered)

        self.ysize_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                          wx.TE_PROCESS_ENTER)
        self.ysize_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.ysize_textctrl, 0, wx.ALL, 2)
        self.ysize_textctrl.Bind(wx.EVT_TEXT, self.ysize_textctrl_changed)
        self.ysize_textctrl.Bind(wx.EVT_TEXT_ENTER, self.ysize_textctrl_entered)

        self.y1_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.y1_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.y1_textctrl, 0, wx.ALL, 2)
        self.y1_textctrl.Bind(wx.EVT_TEXT, self.y1_textctrl_changed)
        self.y1_textctrl.Bind(wx.EVT_TEXT_ENTER, self.y1_textctrl_entered)
        
        self.npix_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                         wx.TE_READONLY)
        self.npix_textctrl.SetFont(self.textentry_font)
        self.npix_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.npix_textctrl, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, 0)
  
        values_sizer.AddSpacer((0,15), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        self.median_static_text = wx.StaticText( self, wx.ID_ANY, u"Median", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.median_static_text.Wrap( -1 )
        values_sizer.Add(self.median_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 0)
        self.median_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_READONLY)
        self.median_textctrl.SetFont(self.textentry_font)
        self.median_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.median_textctrl, 0, wx.ALL, 2)
        self.robust_static_text = wx.StaticText( self, wx.ID_ANY, u"Robust", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.robust_static_text.Wrap( -1 )
        values_sizer.Add(self.robust_static_text, 0, wx.ALL|wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL, 0)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        self.mean_static_text = wx.StaticText( self, wx.ID_ANY, u"Mean", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.mean_static_text.Wrap( -1 )
        values_sizer.Add(self.mean_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 0)
        self.mean_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_READONLY)
        self.mean_textctrl.SetFont(self.textentry_font)
        self.mean_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.mean_textctrl, 0, wx.ALL, 2)
        self.robust_mean_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_READONLY)
        self.robust_mean_textctrl.SetFont(self.textentry_font)
        self.robust_mean_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.robust_mean_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        self.stdev_static_text = wx.StaticText( self, wx.ID_ANY, u"Stdev", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.stdev_static_text.Wrap( -1 )
        values_sizer.Add(self.stdev_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 0)
        self.stdev_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_READONLY)
        self.stdev_textctrl.SetFont(self.textentry_font)
        self.stdev_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.stdev_textctrl, 0, wx.ALL, 2)
        self.robust_stdev_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_READONLY)
        self.robust_stdev_textctrl.SetFont(self.textentry_font)
        self.robust_stdev_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.robust_stdev_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,15), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        self.min_static_text = wx.StaticText( self, wx.ID_ANY, u"Min", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.min_static_text.Wrap( -1 )
        values_sizer.Add(self.min_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 0)
        self.minval_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.minval_textctrl.SetFont(self.textentry_font)
        self.minval_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.minval_textctrl, 0, wx.ALL, 2)
        self.minpos_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.minpos_textctrl.SetFont(self.textentry_font)
        self.minpos_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.minpos_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0,0), 0, wx.EXPAND)
        self.max_static_text = wx.StaticText( self, wx.ID_ANY, u"Max", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.max_static_text.Wrap( -1 )
        values_sizer.Add(self.max_static_text, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, 0)
        self.maxval_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.maxval_textctrl.SetFont(self.textentry_font)
        self.maxval_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.maxval_textctrl, 0, wx.ALL, 2)
        self.maxpos_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.maxpos_textctrl.SetFont(self.textentry_font)
        self.maxpos_textctrl.SetBackgroundColour(textctrl_output_only_background_color)
        values_sizer.Add(self.maxpos_textctrl, 0, wx.ALL, 2)
             
        self.hideshow_button = wx.Button(self, wx.ID_ANY, u"Show", wx.DefaultPosition, wx.DefaultSize, 0)
        values_sizer.Add(self.hideshow_button, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 2)
        self.hideshow_button.Bind(wx.EVT_BUTTON, self.on_hideshow_button)

        v_sizer1 = wx.BoxSizer(wx.VERTICAL)
        v_sizer1.AddStretchSpacer(1.0)
        v_sizer1.Add(values_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL)
        v_sizer1.AddStretchSpacer(1.0)
        self.SetSizer(v_sizer1)
        pub.subscribe(self.queue_update_stats, 'recalc-display-image-called')
        pub.subscribe(self._set_stats_box_parameters, 'set-stats-box-parameters')
        pub.subscribe(self.publish_stats_to_stream, 'get-stats-box-info')

    def publish_stats_to_stream(self, msg=None):
        wx.CallAfter(send_to_stream, sys.stdout, ('stats-box-info', self.stats_info))

    def on_button_press(self, event):
        self.select_panel()
        self.update_stats_box(event.xdata, event.ydata, event.xdata, event.ydata)
        self.redraw_overplot_on_image()
        self.cursor_stats_box_x0, self.cursor_stats_box_y0 = event.xdata, event.ydata

    def on_motion(self, event):
        if event.button is not None:
            self.update_stats_box(self.cursor_stats_box_x0, self.cursor_stats_box_y0, event.xdata, event.ydata)
            self.redraw_overplot_on_image()
            self.update_stats()

    def on_button_release(self, event):
        self.redraw_overplot_on_image()
        self.update_stats()

    def set_cursor_to_stats_box_mode(self, event):
        self.ztv_frame.primary_image_panel.cursor_mode = 'Stats box'
        self.ztv_frame.stats_panel.select_panel()
        self.ztv_frame.stats_panel.highlight_panel()

    def queue_update_stats(self, msg=None):  
        """
        wrapper to call update_stats from CallAfter in order to make GUI as responsive as possible.
        """
        wx.CallAfter(self.update_stats, msg=None)

    def _set_stats_box_parameters(self, msg):
        """
        wrapper to update_stats_box to receive messages & translate them correctly
        """
        x0,x1,y0,y1 = [None]*4
        if msg['xrange'] is not None:
            x0,x1 = msg['xrange']
        if msg['yrange'] is not None:
            y0,y1 = msg['yrange']
        if msg['xrange'] is not None or msg['yrange'] is not None:
            self.update_stats_box(x0, y0, x1, y1)
        if msg['show_overplot'] is not None:
            if msg['show_overplot']:
                self.redraw_overplot_on_image()
            else:
                self.remove_overplot_on_image()
        send_to_stream(sys.stdout, ('set-stats-box-parameters-done', True))

    def update_stats_box(self, x0=None, y0=None, x1=None, y1=None):
        if x0 is None:
            x0 = self.stats_rect.get_x()
        if y0 is None:
            y0 = self.stats_rect.get_y()
        if x1 is None:
            x1 = self.stats_rect.get_x() + self.stats_rect.get_width()
        if y1 is None:
            y1 = self.stats_rect.get_y() + self.stats_rect.get_height()
        if x0 > x1:
            x0, x1 = x1, x0
        if y0 > y1:
            y0, y1 = y1, y0
        x0 = min(max(0, x0), self.ztv_frame.display_image.shape[1] - 1)
        y0 = min(max(0, y0), self.ztv_frame.display_image.shape[0] - 1)
        x1 = min(max(0, x1), self.ztv_frame.display_image.shape[1] - 1)
        y1 = min(max(0, y1), self.ztv_frame.display_image.shape[0] - 1)
        self.stats_rect.set_bounds(x0, y0, x1 - x0, y1 - y0)
        if self.hideshow_button.GetLabel() == 'Hide':  
            self.ztv_frame.primary_image_panel.figure.canvas.draw()
        self.update_stats()

    def remove_overplot_on_image(self):
        self.ztv_frame.primary_image_panel.remove_patch('stats_panel:stats_rect')
        self.hideshow_button.SetLabel(u"Show")

    def redraw_overplot_on_image(self):
        self.ztv_frame.primary_image_panel.add_patch('stats_panel:stats_rect', self.stats_rect)
        self.hideshow_button.SetLabel(u"Hide")        

    def on_hideshow_button(self, evt):
        if self.hideshow_button.GetLabel() == 'Hide':
            self.remove_overplot_on_image()
        else:
            self.redraw_overplot_on_image()

    def get_x0y0x1y1_from_stats_rect(self):
        x0 = self.stats_rect.get_x()
        y0 = self.stats_rect.get_y()
        x1 = x0 + self.stats_rect.get_width()
        y1 = y0 + self.stats_rect.get_height()
        return x0,y0,x1,y1
        
    def update_stats(self, msg=None):
        x0,y0,x1,y1 = self.get_x0y0x1y1_from_stats_rect()
        x0, y0 = int(np.round(x0)), int(np.round(y0))
        x1, y1 = int(np.round(x1)), int(np.round(y1))
        self.last_string_values['x0'] = str(int(x0))
        self.x0_textctrl.SetValue(self.last_string_values['x0'])
        self.last_string_values['y0'] = str(int(y0))
        self.y0_textctrl.SetValue(self.last_string_values['y0'])

        x_npix = int(x1 - x0 + 1)
        self.last_string_values['xsize'] = str(x_npix)
        self.xsize_textctrl.SetValue(self.last_string_values['xsize'])
        y_npix = int(y1 - y0 + 1)
        self.last_string_values['ysize'] = str(y_npix)
        self.ysize_textctrl.SetValue(self.last_string_values['ysize'])

        self.last_string_values['x1'] = str(int(x1))
        self.x1_textctrl.SetValue(self.last_string_values['x1'])
        self.last_string_values['y1'] = str(int(y1))
        self.y1_textctrl.SetValue(self.last_string_values['y1'])
    
        self.npix_textctrl.SetValue(str(x_npix * y_npix))

        stats_data = self.ztv_frame.display_image[y0:y1+1, x0:x1+1]
        finite_mask = np.isfinite(stats_data)
        if finite_mask.max() is np.True_:
            stats_data_mean = stats_data[finite_mask].mean()
            stats_data_median = np.median(stats_data[finite_mask])
            stats_data_std = stats_data[finite_mask].std()
            robust_mean, robust_median, robust_std = sigma_clipped_stats(stats_data[finite_mask])
        else:
            stats_data_mean = np.nan
            stats_data_median = np.nan
            stats_data_std = np.inf
            robust_mean, robust_median, robust_std = np.nan, np.nan, np.inf
        self.stats_info = {'xrange':[x0,x1], 'yrange':[y0,y1],
                           'mean':stats_data_mean, 'median':stats_data_median, 'std':stats_data_std, 
                           'min':stats_data.min(), 'max':stats_data.max()} # want min/max to reflect any Inf/NaN
        self.mean_textctrl.SetValue("{:0.4g}".format(self.stats_info['mean']))
        self.median_textctrl.SetValue("{:0.4g}".format(self.stats_info['median']))
        self.stdev_textctrl.SetValue("{:0.4g}".format(self.stats_info['std']))
        self.stats_info['robust-mean'] = robust_mean
        self.stats_info['robust-median'] = robust_median
        self.stats_info['robust-std'] = robust_std
        self.robust_mean_textctrl.SetValue("{:0.4g}".format(robust_mean)) 
        self.robust_stdev_textctrl.SetValue("{:0.4g}".format(robust_std))
        self.minval_textctrl.SetValue("{:0.4g}".format(self.stats_info['min']))
        self.maxval_textctrl.SetValue("{:0.4g}".format(self.stats_info['max']))
        wmin = np.where(stats_data == stats_data.min())
        wmin = [(wmin[1][i] + x0,wmin[0][i] + y0) for i in np.arange(wmin[0].size)]
        if len(wmin) == 1:
            wmin = wmin[0]
        self.minpos_textctrl.SetValue("{}".format(wmin))
        self.stats_info['wmin'] = wmin
        wmax = np.where(stats_data == stats_data.max())
        wmax = [(wmax[1][i] + x0,wmax[0][i] + y0) for i in np.arange(wmax[0].size)]
        if len(wmax) == 1:
            wmax = wmax[0]
        self.maxpos_textctrl.SetValue("{}".format(wmax))
        self.stats_info['wmax'] = wmax
        set_textctrl_background_color(self.x0_textctrl, 'ok')
        set_textctrl_background_color(self.x1_textctrl, 'ok')
        set_textctrl_background_color(self.xsize_textctrl, 'ok')
        set_textctrl_background_color(self.y0_textctrl, 'ok')
        set_textctrl_background_color(self.y1_textctrl, 'ok')
        set_textctrl_background_color(self.ysize_textctrl, 'ok')
        
    def x0_textctrl_changed(self, evt):
        validate_textctrl_str(self.x0_textctrl, int, self.last_string_values['x0'])

    def x0_textctrl_entered(self, evt):
        if validate_textctrl_str(self.x0_textctrl, int, self.last_string_values['x0']):
            self.last_string_values['x0'] = self.x0_textctrl.GetValue()
            self.update_stats_box(int(self.last_string_values['x0']), None, None, None)
            self.x0_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()
            
    def xsize_textctrl_changed(self, evt):
        validate_textctrl_str(self.xsize_textctrl, int, self.last_string_values['xsize'])

    def xsize_textctrl_entered(self, evt):
        if validate_textctrl_str(self.xsize_textctrl, int, self.last_string_values['xsize']):
            self.last_string_values['xsize'] = self.xsize_textctrl.GetValue()
            xsize = int(self.last_string_values['xsize'])
            sys.stderr.write("\n\nxsize = {}\n\n".format(xsize))
            x0,y0,x1,y1 = self.get_x0y0x1y1_from_stats_rect()
            xc = (x0 + x1) / 2.
            x0 = max(0, int(xc - xsize / 2.))
            x1 = x0 + xsize - 1
            x1 = min(x1, self.ztv_frame.display_image.shape[1] - 1)
            x0 = x1 - xsize + 1
            x0 = max(0, int(xc - xsize / 2.))
            self.update_stats_box(x0, y0, x1, y1)
            self.xsize_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def x1_textctrl_changed(self, evt):
        validate_textctrl_str(self.x1_textctrl, int, self.last_string_values['x1'])

    def x1_textctrl_entered(self, evt):
        if validate_textctrl_str(self.x1_textctrl, int, self.last_string_values['x1']):
            self.last_string_values['x1'] = self.x1_textctrl.GetValue()
            self.update_stats_box(None, None, int(self.last_string_values['x1']), None)
            self.x1_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def y0_textctrl_changed(self, evt):
        validate_textctrl_str(self.y0_textctrl, int, self.last_string_values['y0'])

    def y0_textctrl_entered(self, evt):
        if validate_textctrl_str(self.y0_textctrl, int, self.last_string_values['y0']):
            self.last_string_values['y0'] = self.y0_textctrl.GetValue()
            self.update_stats_box(None, int(self.last_string_values['y0']), None, None)
            self.y0_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def ysize_textctrl_changed(self, evt):
        validate_textctrl_str(self.ysize_textctrl, int, self.last_string_values['ysize'])

    def ysize_textctrl_entered(self, evt):
        if validate_textctrl_str(self.ysize_textctrl, int, self.last_string_values['ysize']):
            self.last_string_values['ysize'] = self.ysize_textctrl.GetValue()
            ysize = int(self.last_string_values['ysize'])
            x0,y0,x1,y1 = self.get_x0y0x1y1_from_stats_rect()
            yc = (y0 + y1) / 2.
            y0 = max(0, int(yc - ysize / 2.))
            y1 = y0 + ysize - 1
            y1 = min(y1, self.ztv_frame.display_image.shape[0] - 1)
            y0 = y1 - ysize + 1
            y0 = max(0, int(yc - ysize / 2.))
            self.update_stats_box(x0, y0, x1, y1)
            self.ysize_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def y1_textctrl_changed(self, evt):
        validate_textctrl_str(self.y1_textctrl, int, self.last_string_values['y1'])

    def y1_textctrl_entered(self, evt):
        if validate_textctrl_str(self.y1_textctrl, int, self.last_string_values['y1']):
            self.last_string_values['y1'] = self.y1_textctrl.GetValue()
            self.update_stats_box(None, None, None, int(self.last_string_values['y1']))
            self.y1_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()
Exemple #7
0
class CaseSelector(_my_SelectorWidget):
    """
    Select a min/max range of the x or y axes for a matplotlib Axes.
    For the selector to remain responsive you much keep a reference to
    it.
    Example usage::
        ax = subplot(111)
        ax.plot(x,y)
        def onselect(vmin, vmax):
            print vmin, vmax
        span = SpanSelector(ax, onselect, 'horizontal')
    *onmove_callback* is an optional callback that is called on mouse
    move within the span range
    """

    def __init__(self, ax, onselect, onclick, minspan=0.1, nrect=10,
                 update_on_ext_event=True,
                 rectprops=None, stay_rectprops=None, lineprops=None,
                 onmove_callback=None, button=None):
        """
        Create a case selector in *ax*.  When a selection is made, call 
        *onselect* with::
            onselect(vmin, vmax)
        and clear the span.
        *direction* must be 'horizontal' or 'vertical'
        If *minspan* is not *None*, ignore events smaller than *minspan*
        The span rectangle is drawn with *rectprops*; default::
          rectprops = dict(facecolor='red', alpha=0.5)
        Set the visible attribute to *False* if you want to turn off
        the functionality of the span selector
        If *span_stays* is True, the span stays visble after making
        a valid selection.
        *button* is a list of integers indicating which mouse buttons should
        be used for selection.  You can also specify a single
        integer if only a single button is desired.  Default is *None*,
        which does not limit which button can be used.
        Note, typically:
         1 = left mouse button
         2 = center mouse button (scroll wheel)
         3 = right mouse button
        """
        _my_SelectorWidget.__init__(self, ax, onselect, update_on_ext_event, button=button)

        if rectprops is None:
            self.rectprops = dict(facecolor='#f5f5f5', alpha=0.3)
        else:
            self.rectprops = rectprops
        if lineprops is None:
            self.lineprops = dict(color='#e66101', lw=2)  # bar color
        else:
            self.lineprops = lineprops

        if not isinstance(nrect, list):
            nrect = [nrect]
        if stay_rectprops is None:
            cc = ['#984ea3', '#ffff33', '#d8b365', '#5ab4ac']  # green yellow blue red
            color = [cc[i % len(cc)] for i in range(0, len(nrect))]
            self.stay_rectprops = [dict(facecolor=c, alpha=0.5) for c in color]
        else:
            assert (len(nrect) == len(stay_rectprops))
            self.stay_rectprops = stay_rectprops

        self.pressv = None
        self.onclick = onclick
        self.onmove_callback = onmove_callback
        self.minspan = minspan

        # Needed when dragging out of axes
        self.prev = (0, 0)

        # Reset canvas so that `new_axes` connects events.
        self.canvas = None
        self.new_axes(ax, nrect)

    def new_axes(self, ax, nrect):
        self.ax = ax
        if self.canvas is not ax.figure.canvas:
            if self.canvas is not None:
                self.disconnect_events()
            self.canvas = ax.figure.canvas
            self.connect_default_events()
        # span
        trans = blended_transform_factory(self.ax.transData, self.ax.transAxes)
        w, h = 0, 1
        self.rect = Rectangle((0, 0), w, h, transform=trans, visible=False,
                              animated=True, **self.rectprops)
        self.ax.add_patch(self.rect)
        self.artists = [self.rect]
        # stay rect
        self.stay_rects = []
        for set in range(0, len(nrect)):
            self.stay_rects.append([])
            for n in range(0, nrect[set]):
                stay_rect = Rectangle((0, 0), w, h, transform=trans, visible=False,
                                      animated=True, **self.stay_rectprops[set])
                self.ax.add_patch(stay_rect)
                self.stay_rects[set].append(stay_rect)
            self.artists.extend(self.stay_rects[set])
        # bar
        self.bar = ax.axvline(0, w, h, visible=False, **self.lineprops)
        self.artists.append(self.bar)

    def set_bar_position(self, x):
        self.bar.set_xdata(x)
        self.bar.set_visible(True)

    def set_stay_rects_x_bounds(self, xarr, set=0):
        for n, stay_rect in enumerate(self.stay_rects[set]):
            try:
                xmin, xmax = xarr[n]
            except IndexError:
                stay_rect.set_visible(False)
            else:
                stay_rect.set_x(xmin)
                stay_rect.set_y(self.rect.get_y())
                stay_rect.set_width(abs(xmax - xmin))
                stay_rect.set_height(self.rect.get_height())
                stay_rect.set_visible(True)

    def set_stay_rect_visible(self, b=True, set=0):
        for stay_rect in self.stay_rects[set]:
            stay_rect.set_visible(b)

    def ignore(self, event):
        """return *True* if *event* should be ignored"""
        return _SelectorWidget.ignore(self, event) or not self.visible

    def _press(self, event):
        """on button press event"""
        xdata, ydata = self._get_data(event)
        self.pressv = xdata
        return False

    def _release(self, event):
        """on button release event"""
        if self.pressv is None:
            return
        self.buttonDown = False

        self.rect.set_visible(False)
        vmin = self.pressv
        xdata, ydata = self._get_data(event)
        vmax = xdata or self.prev[0]

        if vmin > vmax:
            vmin, vmax = vmax, vmin
        span = vmax - vmin
        if span < self.minspan and event.button == 3:  # right click to remove span
            self.onclick(vmin)
            return
        elif span > self.minspan and event.button == 1:
            self.onselect(vmin, vmax)
            self.pressv = None
            return False
        elif span > self.minspan and event.button == 3:
            self.onselect(vmin, vmax, True)
            self.pressv = None
            return False

    def _onmove(self, event):
        self.rect.set_visible(self.visible)
        """on motion notify event"""
        if self.pressv is None:
            return
        x, y = self._get_data(event)
        if x is None:
            return

        self.prev = x, y
        v = x
        minv, maxv = v, self.pressv
        if minv > maxv:
            minv, maxv = maxv, minv
        self.rect.set_x(minv)
        self.rect.set_width(maxv - minv)

        if self.onmove_callback is not None:
            vmin = self.pressv
            xdata, ydata = self._get_data(event)
            vmax = xdata or self.prev[0]

            if vmin > vmax:
                vmin, vmax = vmax, vmin
            self.onmove_callback(vmin, vmax)
        if not self.update_on_ext_event:
            self.update()
        return False
Exemple #8
0
class LensGUI:
    def __init__(self,parent):
        self.root = Tk.Tk()

        self.parent = parent
        self.img = self.parent.img
        self.color = self.parent.color

        self.mover = None

        f1 = Figure((12.06,12.06))
        a1 = f1.add_axes([0,101./201,100./201,100./201])
        self.img1 = a1.imshow(self.img,origin='bottom',interpolation='nearest')
        a1.set_xticks([])
        a1.set_yticks([])
        xlim = a1.get_xlim()
        ylim = a1.get_ylim()

        a2 = f1.add_axes([101./201,101./201,100./201,100./201])
        self.img2 = a2.imshow(self.img,origin='bottom',interpolation='nearest')
        a2.set_xlim(xlim)
        a2.set_ylim(ylim)
        a2.set_xticks([])
        a2.set_yticks([])

        a3 = f1.add_axes([0.,0.,100./201,100./201])
        self.img3 = a3.imshow(self.img*0+1,origin='bottom',interpolation='nearest')
        a3.set_xlim(xlim)
        a3.set_ylim(ylim)
        a3.set_xticks([])
        a3.set_yticks([])

        a4 = f1.add_axes([101./201,0.,100./201,100./201])
        a4.imshow(self.parent.b*0)
        a4.cla()
        a4.set_xlim(xlim)
        a4.set_ylim(ylim)
        a4.set_xticks([])
        a4.set_yticks([])

        canvas = FigureCanvasTkAgg(f1,master=self.root)
        canvas.show()
        canvas.get_tk_widget().pack(side=Tk.TOP,fill=Tk.BOTH,expand=1)
        toolbar = NavigationToolbar2TkAgg(canvas,self.root )
        toolbar.update()
        canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
        bFrame = Tk.Frame(self.root)
        bFrame.pack(side=Tk.TOP,fill=Tk.BOTH,expand=1)

        self.f1 = f1
        self.a1 = a1
        self.a2 = a2
        self.a3 = a3
        self.a4 = a4
        self.bFrame = bFrame

        self.canvas = canvas
        self.toolbar = toolbar

        self.rubberBox = None

        self.addButtons()

    def addButtons(self):
        self.activeButton = None
        self.bAGtext = Tk.StringVar()
        self.bAGtext.set('Add Galaxy')
        self.buttonAG = Tk.Button(self.toolbar,textvariable=self.bAGtext,command=self.parent.addGal,width=10)
        self.buttonAG.pack(side=Tk.LEFT)

        self.bALtext = Tk.StringVar()
        self.bALtext.set('Add Lens')
        self.buttonAL = Tk.Button(self.toolbar,textvariable=self.bALtext,command=self.parent.addLens,width=10)
        self.buttonAL.pack(side=Tk.LEFT)

        self.bAStext = Tk.StringVar()
        self.bAStext.set('Add Source')
        self.buttonAS = Tk.Button(self.toolbar,textvariable=self.bAStext,command=self.parent.addSrc,width=10)
        self.buttonAS.pack(side=Tk.LEFT)
        self.buttonAS.configure(state='disabled')

        self.buttonFit = Tk.Button(self.toolbar,text='Fit Light',command=self.parent.fitLight,width=10)
        self.buttonFit.pack(side=Tk.LEFT)
        #self.buttonFit.configure(state='disabled')

        self.bOpttext = Tk.StringVar()
        self.bOpttext.set('Optimize')
        self.buttonOptimize = Tk.Button(self.toolbar,textvariable=self.bOpttext,command=self.parent.optimize,width=10)
        self.buttonOptimize.pack(side=Tk.LEFT)
        #self.buttonOptimize.configure(state='disabled')

        self.buttonSave = Tk.Button(self.bFrame,text='Save',command=self.parent.saveState,width=10)
        self.buttonSave.pack(side=Tk.LEFT)

        self.buttonLoad = Tk.Button(self.bFrame,text='Load',command=self.parent.loadState,width=10)
        self.buttonLoad.pack(side=Tk.LEFT)

        self.bAMtext = Tk.StringVar()
        self.bAMtext.set('Add Mask')
        self.buttonMask = Tk.Button(self.bFrame,textvariable=self.bAMtext,command=self.addMask,width=10)
        self.buttonMask.pack(side=Tk.LEFT)


    def deactivateButtons(self):
        if self.toolbar.mode!='':
            self.toolbar.zoom()
            self.toolbar.pan()
            self.toolbar.pan()
        if self.activeButton==self.buttonAG:
            self.bAGtext.set('Add Galaxy')
            self.canvas.mpl_disconnect(self.pressid)
        elif self.activeButton==self.buttonAL:
            self.bALtext.set('Add Lens')
            self.canvas.mpl_disconnect(self.pressid)
        elif self.activeButton==self.buttonAS:
            self.bAStext.set('Add Source')
            self.canvas.mpl_disconnect(self.pressid)
        elif self.activeButton==self.buttonMask:
            self.bAMtext.set('Add Mask')
            self.canvas.mpl_disconnect(self.pressid)
            self.canvas.mpl_disconnect(self.moveid)
            self.canvas.mpl_disconnect(self.releaseid)
        self.pressid = None
        self.releaseid = None
        self.activeButton = None


    def addMask(self,loaded=False):
        from matplotlib.patches import Rectangle
        if loaded and self.parent.mask is not None:
            import numpy
            y,x = numpy.where(self.parent.mask==1)
            x0,x1,y0,y1 = x.min(),x.max(),y.min(),y.max()
            self.rubberBox = Rectangle((x0,y0),x1-x0,y1-y0,fc='none',ec='w')
            self.a1.add_patch(self.rubberBox)
            self.canvas.draw()
            return
        if self.activeButton==self.buttonMask:
            self.deactivateButtons()
            return
        self.deactivateButtons()
        self.xmask = None
        def onPress(event):
            axes = event.inaxes
            if axes==self.a1:
                self.xmask = event.xdata
                self.ymask = event.ydata
            if self.rubberBox is not None:
                self.rubberBox.remove()
                self.rubberBox = None
        def onMove(event):
            if self.xmask is None:
                return
            axes = event.inaxes
            if axes==self.a1:
                x,y = event.xdata,event.ydata
                dx = x-self.xmask
                dy = y-self.ymask
                if self.rubberBox is None:
                    self.rubberBox = Rectangle((self.xmask,self.ymask),
                                                dx,dy,fc='none',ec='w')
                    self.a1.add_patch(self.rubberBox)
                else:
                    self.rubberBox.set_height(dy)
                    self.rubberBox.set_width(dx)
                self.canvas.draw()
        def onRelease(event):
            dy = int(self.rubberBox.get_height())
            dx = int(self.rubberBox.get_width())
            x0,y0 = int(self.xmask),int(self.ymask)
            x1,y1 = x0+dx,y0+dy
            self.parent.mask = self.parent.imgs[0]*0
            self.parent.mask[y0:y1,x0:x1] = 1
            self.parent.mask = self.parent.mask==1
            self.deactivateButtons()
        self.pressid = self.canvas.mpl_connect('button_press_event',onPress)
        self.moveid = self.canvas.mpl_connect('motion_notify_event',onMove)
        self.releaseid = self.canvas.mpl_connect('button_release_event',onRelease)
        self.bAMtext.set('Cancel')
        self.activeButton = self.buttonMask


    def showResid(self):
        if self.parent.models is None:
            self.a2.imshow(self.parent.img,origin='bottom',
                            interpolation='nearest')
            self.a3.cla()
            self.a3.set_xticks([])
            self.a3.set_yticks([])
            self.canvas.show()
            return
        models = self.parent.models
        imgs = self.parent.imgs
        nimgs = self.parent.nimgs
        if self.color is not None:
            if nimgs==2:
                b = imgs[0]-models[0]
                r = imgs[1]-models[1]
                g = (b+r)/2.
                resid = self.color.colorize(b,g,r)
                b = models[0]
                r = models[1]
                g = (b+r)/2.
                model = self.color.colorize(b,g,r,newI=True)
            else:
                b = imgs[0]-models[0]
                g = imgs[1]-models[1]
                r = imgs[2]-models[2]
                resid = self.color.colorize(b,g,r)
                b = models[0]
                g = models[1]
                r = models[2]
                model = self.color.colorize(b,g,r,newI=True)
        else:
            resid = imgs[0]-models[0]
            model = models[0]
            self.img3.set_clim([0.,model.max()])
        #self.a2.imshow(resid,origin='bottom',interpolation='nearest')
        #self.a3.imshow(model,origin='bottom',interpolation='nearest')
        self.img2.set_data(resid)
        self.img3.set_data(model)
        self.canvas.draw()

    def redrawSymbols(self):
        import objectMover
        if self.mover is not None:
            self.mover.remove()
        self.mover = objectMover.ObjMover(self.parent,self.a4,self.canvas)
Exemple #9
0
class ZoneInteret:
    """
        Cette classe permet de gérer les informations sur la zone d'interet
        Une zone interet est un cadre d'image sur l'image entière.
        On se concentre sur cette zone d'interet pour faire le traitement.
        C'est une manière de réduire le bruit sur le résultat de traitement
        @version 3.0
    """
    @staticmethod
    def verifier_presence_fichier_ini():
        """
            Vérifier si les fichiers de zone d'interet sont déjà présents dans le dossier
            :param:
            :returns: true si présent, false sinon
        """
        return os.path.isfile('./zi/param.ini')

    @staticmethod
    def supprimer_ZI(window):
        """
            La méthode pour gérer la suppresion de zone interet
            :param window: le fenetre principale
            :returns:
        """

        #si le fichier ./zi/param.ini existe
        if os.path.isfile('./zi/param.ini'):
            try:
                #suppression de ces documents
                os.remove("./zi/param.ini")
                os.remove("./zi/image_modele.png")
                os.remove("./zi/image_zone_interet.png")
                #on informe l'utilisateur  du succes de l'operation
                QMessageBox.information(
                    window, "Information",
                    "Supprimer la Zone d'intérêt avec succès", QMessageBox.Ok)
            except OSError:
                #on informe l'utilisateur  de l'echec de l'operation
                QMessageBox.warning(
                    window, "Erreur",
                    "Impossible de supprimer les fichiers dans le repertoire /zi",
                    QMessageBox.Ok)
        else:
            # si le fichier ./zi/param.ini n'existe pas
            QMessageBox.warning(
                window, "Erreur",
                "Impossible de trouver les fichiers dans le repertoire /zi",
                QMessageBox.Ok)

    def __init__(self, video):
        """
            Initialise les variables necessaires à l'affichage de l'image et aux evenements
            :param video: la vidéo à traiter
            :returns:
        """
        self.flag = False
        self.get_one_image_from_video(video)

        # On se sert de l'image extraite precedemment
        self.img = mpimg.imread('./zi/image_modele.png')

        # On initialise le titre de la fenetre
        fig = plt.figure(1)
        fig.canvas.set_window_title("Zone Interet")

        # On récupère les infos des axes
        self.ax = plt.gca()

        # On initialise le futur rectangle dessiné (non rempli aux bordures rouges)
        self.rect = Rectangle((0, 0), 1, 1, fill=False, edgecolor="red")

        # Initialisation des points du rectangle
        self.x0 = None
        self.y0 = None
        self.x1 = None
        self.y1 = None
        self.ax.add_patch(self.rect)

        # Liaison des événements
        self.ax.figure.canvas.mpl_connect('button_press_event',
                                          self.on_mouseclick_press)
        self.ax.figure.canvas.mpl_connect('button_release_event',
                                          self.on_mouseclick_release)
        self.ax.figure.canvas.mpl_connect('key_press_event',
                                          self.on_keyboard_press)

        # Affichage de l'image dans la fenêtre
        self.imgplot = plt.imshow(self.img)

        self.show_window()

    def on_mouseclick_press(self, event):
        """
            Un click gauche -> sauvegarde des coordonnées du pointeur
            :param event: évènement de clique
            :returns:
        """
        #coordonnees x de la zone cliquee
        self.x0 = event.xdata
        #coordonnees y de la zone cliquee
        self.y0 = event.ydata

    def on_mouseclick_release(self, event):
        """
            Click gauche relâché -> dessin du rectangle
            :param event: évènement de souris
            :returns:
        """
        #obtention des autres coordonnees pour dessiner le rectangle
        self.x1 = event.xdata
        self.y1 = event.ydata
        self.rect.set_width(self.x1 - self.x0)
        self.rect.set_height(self.y1 - self.y0)
        self.rect.set_xy((self.x0, self.y0))
        self.ax.figure.canvas.draw()

    def on_keyboard_press(self, event):
        """
            Si la touche "enter" est appuyée, on sauvegarde la zone d'intérêt
            :param event: évenenment de keyboard
            :return:
        """
        #touche enter appuyée
        if event.key == 'enter':
            self.flag = True
            # on ecrit dans le fichier
            with open("./zi/param.ini", "w") as file:
                file.write(str(int(self.rect.get_x())) + ",")
                file.write(str(int(self.rect.get_y())) + ",")
                file.write(str(int(self.rect.get_width())) + ",")
                file.write(str(int(self.rect.get_height())))

            # On cache les axes avant d'enregistrer l'image modele avec la zone d'interet
            self.ax.get_xaxis().set_visible(False)
            self.ax.get_yaxis().set_visible(False)
            # Enregistrement zone interet
            plt.title("Zone interet")
            plt.savefig("./zi/image_zone_interet.png")
            plt.close()

    def show_window(self):
        """
            Pour afficher la fenetre qui est utilisee pour choisir une zone interet
            :param:
            :returns:
        """

        plt.title(
            "Selectionnez la zone d'interet avec la souris. Appuyez sur entrer pour valider."
        )
        # Affichage de la fenetre
        plt.show()

    def get_one_image_from_video(self, video):
        """
        Extrait une image de la vidéo selectionnée
        Cette image est utilisée pour choisir une zone interet
        :param video: la vidéo choisie
        :return:
        """
        video_capture = cv2.VideoCapture(video)
        nb_frame = video_capture.get(cv2.CAP_PROP_FRAME_COUNT)
        video_capture.set(cv2.CAP_PROP_FRAME_COUNT, int(nb_frame - 1))
        success, self.image = video_capture.read()
        #sauvegarder l'image
        cv2.imwrite("zi/image_modele.png", self.image)
Exemple #10
0
class StatsPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY, wx.DefaultPosition,
                          wx.DefaultSize)
        self.ztv_frame = self.GetTopLevelParent()
        self.ztv_frame.primary_image_panel.popup_menu_cursor_modes.append(
            'Stats box')
        self.ztv_frame.primary_image_panel.available_cursor_modes[
            'Stats box'] = {
                'set-to-mode': self.set_cursor_to_stats_box_mode,
                'on_button_press': self.on_button_press,
                'on_motion': self.on_motion,
                'on_button_release': self.on_button_release
            }
        self.textentry_font = wx.Font(14, wx.FONTFAMILY_MODERN, wx.NORMAL,
                                      wx.FONTWEIGHT_LIGHT, False)

        self.stats_info = None

        self.last_string_values = {
            'x0': '',
            'xsize': '',
            'x1': '',
            'y0': '',
            'ysize': '',
            'y1': ''
        }
        self.stats_rect = Rectangle((0, 0),
                                    10,
                                    10,
                                    color='magenta',
                                    fill=False,
                                    zorder=100)
        # use self.stats_rect as where we store/retrieve the x0,y0,x1,y1
        # x0,y0,x1,y1 should be limited to range of 0 to shape-1
        # but, stats should be calculated over e.g. x0:x1+1  (so that have pixels to do stats on even if x0==x1)
        # and, width/height of stats_rect should always be >= 0

        values_sizer = wx.FlexGridSizer(10, 5, 0, 0)
        values_sizer.SetFlexibleDirection(wx.BOTH)
        values_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        self.low_static_text = wx.StaticText(self, wx.ID_ANY, u"Low",
                                             wx.DefaultPosition,
                                             wx.DefaultSize, wx.ALIGN_RIGHT)
        self.low_static_text.Wrap(-1)
        values_sizer.Add(self.low_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 0)

        self.low_static_text = wx.StaticText(self, wx.ID_ANY, u"# pix",
                                             wx.DefaultPosition,
                                             wx.DefaultSize, 0)
        self.low_static_text.Wrap(-1)
        values_sizer.Add(self.low_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 0)

        self.high_static_text = wx.StaticText(self, wx.ID_ANY, u"High",
                                              wx.DefaultPosition,
                                              wx.DefaultSize, 0)
        self.high_static_text.Wrap(-1)
        values_sizer.Add(self.high_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 0)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        self.x_static_text = wx.StaticText(self, wx.ID_ANY, u"x",
                                           wx.DefaultPosition, wx.DefaultSize,
                                           0)
        self.x_static_text.Wrap(-1)
        values_sizer.Add(self.x_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL, 0)

        self.x0_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                       wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.x0_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.x0_textctrl, 0, wx.ALL, 2)
        self.x0_textctrl.Bind(wx.EVT_TEXT, self.x0_textctrl_changed)
        self.x0_textctrl.Bind(wx.EVT_TEXT_ENTER, self.x0_textctrl_entered)

        self.xsize_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                          wx.DefaultPosition, wx.DefaultSize,
                                          wx.TE_PROCESS_ENTER)
        self.xsize_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.xsize_textctrl, 0, wx.ALL, 2)
        self.xsize_textctrl.Bind(wx.EVT_TEXT, self.xsize_textctrl_changed)
        self.xsize_textctrl.Bind(wx.EVT_TEXT_ENTER,
                                 self.xsize_textctrl_entered)

        self.x1_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                       wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.x1_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.x1_textctrl, 0, wx.ALL, 2)
        self.x1_textctrl.Bind(wx.EVT_TEXT, self.x1_textctrl_changed)
        self.x1_textctrl.Bind(wx.EVT_TEXT_ENTER, self.x1_textctrl_entered)

        self.npix_static_text = wx.StaticText(self, wx.ID_ANY, u"# pixels",
                                              wx.DefaultPosition,
                                              wx.DefaultSize, 0)
        self.npix_static_text.Wrap(-1)
        values_sizer.Add(self.npix_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_BOTTOM,
                         0)

        self.y_static_text = wx.StaticText(self, wx.ID_ANY, u"y",
                                           wx.DefaultPosition, wx.DefaultSize,
                                           0)
        self.y_static_text.Wrap(-1)
        values_sizer.Add(self.y_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL, 0)

        self.y0_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                       wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.y0_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.y0_textctrl, 0, wx.ALL, 2)
        self.y0_textctrl.Bind(wx.EVT_TEXT, self.y0_textctrl_changed)
        self.y0_textctrl.Bind(wx.EVT_TEXT_ENTER, self.y0_textctrl_entered)

        self.ysize_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                          wx.DefaultPosition, wx.DefaultSize,
                                          wx.TE_PROCESS_ENTER)
        self.ysize_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.ysize_textctrl, 0, wx.ALL, 2)
        self.ysize_textctrl.Bind(wx.EVT_TEXT, self.ysize_textctrl_changed)
        self.ysize_textctrl.Bind(wx.EVT_TEXT_ENTER,
                                 self.ysize_textctrl_entered)

        self.y1_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                       wx.DefaultPosition, wx.DefaultSize,
                                       wx.TE_PROCESS_ENTER)
        self.y1_textctrl.SetFont(self.textentry_font)
        values_sizer.Add(self.y1_textctrl, 0, wx.ALL, 2)
        self.y1_textctrl.Bind(wx.EVT_TEXT, self.y1_textctrl_changed)
        self.y1_textctrl.Bind(wx.EVT_TEXT_ENTER, self.y1_textctrl_entered)

        self.npix_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                         wx.DefaultPosition, wx.DefaultSize,
                                         wx.TE_READONLY)
        self.npix_textctrl.SetFont(self.textentry_font)
        self.npix_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.npix_textctrl, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, 0)

        values_sizer.AddSpacer((0, 15), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        self.median_static_text = wx.StaticText(self, wx.ID_ANY, u"Median",
                                                wx.DefaultPosition,
                                                wx.DefaultSize, 0)
        self.median_static_text.Wrap(-1)
        values_sizer.Add(self.median_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        self.median_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.median_textctrl.SetFont(self.textentry_font)
        self.median_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.median_textctrl, 0, wx.ALL, 2)
        self.robust_static_text = wx.StaticText(self, wx.ID_ANY, u"Robust",
                                                wx.DefaultPosition,
                                                wx.DefaultSize, 0)
        self.robust_static_text.Wrap(-1)
        values_sizer.Add(self.robust_static_text, 0,
                         wx.ALL | wx.ALIGN_BOTTOM | wx.ALIGN_CENTER_HORIZONTAL,
                         0)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        self.mean_static_text = wx.StaticText(self, wx.ID_ANY, u"Mean",
                                              wx.DefaultPosition,
                                              wx.DefaultSize, 0)
        self.mean_static_text.Wrap(-1)
        values_sizer.Add(self.mean_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        self.mean_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                         wx.DefaultPosition, wx.DefaultSize,
                                         wx.TE_READONLY)
        self.mean_textctrl.SetFont(self.textentry_font)
        self.mean_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.mean_textctrl, 0, wx.ALL, 2)
        self.robust_mean_textctrl = wx.TextCtrl(self, wx.ID_ANY,
                                                wx.EmptyString,
                                                wx.DefaultPosition,
                                                wx.DefaultSize, wx.TE_READONLY)
        self.robust_mean_textctrl.SetFont(self.textentry_font)
        self.robust_mean_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.robust_mean_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        self.stdev_static_text = wx.StaticText(self, wx.ID_ANY, u"Stdev",
                                               wx.DefaultPosition,
                                               wx.DefaultSize, 0)
        self.stdev_static_text.Wrap(-1)
        values_sizer.Add(self.stdev_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        self.stdev_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                          wx.DefaultPosition, wx.DefaultSize,
                                          wx.TE_READONLY)
        self.stdev_textctrl.SetFont(self.textentry_font)
        self.stdev_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.stdev_textctrl, 0, wx.ALL, 2)
        self.robust_stdev_textctrl = wx.TextCtrl(self, wx.ID_ANY,
                                                 wx.EmptyString,
                                                 wx.DefaultPosition,
                                                 wx.DefaultSize,
                                                 wx.TE_READONLY)
        self.robust_stdev_textctrl.SetFont(self.textentry_font)
        self.robust_stdev_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.robust_stdev_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 15), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        self.min_static_text = wx.StaticText(self, wx.ID_ANY, u"Min",
                                             wx.DefaultPosition,
                                             wx.DefaultSize, 0)
        self.min_static_text.Wrap(-1)
        values_sizer.Add(self.min_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        self.minval_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.minval_textctrl.SetFont(self.textentry_font)
        self.minval_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.minval_textctrl, 0, wx.ALL, 2)
        self.minpos_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.minpos_textctrl.SetFont(self.textentry_font)
        self.minpos_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.minpos_textctrl, 0, wx.ALL, 2)
        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)

        values_sizer.AddSpacer((0, 0), 0, wx.EXPAND)
        self.max_static_text = wx.StaticText(self, wx.ID_ANY, u"Max",
                                             wx.DefaultPosition,
                                             wx.DefaultSize, 0)
        self.max_static_text.Wrap(-1)
        values_sizer.Add(self.max_static_text, 0,
                         wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 0)
        self.maxval_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.maxval_textctrl.SetFont(self.textentry_font)
        self.maxval_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.maxval_textctrl, 0, wx.ALL, 2)
        self.maxpos_textctrl = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString,
                                           wx.DefaultPosition, wx.DefaultSize,
                                           wx.TE_READONLY)
        self.maxpos_textctrl.SetFont(self.textentry_font)
        self.maxpos_textctrl.SetBackgroundColour(
            textctrl_output_only_background_color)
        values_sizer.Add(self.maxpos_textctrl, 0, wx.ALL, 2)

        self.hideshow_button = wx.Button(self, wx.ID_ANY, u"Show",
                                         wx.DefaultPosition, wx.DefaultSize, 0)
        values_sizer.Add(
            self.hideshow_button, 0,
            wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 2)
        self.hideshow_button.Bind(wx.EVT_BUTTON, self.on_hideshow_button)

        v_sizer1 = wx.BoxSizer(wx.VERTICAL)
        v_sizer1.AddStretchSpacer(1.0)
        v_sizer1.Add(values_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL)
        v_sizer1.AddStretchSpacer(1.0)
        self.SetSizer(v_sizer1)
        pub.subscribe(self.queue_update_stats, 'recalc-display-image-called')
        pub.subscribe(self._set_stats_box_parameters,
                      'set-stats-box-parameters')
        pub.subscribe(self.publish_stats_to_stream, 'get-stats-box-info')

    def publish_stats_to_stream(self, msg=None):
        wx.CallAfter(send_to_stream, sys.stdout,
                     ('stats-box-info', self.stats_info))

    def on_button_press(self, event):
        self.select_panel()
        self.update_stats_box(event.xdata, event.ydata, event.xdata,
                              event.ydata)
        self.redraw_overplot_on_image()
        self.cursor_stats_box_x0, self.cursor_stats_box_y0 = event.xdata, event.ydata

    def on_motion(self, event):
        if event.button is not None:
            self.update_stats_box(self.cursor_stats_box_x0,
                                  self.cursor_stats_box_y0, event.xdata,
                                  event.ydata)
            self.redraw_overplot_on_image()
            self.update_stats()

    def on_button_release(self, event):
        self.redraw_overplot_on_image()
        self.update_stats()

    def set_cursor_to_stats_box_mode(self, event):
        self.ztv_frame.primary_image_panel.cursor_mode = 'Stats box'
        self.ztv_frame.stats_panel.select_panel()
        self.ztv_frame.stats_panel.highlight_panel()

    def queue_update_stats(self, msg=None):
        """
        wrapper to call update_stats from CallAfter in order to make GUI as responsive as possible.
        """
        wx.CallAfter(self.update_stats, msg=None)

    def _set_stats_box_parameters(self, msg):
        """
        wrapper to update_stats_box to receive messages & translate them correctly
        """
        x0, x1, y0, y1 = [None] * 4
        if msg['xrange'] is not None:
            x0, x1 = msg['xrange']
        if msg['yrange'] is not None:
            y0, y1 = msg['yrange']
        if msg['xrange'] is not None or msg['yrange'] is not None:
            self.update_stats_box(x0, y0, x1, y1)
        if msg['show_overplot'] is not None:
            if msg['show_overplot']:
                self.redraw_overplot_on_image()
            else:
                self.remove_overplot_on_image()
        send_to_stream(sys.stdout, ('set-stats-box-parameters-done', True))

    def update_stats_box(self, x0=None, y0=None, x1=None, y1=None):
        if x0 is None:
            x0 = self.stats_rect.get_x()
        if y0 is None:
            y0 = self.stats_rect.get_y()
        if x1 is None:
            x1 = self.stats_rect.get_x() + self.stats_rect.get_width()
        if y1 is None:
            y1 = self.stats_rect.get_y() + self.stats_rect.get_height()
        if x0 > x1:
            x0, x1 = x1, x0
        if y0 > y1:
            y0, y1 = y1, y0
        x0 = min(max(0, x0), self.ztv_frame.display_image.shape[1] - 1)
        y0 = min(max(0, y0), self.ztv_frame.display_image.shape[0] - 1)
        x1 = min(max(0, x1), self.ztv_frame.display_image.shape[1] - 1)
        y1 = min(max(0, y1), self.ztv_frame.display_image.shape[0] - 1)
        self.stats_rect.set_bounds(x0, y0, x1 - x0, y1 - y0)
        if self.hideshow_button.GetLabel() == 'Hide':
            self.ztv_frame.primary_image_panel.figure.canvas.draw()
        self.update_stats()

    def remove_overplot_on_image(self):
        self.ztv_frame.primary_image_panel.remove_patch(
            'stats_panel:stats_rect')
        self.hideshow_button.SetLabel(u"Show")

    def redraw_overplot_on_image(self):
        self.ztv_frame.primary_image_panel.add_patch('stats_panel:stats_rect',
                                                     self.stats_rect)
        self.hideshow_button.SetLabel(u"Hide")

    def on_hideshow_button(self, evt):
        if self.hideshow_button.GetLabel() == 'Hide':
            self.remove_overplot_on_image()
        else:
            self.redraw_overplot_on_image()

    def get_x0y0x1y1_from_stats_rect(self):
        x0 = self.stats_rect.get_x()
        y0 = self.stats_rect.get_y()
        x1 = x0 + self.stats_rect.get_width()
        y1 = y0 + self.stats_rect.get_height()
        return x0, y0, x1, y1

    def update_stats(self, msg=None):
        x0, y0, x1, y1 = self.get_x0y0x1y1_from_stats_rect()
        x0, y0 = int(np.round(x0)), int(np.round(y0))
        x1, y1 = int(np.round(x1)), int(np.round(y1))
        self.last_string_values['x0'] = str(int(x0))
        self.x0_textctrl.SetValue(self.last_string_values['x0'])
        self.last_string_values['y0'] = str(int(y0))
        self.y0_textctrl.SetValue(self.last_string_values['y0'])

        x_npix = int(x1 - x0 + 1)
        self.last_string_values['xsize'] = str(x_npix)
        self.xsize_textctrl.SetValue(self.last_string_values['xsize'])
        y_npix = int(y1 - y0 + 1)
        self.last_string_values['ysize'] = str(y_npix)
        self.ysize_textctrl.SetValue(self.last_string_values['ysize'])

        self.last_string_values['x1'] = str(int(x1))
        self.x1_textctrl.SetValue(self.last_string_values['x1'])
        self.last_string_values['y1'] = str(int(y1))
        self.y1_textctrl.SetValue(self.last_string_values['y1'])

        self.npix_textctrl.SetValue(str(x_npix * y_npix))

        stats_data = self.ztv_frame.display_image[y0:y1 + 1, x0:x1 + 1]
        finite_mask = np.isfinite(stats_data)
        if finite_mask.max() is np.True_:
            stats_data_mean = stats_data[finite_mask].mean()
            stats_data_median = np.median(stats_data[finite_mask])
            stats_data_std = stats_data[finite_mask].std()
            robust_mean, robust_median, robust_std = sigma_clipped_stats(
                stats_data[finite_mask])
        else:
            stats_data_mean = np.nan
            stats_data_median = np.nan
            stats_data_std = np.inf
            robust_mean, robust_median, robust_std = np.nan, np.nan, np.inf
        self.stats_info = {
            'xrange': [x0, x1],
            'yrange': [y0, y1],
            'mean': stats_data_mean,
            'median': stats_data_median,
            'std': stats_data_std,
            'min': stats_data.min(),
            'max': stats_data.max()
        }  # want min/max to reflect any Inf/NaN
        self.mean_textctrl.SetValue("{:0.4g}".format(self.stats_info['mean']))
        self.median_textctrl.SetValue("{:0.4g}".format(
            self.stats_info['median']))
        self.stdev_textctrl.SetValue("{:0.4g}".format(self.stats_info['std']))
        self.stats_info['robust-mean'] = robust_mean
        self.stats_info['robust-median'] = robust_median
        self.stats_info['robust-std'] = robust_std
        self.robust_mean_textctrl.SetValue("{:0.4g}".format(robust_mean))
        self.robust_stdev_textctrl.SetValue("{:0.4g}".format(robust_std))
        self.minval_textctrl.SetValue("{:0.4g}".format(self.stats_info['min']))
        self.maxval_textctrl.SetValue("{:0.4g}".format(self.stats_info['max']))
        wmin = np.where(stats_data == stats_data.min())
        wmin = [(wmin[1][i] + x0, wmin[0][i] + y0)
                for i in np.arange(wmin[0].size)]
        if len(wmin) == 1:
            wmin = wmin[0]
        self.minpos_textctrl.SetValue("{}".format(wmin))
        self.stats_info['wmin'] = wmin
        wmax = np.where(stats_data == stats_data.max())
        wmax = [(wmax[1][i] + x0, wmax[0][i] + y0)
                for i in np.arange(wmax[0].size)]
        if len(wmax) == 1:
            wmax = wmax[0]
        self.maxpos_textctrl.SetValue("{}".format(wmax))
        self.stats_info['wmax'] = wmax
        set_textctrl_background_color(self.x0_textctrl, 'ok')
        set_textctrl_background_color(self.x1_textctrl, 'ok')
        set_textctrl_background_color(self.xsize_textctrl, 'ok')
        set_textctrl_background_color(self.y0_textctrl, 'ok')
        set_textctrl_background_color(self.y1_textctrl, 'ok')
        set_textctrl_background_color(self.ysize_textctrl, 'ok')

    def x0_textctrl_changed(self, evt):
        validate_textctrl_str(self.x0_textctrl, int,
                              self.last_string_values['x0'])

    def x0_textctrl_entered(self, evt):
        if validate_textctrl_str(self.x0_textctrl, int,
                                 self.last_string_values['x0']):
            self.last_string_values['x0'] = self.x0_textctrl.GetValue()
            self.update_stats_box(int(self.last_string_values['x0']), None,
                                  None, None)
            self.x0_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def xsize_textctrl_changed(self, evt):
        validate_textctrl_str(self.xsize_textctrl, int,
                              self.last_string_values['xsize'])

    def xsize_textctrl_entered(self, evt):
        if validate_textctrl_str(self.xsize_textctrl, int,
                                 self.last_string_values['xsize']):
            self.last_string_values['xsize'] = self.xsize_textctrl.GetValue()
            xsize = int(self.last_string_values['xsize'])
            sys.stderr.write("\n\nxsize = {}\n\n".format(xsize))
            x0, y0, x1, y1 = self.get_x0y0x1y1_from_stats_rect()
            xc = (x0 + x1) / 2.
            x0 = max(0, int(xc - xsize / 2.))
            x1 = x0 + xsize - 1
            x1 = min(x1, self.ztv_frame.display_image.shape[1] - 1)
            x0 = x1 - xsize + 1
            x0 = max(0, int(xc - xsize / 2.))
            self.update_stats_box(x0, y0, x1, y1)
            self.xsize_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def x1_textctrl_changed(self, evt):
        validate_textctrl_str(self.x1_textctrl, int,
                              self.last_string_values['x1'])

    def x1_textctrl_entered(self, evt):
        if validate_textctrl_str(self.x1_textctrl, int,
                                 self.last_string_values['x1']):
            self.last_string_values['x1'] = self.x1_textctrl.GetValue()
            self.update_stats_box(None, None,
                                  int(self.last_string_values['x1']), None)
            self.x1_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def y0_textctrl_changed(self, evt):
        validate_textctrl_str(self.y0_textctrl, int,
                              self.last_string_values['y0'])

    def y0_textctrl_entered(self, evt):
        if validate_textctrl_str(self.y0_textctrl, int,
                                 self.last_string_values['y0']):
            self.last_string_values['y0'] = self.y0_textctrl.GetValue()
            self.update_stats_box(None, int(self.last_string_values['y0']),
                                  None, None)
            self.y0_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def ysize_textctrl_changed(self, evt):
        validate_textctrl_str(self.ysize_textctrl, int,
                              self.last_string_values['ysize'])

    def ysize_textctrl_entered(self, evt):
        if validate_textctrl_str(self.ysize_textctrl, int,
                                 self.last_string_values['ysize']):
            self.last_string_values['ysize'] = self.ysize_textctrl.GetValue()
            ysize = int(self.last_string_values['ysize'])
            x0, y0, x1, y1 = self.get_x0y0x1y1_from_stats_rect()
            yc = (y0 + y1) / 2.
            y0 = max(0, int(yc - ysize / 2.))
            y1 = y0 + ysize - 1
            y1 = min(y1, self.ztv_frame.display_image.shape[0] - 1)
            y0 = y1 - ysize + 1
            y0 = max(0, int(yc - ysize / 2.))
            self.update_stats_box(x0, y0, x1, y1)
            self.ysize_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()

    def y1_textctrl_changed(self, evt):
        validate_textctrl_str(self.y1_textctrl, int,
                              self.last_string_values['y1'])

    def y1_textctrl_entered(self, evt):
        if validate_textctrl_str(self.y1_textctrl, int,
                                 self.last_string_values['y1']):
            self.last_string_values['y1'] = self.y1_textctrl.GetValue()
            self.update_stats_box(None, None, None,
                                  int(self.last_string_values['y1']))
            self.y1_textctrl.SetSelection(-1, -1)
            self.redraw_overplot_on_image()
class EditableRectangle:

    _angle = 0

    def __init__(self, ax):
        self.ax = ax

        # Set up main rectangle
        self.rect = Rectangle((0, 0), 0, 0, visible=False, transform=None, picker=True)
        self.ax.add_patch(self.rect)

        # Set up anchors
        self.anchors = []
        for i in range(len(RECTANGLE_ANCHOR_LOCS)):
            anchor = Rectangle((0, 0), ANCHOR_SIZE, ANCHOR_SIZE, visible=False, transform=None, facecolor='red', picker=True)
            self.anchors.append(anchor)
            self.ax.add_patch(anchor)

        self.press = None
        self.mode = None
        self.connect()

    def connect(self):
        self.cid_press = self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press)
        self.cid_release = self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release)
        self.cid_motion = self.ax.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
        self.cid_pick = self.ax.figure.canvas.mpl_connect('pick_event', self.on_pick)

    def on_pick(self, event):
        if event.artist in self.anchors:
            if event.mouseevent.key == 'r':
                self.mode = 'anchor-rotate'
                self.center_x = self.x0 + self.width * 0.5
                self.center_y = self.y0 + self.height * 0.5
                self.angle_start = self.angle
                self.angle_drag_start = np.degrees(np.arctan2(event.mouseevent.y - self.center_y, event.mouseevent.x - self.center_x))
                print(self.angle_start)
            else:
                self.mode = 'anchor-drag'
                anchor_index = self.anchors.index(event.artist)
                self.active_anchor_index = anchor_index
            self.press = True
        elif event.artist is self.rect:
            self.mode = 'rectangle-drag'
            self.drag_start_x0 = self.x0
            self.drag_start_y0 = self.y0
            self.drag_start_x = event.mouseevent.x
            self.drag_start_y = event.mouseevent.y
            self.press = True

    def on_press(self, event):

        if event.inaxes != self.ax:
            return

        if self.mode == 'create':
            self.x0 = event.x
            self.y0 = event.y
            self.rect.set_visible(True)
            self.press = True

        # contains, attrd = self.rect.contains(event)
        # if not contains: return
        # print('event contains', self.rect.xy)
        # x0, y0 = self.rect.xy
        # self.press = x0, y0, event.x, event.y

    @property
    def angle(self):
        return self._angle

    @angle.setter
    def angle(self, value):
        self._angle = value
        self.rect.angle = value
        self.rect._update_patch_transform()

    @property
    def x0(self):
        return self.rect.get_x()

    @x0.setter
    def x0(self, value):
        self.rect.set_x(value)

    @property
    def y0(self):
        return self.rect.get_y()

    @y0.setter
    def y0(self, value):
        self.rect.set_y(value)

    @property
    def width(self):
        return self.rect.get_width()

    @width.setter
    def width(self, value):
        self.rect.set_width(value)

    @property
    def height(self):
        return self.rect.get_height()

    @height.setter
    def height(self, value):
        self.rect.set_height(value)

    def on_motion(self, event):

        if self.press is None:
            return

        if event.inaxes != self.ax:
            return

        if self.mode == 'create':

            self.width = event.x - self.x0
            self.height = event.y - self.y0

            self.rect.figure.canvas.draw()

        elif self.mode == 'rectangle-drag':

            self.x0 = self.drag_start_x0 + event.x - self.drag_start_x
            self.y0 = self.drag_start_y0 + event.y - self.drag_start_y

            self.update_anchors()

            self.rect.figure.canvas.draw()

        elif self.mode == 'anchor-drag':

            px, py = RECTANGLE_ANCHOR_LOCS[self.active_anchor_index]

            if px == -1:
                self.x0, self.width = event.x, self.x0 + self.width - event.x
            elif px == 1:
                self.width = event.x - self.x0

            if py == -1:
                self.y0, self.height = event.y, self.y0 + self.height - event.y
            elif py == 1:
                self.height = event.y - self.y0

            self.update_anchors()

            self.rect.figure.canvas.draw()

        elif self.mode == 'anchor-rotate':

            angle_current = np.degrees(np.arctan2(event.y - self.center_y, event.x - self.center_x))

            self.angle = self.angle_start + (angle_current - self.angle_drag_start)

            self.update_anchors()

            self.rect.figure.canvas.draw()

    def on_release(self, event):
        if self.mode == 'create':
            self.update_anchors()
            self.set_anchor_visibility(True)
        self.press = None
        self.mode = None
        self.rect.figure.canvas.draw()

    def set_anchor_visibility(self, visible):
        for anchor in self.anchors:
            anchor.set_visible(visible)

    def update_anchors(self):
        for anchor, (dx, dy) in zip(self.anchors, RECTANGLE_ANCHOR_LOCS):
            xc = self.x0 + 0.5 * self.width
            yc = self.y0 + 0.5 * self.height
            dx = 0.5 * (dx * self.width - ANCHOR_SIZE)
            dy = 0.5 * (dy * self.height - ANCHOR_SIZE)
            dxr = dx * np.cos(np.radians(self.angle)) - dy * np.sin(np.radians(self.angle))
            dyr = dx * np.sin(np.radians(self.angle)) + dy * np.cos(np.radians(self.angle))
            anchor.set_xy((xc + dxr, yc + dyr))

    def disconnect(self):
        self.ax.figure.canvas.mpl_disconnect(self.cid_press)
        self.ax.figure.canvas.mpl_disconnect(self.cid_release)
        self.ax.figure.canvas.mpl_disconnect(self.cid_motion)
Exemple #12
0
class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.scroll = QtWidgets.QScrollArea(self)
        self.scroll.setParent(None)
        #self.fig =Figure(tight_layout=True)
        self.fig = Figure()
        left = 0.0
        bottom = 0.0
        width = 1
        height = 1
        self.fig.add_axes([left, bottom, width, height])
        self.canvas = FigureCanvas(self.fig)
        self.fig.set_facecolor([0.23, 0.23, 0.23, 0.5])
        self.canvas.axes = self.canvas.figure.gca()

        #self.canvas.figure.tight_layout(pad=0)
        self.vertical_layout = QVBoxLayout()
        self.vertical_layout.addWidget(self.canvas)
        self.mpl_toolbar = my_toolbar(self.canvas, self)
        self.mpl_toolbar.setParentClass(self)
        self.mpl_toolbar.setMinimumWidth(100)

        self.mpl_toolbar.setFixedHeight(26)
        self.mpl_toolbar.setStyleSheet(
            "QToolBar { opacity: 1;border: 0px; background-color: rgb(133, 196, 65); border-bottom: 1px solid #19232D;padding: 2px;  font-weight: bold;spacing: 2px; } "
        )
        self.mpl_toolbar.setObjectName("myToolBar")

        #self.canvas.mpl_connect("resize_event", self.resize)
        self.vertical_layout.addWidget(self.mpl_toolbar)
        self.setLayout(self.vertical_layout)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().setSpacing(0)
        self.rect = Rectangle((0, 0), 1, 1)
        self.updateSecondImage = None
        self.patchesTotal = 0
        self.typeOfAnnotation = "autoDetcted"
        self.frameAtString = "Frame 0"
        self.currentSelectedOption = None

        self.AllBoxListDictionary = {
            "eraseBox": [],
            "oneWormLive": [],
            "multiWormLive": [],
            "oneWormDead": [],
            "multiWormDead": [],
            "miscBoxes": [],
            "autoDetcted": []
        }

        self.eraseBoxXYValues = self.AllBoxListDictionary["eraseBox"]
        self.addBoxXYValues = self.AllBoxListDictionary["miscBoxes"]
        self.oneWormLiveBoxXYValues = self.AllBoxListDictionary["oneWormLive"]
        self.multiWormLiveBoxXYValues = self.AllBoxListDictionary[
            "multiWormLive"]
        self.oneWormDeadBoxXYValues = self.AllBoxListDictionary["oneWormDead"]
        self.multiWormDeadBoxXYValues = self.AllBoxListDictionary[
            "multiWormDead"]
        self.autoDetectedBoxXYValues = self.AllBoxListDictionary["autoDetcted"]
        self.tempList = []

    def resetAllBoxListDictionary(self):
        self.AllBoxListDictionary = {
            "eraseBox": [],
            "oneWormLive": [],
            "multiWormLive": [],
            "oneWormDead": [],
            "multiWormDead": [],
            "miscBoxes": [],
            "autoDetcted": []
        }

    def updateAllBoxListDictionary(self):
        self.AllBoxListDictionary["eraseBox"] = self.eraseBoxXYValues
        self.AllBoxListDictionary["miscBoxes"] = self.addBoxXYValues
        self.AllBoxListDictionary["oneWormLive"] = self.oneWormLiveBoxXYValues
        self.AllBoxListDictionary[
            "multiWormLive"] = self.multiWormLiveBoxXYValues
        self.AllBoxListDictionary["oneWormDead"] = self.oneWormDeadBoxXYValues
        self.AllBoxListDictionary[
            "multiWormDead"] = self.multiWormDeadBoxXYValues
        self.AllBoxListDictionary["autoDetcted"] = self.autoDetectedBoxXYValues

    def updateAllListFromAllBoxListDictionary(self):
        self.eraseBoxXYValues = self.AllBoxListDictionary["eraseBox"]
        self.addBoxXYValues = self.AllBoxListDictionary["miscBoxes"]
        self.oneWormLiveBoxXYValues = self.AllBoxListDictionary["oneWormLive"]
        self.multiWormLiveBoxXYValues = self.AllBoxListDictionary[
            "multiWormLive"]
        self.oneWormDeadBoxXYValues = self.AllBoxListDictionary["oneWormDead"]
        self.multiWormDeadBoxXYValues = self.AllBoxListDictionary[
            "multiWormDead"]
        self.autoDetectedBoxXYValues = self.AllBoxListDictionary["autoDetcted"]

    def setFrameAtString(self, text):
        self.frameAtString = text

    def getFrameAtString(self):
        return self.frameAtString

    def getCurrentSelectedOption(self):
        return self.currentSelectedOption

    def setCurrentSelectedOption(self, option):
        self.currentSelectedOption = option

    def setDarkTheme(self):
        self.mpl_toolbar.setStyleSheet(
            "QToolBar#myToolBar{ border: 0px; background-color: rgb(133, 0,s 65); border-bottom: 1px solid #19232D;padding: 2px;  font-weight: bold;spacing: 2px; } "
        )
        self.fig.set_facecolor([0.23, 0.23, 0.23, 0.5])
        #self.fig.set_facecolor('grey')
        self.canvas.draw()

    def setGreenTheme(self):
        self.mpl_toolbar.setStyleSheet(
            "QToolBar { border: 0px; background-color: rgb(133, 196, 65); border-bottom: 1px solid #19232D;padding: 2px;  font-weight: bold;spacing: 2px; } "
        )
        self.fig.set_facecolor('grey')
        self.canvas.draw()

    def setTypeOfAnnotation(self, text):
        self.typeOfAnnotation = text

    def restrictCanvasMinimumSize(self, size):
        self.canvas.setMinimumSize(size)

    def unmountWidgetAndClear(self):
        self.vertical_layout.removeWidget(self.canvas)
        self.vertical_layout.removeWidget(self.scroll)
        self.scroll.setParent(None)
        self.canvas.setParent(None)
        sip.delete(self.scroll)
        del self.canvas
        self.scroll = None
        self.canvas = None
        self.canvas = FigureCanvas(Figure())
        self.canvas.axes = self.canvas.figure.gca()
        #self.canvas.figure.tight_layout()
        self.scroll = QtWidgets.QScrollArea(self)
        self.scroll.setWidgetResizable(True)

    def connectClickListnerToCurrentImageForCrop(self,
                                                 givenController,
                                                 updateSecondImage=None,
                                                 listOfControllers=None,
                                                 keyForController=None):
        self.cid1 = self.canvas.mpl_connect("button_press_event",
                                            self.on_press_for_crop)
        self.cid2 = self.canvas.mpl_connect("motion_notify_event",
                                            self.onmove_for_crop)
        self.cid3 = self.canvas.mpl_connect("button_release_event",
                                            self.on_release_for_crop)
        self.givenControllerObject = givenController
        self.updateSecondImage = updateSecondImage
        self.pressevent = None
        self.listOfControllers = listOfControllers
        self.keyForController = keyForController

    def on_press_for_crop(self, event):
        if (self.mpl_toolbar.mode):
            return

        try:
            self.rect.remove()
        except:
            pass
        self.addedPatch = None
        self.x0 = event.xdata
        self.y0 = event.ydata
        self.rect = Rectangle((self.x0, self.y0), 1, 1)
        self.rect._alpha = 0.5
        self.rect._linewidth = 2
        self.rect.set_color("C2")
        self.rect.set
        self.pressevent = 1
        self.addedPatch = self.canvas.axes.add_patch(self.rect)

    def on_release_for_crop(self, event):
        if (self.mpl_toolbar.mode):
            return

        self.pressevent = None

        minMaxVertices = [
            int(np.ceil(min(self.x0, self.x1))),
            int(np.ceil(min(self.y0, self.y1))),
            int(np.round(max(self.x0, self.x1))),
            int(np.round(max(self.y0, self.y1))),
        ]
        self.givenControllerObject.updateManualCropCoordinates(minMaxVertices)
        image = self.givenControllerObject.showManualCropImage()
        self.canvas.axes.clear()
        self.canvas.axes.axis("off")
        self.canvas.axes.imshow(image)
        self.canvas.draw()
        if self.updateSecondImage is not None:
            self.updateSecondImage.canvas.axes.clear()
            self.updateSecondImage.canvas.axes.axis("off")
            self.updateSecondImage.canvas.axes.imshow(
                self.givenControllerObject.getCroppedImage(0))
            self.updateSecondImage.canvas.draw()
            self.listOfControllers[
                self.keyForController] = self.givenControllerObject

    def onmove_for_crop(self, event):

        if self.pressevent is None:
            return
        self.x1 = event.xdata
        self.y1 = event.ydata
        self.rect.set_width(self.x1 - self.x0)
        self.rect.set_height(self.y1 - self.y0)
        self.rect.set_xy((self.x0, self.y0))
        self.canvas.draw()

    def disconnectClickListnerFromCurrentImageForCrop(self):
        try:
            self.canvas.mpl_disconnect(self.cid1)
            self.canvas.mpl_disconnect(self.cid2)
            self.canvas.mpl_disconnect(self.cid3)
            self.updateSecondImage = None
        except:
            pass

    def getCurrentScrollParam(self):
        self.currentVerticalSliderValue = self.scroll.verticalScrollBar(
        ).value()
        self.currentHorizontalSliderValue = self.scroll.horizontalScrollBar(
        ).value()

    def resetCurrentScrollParam(self):
        self.scroll.verticalScrollBar().setValue(
            self.currentVerticalSliderValue)
        self.scroll.horizontalScrollBar().setValue(
            self.currentHorizontalSliderValue)

    def resize(self, event):
        # on resize reposition the navigation toolbar to (0,0) of the axes.
        x, y = self.fig.axes[0].transAxes.transform((0, 0))
        figw, figh = self.fig.get_size_inches()
        ynew = figh * self.fig.dpi - y - self.mpl_toolbar.frameGeometry(
        ).height()
        self.mpl_toolbar.move(x, ynew)

    def connectClickListnerToCurrentImageForAnnotate(self,
                                                     givenController,
                                                     updateSecondImage=None):
        self.cid4 = self.canvas.mpl_connect("button_press_event",
                                            self.on_press_for_annotate)

        self.cid7 = self.canvas.mpl_connect('pick_event', self.onpick)
        #self.cid7 = self.canvas.mpl_connect('button_press_event', self.right_click_press_for_annotate)
        self.givenControllerObject = givenController
        self.updateSecondImage = updateSecondImage
        self.pressevent = None

    def autoAnnotateOnOverlay(self, autoDetectedObjects):

        for index, row in autoDetectedObjects.iterrows():
            print(row.bbox3)

            #if self.pressevent is None:
            #    return
            #self.x1 = event.xdata
            #self.y1 = event.ydata
            self.rect.set_width(row.bbox3 - row.bbox1)
            self.rect.set_height(row.bbox2 - row.bbox0)
            self.rect.set_xy((row.bbox1, row.bbox0))

            self.canvas.draw()

            self.rect = Rectangle((row.bbox1, row.bbox0), 1, 1, picker=True)
            self.rect._alpha = 1
            self.rect._edgecolor = (0, 1, 0, 1)
            self.rect._facecolor = (0, 0, 0, 0)

            self.rect._linewidth = 1
            self.rect.set_linestyle('dashed')
            self.rect.addName = self.typeOfAnnotation
            self.pressevent = 1
            self.canvas.axes.add_patch(self.rect)
            self.patchesTotal = self.patchesTotal + 1

            if [row.bbox1, row.bbox0, row.bbox3,
                    row.bbox2] not in self.autoDetectedBoxXYValues:
                self.autoDetectedBoxXYValues.append(
                    [row.bbox1, row.bbox0, row.bbox3, row.bbox2])

            # Update latest values
            self.updateAllBoxListDictionary()
            #print(self.typeOfAnnotation)
            '''if self.typeOfAnnotation == "eraseBox":
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])

            if self.typeOfAnnotation not in ["eraseBox", "oneWormLive", "multiWormLive", "oneWormDead", "multiWormDead"]:
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])

            if self.typeOfAnnotation == "oneWormLive":
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])

            if self.typeOfAnnotation == "multiWormLive":
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])

            if self.typeOfAnnotation == "oneWormDead":
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])

            if self.typeOfAnnotation == "multiWormDead":
                if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                    self.tempList.append([self.x0, self.y0, self.x1, self.y1])'''

            #self.canvas.draw()

        #return(self.canvas)

    def on_press_for_annotate(self, event):
        # try:
        #     self.rect.remove()
        # except:
        #     pass
        if (self.mpl_toolbar.mode):
            return

        if event.button == 1:
            self.cid5 = self.canvas.mpl_connect("motion_notify_event",
                                                self.onmove_for_annotate)
            self.cid6 = self.canvas.mpl_connect("button_release_event",
                                                self.on_release_for_annotate)

            self.x0 = event.xdata
            self.y0 = event.ydata

            self.rect = Rectangle((self.x0, self.y0), 1, 1, picker=True)
            self.rect._alpha = 1
            if self.typeOfAnnotation not in [
                    "eraseBox", "oneWormLive", "multiWormLive", "oneWormDead",
                    "multiWormDead"
            ]:
                self.rect._edgecolor = (0, 1, 0, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "autoDetcted":
                self.rect._edgecolor = (0, 1, 0, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "eraseBox":
                self.rect._edgecolor = (0, 0, 0, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "oneWormLive":
                self.rect._edgecolor = (0, 0, 1, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "multiWormLive":
                self.rect._edgecolor = (1, 1, 0, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "oneWormDead":
                self.rect._edgecolor = (1, 0, 0, 1)
                self.rect._facecolor = (0, 0, 0, 0)
            elif self.typeOfAnnotation == "multiWormDead":
                self.rect._edgecolor = (1, 1, 1, 1)
                self.rect._facecolor = (0, 0, 0, 0)

            self.rect._linewidth = 1
            self.rect.set_linestyle('dashed')
            self.rect.addName = self.typeOfAnnotation
            self.pressevent = 1
            self.canvas.axes.add_patch(self.rect)
            self.patchesTotal = self.patchesTotal + 1

    def on_release_for_annotate(self, event):
        if (self.mpl_toolbar.mode):
            return

        if event.button == 1:
            self.canvas.mpl_disconnect(self.cid5)
            if (self.rect.get_height() == 1) and (self.rect.get_width() == 1):
                self.rect.remove()
            self.pressevent = None
            self.canvas.mpl_disconnect(self.cid6)

        if self.typeOfAnnotation == "eraseBox":
            #print(self.typeOfAnnotation)
            self.eraseBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        if self.typeOfAnnotation not in [
                "eraseBox", "oneWormLive", "multiWormLive", "oneWormDead",
                "multiWormDead"
        ]:
            #print(self.typeOfAnnotation)
            self.addBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        if self.typeOfAnnotation == "oneWormLive":
            self.oneWormLiveBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        if self.typeOfAnnotation == "multiWormLive":
            self.multiWormLiveBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        if self.typeOfAnnotation == "oneWormDead":
            self.oneWormDeadBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        if self.typeOfAnnotation == "multiWormDead":
            self.multiWormDeadBoxXYValues.append(self.tempList[-1])
            self.tempList = []

        # updateAllBoxListDictionary(self)
        self.updateAllBoxListDictionary()

        # self.givenControllerObject.updateManualCropCoordinates(minMaxVertices)
        # image = self.givenControllerObject.showManualCropImage()
        # self.canvas.axes.clear()
        # self.canvas.axes.axis("off")
        # self.canvas.axes.imshow(image)
        # self.canvas.draw()
        # if self.updateSecondImage is not None:
        #     self.updateSecondImage.canvas.axes.clear()
        #     self.updateSecondImage.canvas.axes.axis("off")
        #     self.updateSecondImage.canvas.axes.imshow(self.givenControllerObject.getCroppedImage(0))
        #     self.updateSecondImage.canvas.draw()

    def onmove_for_annotate(self, event):

        if self.pressevent is None:
            return
        self.x1 = event.xdata
        self.y1 = event.ydata
        self.rect.set_width(self.x1 - self.x0)
        self.rect.set_height(self.y1 - self.y0)
        self.rect.set_xy((self.x0, self.y0))

        #print(self.typeOfAnnotation)
        if self.typeOfAnnotation == "eraseBox":
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        if self.typeOfAnnotation not in [
                "eraseBox", "oneWormLive", "multiWormLive", "oneWormDead",
                "multiWormDead"
        ]:
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        if self.typeOfAnnotation == "oneWormLive":
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        if self.typeOfAnnotation == "multiWormLive":
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        if self.typeOfAnnotation == "oneWormDead":
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        if self.typeOfAnnotation == "multiWormDead":
            if [self.x0, self.y0, self.x1, self.y1] not in self.tempList:
                self.tempList.append([self.x0, self.y0, self.x1, self.y1])

        self.canvas.draw()

    def getEraseBoxXYValues(self):
        return (self.eraseBoxXYValues)

    def getAutoDetctedBoxXYValues(self):
        return (self.autoDetectedBoxXYValues)

    def getAddBoxXYValues(self):
        return (self.addBoxXYValues)

    def getOneWormLiveBoxXYValues(self):
        return (self.oneWormLiveBoxXYValues)

    def getMultiWormLiveBoxXYValues(self):
        return (self.multiWormLiveBoxXYValues)

    def getOneWormDeadBoxXYValues(self):
        return (self.oneWormDeadBoxXYValues)

    def getMultiWormDeadBoxXYValues(self):
        return (self.multiWormDeadBoxXYValues)

    def resetEraseBoxXYValues(self):
        self.eraseBoxXYValues = []

    def resetAutoDetctedBoxXYValues(self):
        self.autoDetectedBoxXYValues = []

    def resetAddBoxXYValues(self):
        self.addBoxXYValues = []

    def resetOneWormLiveBoxXYValues(self):
        self.oneWormLiveBoxXYValues = []

    def resetMultiWormLiveBoxXYValues(self):
        self.multiWormLiveBoxXYValues = []

    def resetOneWormDeadBoxXYValues(self):
        self.oneWormDeadBoxXYValues = []

    def resetMultiWormDeadBoxXYValues(self):
        self.multiWormDeadBoxXYValues = []

    def disconnectClickListnerFromCurrentImageForAnnotate(self):
        try:
            self.canvas.mpl_disconnect(self.cid4)

            self.canvas.mpl_disconnect(self.cid7)
            self.updateSecondImage = None
        except:
            pass

    def onpick(self, event):
        #if event.button == 3:       #"3" is the right button
        # print "you click the right button"
        # print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
        # event.button, event.x, event.y, event.xdata, event.ydata)
        #Get the coordinates of the mouse click
        #I create the action
        if (self.mpl_toolbar.mode):
            return
        if event.mouseevent.button == 3:
            self.objectPicked = event.artist
            noteAction_1 = QtWidgets.QAction('Delete Box', self)
            noteAction_2 = QtWidgets.QAction('Classify', self)
            #noteAction_5 = QtWidgets.QAction('Add Once',self)
            #noteAction_2 = QtWidgets.QAction('Add Through',self)
            #noteAction_3 = QtWidgets.QAction('Mask Here',self)
            #noteAction_4 = QtWidgets.QAction('Mask Through',self)
            #noteAction_6 = QtWidgets.QAction('Live here',self)
            #noteAction_7 = QtWidgets.QAction('Live all',self)
            #noteAction_8 = QtWidgets.QAction('Dead here',self)
            #noteAction_9 = QtWidgets.QAction('Dead all',self)

            #I create the context menu
            self.popMenu = QtWidgets.QMenu(self)
            self.popMenu.addAction(noteAction_1)
            self.popMenu.addAction(noteAction_2)
            # self.popMenu.addAction(noteAction_2)
            # self.popMenu.addAction(noteAction_3)
            # self.popMenu.addAction(noteAction_4)
            # self.popMenu.addAction(noteAction_5)
            # self.popMenu.addAction(noteAction_6)
            # self.popMenu.addAction(noteAction_7)
            # self.popMenu.addAction(noteAction_8)
            # self.popMenu.addAction(noteAction_9)

            cursor = QtGui.QCursor()
            #self.connect(self.figure_canvas, SIGNAL("clicked()"), self.context_menu)
            #self.popMenu.exec_(self.mapToGlobal(event.globalPos()))
            noteAction_1.triggered.connect(lambda: self.removeThisArea(1))
            noteAction_2.triggered.connect(
                lambda: self.classifyAsCurrentSelection(1))
            # noteAction_2.triggered.connect(lambda :self.removeThisArea(2))
            # noteAction_3.triggered.connect(lambda :self.removeThisArea(3))
            # noteAction_4.triggered.connect(lambda :self.removeThisArea(4))
            # noteAction_5.triggered.connect(lambda :self.removeThisArea(5))
            # noteAction_6.triggered.connect(lambda :self.removeThisArea(5))
            # noteAction_7.triggered.connect(lambda :self.removeThisArea(2))
            # noteAction_8.triggered.connect(lambda :self.removeThisArea(3))
            # noteAction_9.triggered.connect(lambda :self.removeThisArea(4))

            self.popMenu.popup(cursor.pos())
        else:
            return

    def right_click_press_for_annotate(self, event):
        if (self.mpl_toolbar.mode):
            return
        if event.button == 3:  #"3" is the right button
            # print "you click the right button"
            # print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
            # event.button, event.x, event.y, event.xdata, event.ydata)
            #Get the coordinates of the mouse click
            #I create the action
            noteAction_1 = QtWidgets.QAction('Remove', self)
            noteAction_2 = QtWidgets.QAction('Add', self)

            #I create the context menu
            self.popMenu = QtWidgets.QMenu(self)
            self.popMenu.addAction(noteAction_1)
            self.popMenu.addAction(noteAction_2)
            cursor = QtGui.QCursor()

            #self.connect(self.figure_canvas, SIGNAL("clicked()"), self.context_menu)
            #self.popMenu.exec_(self.mapToGlobal(event.globalPos()))
            noteAction_1.triggered.connect(
                lambda eventData=object: self.removeThisArea(eventData))
            noteAction_2.triggered.connect(
                lambda eventData=object: self.classifyAsCurrentSelection(
                    eventData))
            self.popMenu.popup(cursor.pos())

    def classifyAsCurrentSelection(self, caseNumber):

        # Get all the list values for this frame
        self.updateAllListFromAllBoxListDictionary()

        print("INSIDE classifyAsCurrentSelection")

        try:
            if caseNumber == 1:  # green delete
                print(type(self.objectPicked))
                X0 = self.objectPicked.get_xy()[0]
                Y0 = self.objectPicked.get_xy()[1]
                X1 = X0 + self.objectPicked.get_width()
                Y1 = Y0 + self.objectPicked.get_height()

                selectedBoxCoords = [X0, Y0, X1, Y1]

                if self.currentSelectedOption == "eraseBox":
                    #self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    #self.eraseBoxXYValues.append(selectedBoxCoords)
                    print("Use Delte Option! Right Click -> Delete Box")

                if self.currentSelectedOption == "autoDetcted":
                    #self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    #self.addBoxXYValues.append(selectedBoxCoords)
                    print("Already Selected!")

                if self.currentSelectedOption not in [
                        "oneWormLive", "multiWormLive", "oneWormDead",
                        "multiWormDead", "autoDetcted"
                ]:
                    self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    self.addBoxXYValues.append(selectedBoxCoords)

                    self.rect.set_width(X1 - X0)
                    self.rect.set_height(Y1 - Y0)
                    self.rect.set_xy((X0, Y0))

                    self.rect = Rectangle((X0, Y0), 1, 1, picker=True)
                    self.rect._alpha = 1
                    self.rect._edgecolor = (0, 1, 0, 1)
                    self.rect._facecolor = (0, 0, 0, 0)

                    self.canvas.draw()

                    self.rect._linewidth = 1
                    self.rect.set_linestyle('dashed')
                    self.rect.addName = self.typeOfAnnotation
                    self.pressevent = 1
                    self.canvas.axes.add_patch(self.rect)

                if self.currentSelectedOption == "oneWormLive" and selectedBoxCoords not in self.oneWormLiveBoxXYValues:

                    self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    self.oneWormLiveBoxXYValues.append(selectedBoxCoords)

                    self.canvas.draw()

                    self.rect.set_width(X1 - X0)
                    self.rect.set_height(Y1 - Y0)
                    self.rect.set_xy((X0, Y0))

                    self.rect = Rectangle((X0, Y0), 1, 1, picker=True)
                    self.rect._alpha = 1
                    self.rect._edgecolor = (0, 0, 1, 1)
                    self.rect._facecolor = (0, 0, 0, 0)

                    self.rect._linewidth = 1
                    self.rect.set_linestyle('dashed')
                    self.rect.addName = self.typeOfAnnotation
                    self.pressevent = 1
                    self.canvas.axes.add_patch(self.rect)

                    self.canvas.draw()

                if self.currentSelectedOption == "multiWormLive" and selectedBoxCoords not in self.multiWormLiveBoxXYValues:
                    self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    self.multiWormLiveBoxXYValues.append(selectedBoxCoords)

                    self.rect.set_width(X1 - X0)
                    self.rect.set_height(Y1 - Y0)
                    self.rect.set_xy((X0, Y0))

                    self.rect = Rectangle((X0, Y0), 1, 1, picker=True)
                    self.rect._alpha = 1
                    self.rect._edgecolor = (1, 1, 0, 1)
                    self.rect._facecolor = (0, 0, 0, 0)

                    self.canvas.draw()

                    self.rect._linewidth = 1
                    self.rect.set_linestyle('dashed')
                    self.rect.addName = self.typeOfAnnotation
                    self.pressevent = 1
                    self.canvas.axes.add_patch(self.rect)

                if self.currentSelectedOption == "oneWormDead" and selectedBoxCoords not in self.oneWormDeadBoxXYValues:

                    self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    self.oneWormDeadBoxXYValues.append(selectedBoxCoords)

                    self.rect.set_width(X1 - X0)
                    self.rect.set_height(Y1 - Y0)
                    self.rect.set_xy((X0, Y0))

                    self.rect = Rectangle((X0, Y0), 1, 1, picker=True)
                    self.rect._alpha = 1
                    self.rect._edgecolor = (1, 0, 0, 1)
                    self.rect._facecolor = (0, 0, 0, 0)

                    self.canvas.draw()

                    self.rect._linewidth = 1
                    self.rect.set_linestyle('dashed')
                    self.rect.addName = self.typeOfAnnotation
                    self.pressevent = 1
                    self.canvas.axes.add_patch(self.rect)

                if self.currentSelectedOption == "multiWormDead" and selectedBoxCoords not in self.multiWormDeadBoxXYValues:
                    self.autoDetectedBoxXYValues.remove(selectedBoxCoords)
                    self.multiWormDeadBoxXYValues.append(selectedBoxCoords)

                    self.rect.set_width(X1 - X0)
                    self.rect.set_height(Y1 - Y0)
                    self.rect.set_xy((X0, Y0))

                    self.rect = Rectangle((X0, Y0), 1, 1, picker=True)
                    self.rect._alpha = 1
                    self.rect._edgecolor = (1, 1, 1, 1)
                    self.rect._facecolor = (0, 0, 0, 0)

                    self.canvas.draw()

                    self.rect._linewidth = 1
                    self.rect.set_linestyle('dashed')
                    self.rect.addName = self.typeOfAnnotation
                    self.pressevent = 1
                    self.canvas.axes.add_patch(self.rect)

        except:
            print("Delete and Redraw!")
        # updateAllBoxListDictionary(self)
        self.updateAllBoxListDictionary()

    def removeThisArea(self, caseNumber):

        # Get all the list values for this frame
        self.updateAllListFromAllBoxListDictionary()

        if caseNumber == 1:  # green delete
            print(type(self.objectPicked))
            X0 = self.objectPicked.get_xy()[0]
            Y0 = self.objectPicked.get_xy()[1]
            X1 = X0 + self.objectPicked.get_width()
            Y1 = Y0 + self.objectPicked.get_height()

            removeBoxCoords = [X0, Y0, X1, Y1]
            #print(removeBoxCoords)
            self.objectPicked.remove()
            self.patchesTotal = self.patchesTotal - 1

            try:
                if removeBoxCoords in self.eraseBoxXYValues:
                    self.eraseBoxXYValues.remove(removeBoxCoords)

                if removeBoxCoords in self.addBoxXYValues:
                    self.addBoxXYValues.remove(removeBoxCoords)

                if removeBoxCoords in self.oneWormLiveBoxXYValues:
                    #print(self.oneWormLiveBoxXYValues)
                    self.oneWormLiveBoxXYValues.remove(removeBoxCoords)
                    #print(self.oneWormLiveBoxXYValues)

                if removeBoxCoords in self.multiWormLiveBoxXYValues:
                    self.multiWormLiveBoxXYValues.remove(removeBoxCoords)

                if removeBoxCoords in self.oneWormDeadBoxXYValues:
                    self.oneWormDeadBoxXYValues.remove(removeBoxCoords)

                if removeBoxCoords in self.multiWormDeadBoxXYValues:
                    self.multiWormDeadBoxXYValues.remove(removeBoxCoords)

                if removeBoxCoords in self.autoDetectedBoxXYValues:
                    print(len(self.autoDetectedBoxXYValues))
                    self.autoDetectedBoxXYValues.remove(removeBoxCoords)
                    print(len(self.autoDetectedBoxXYValues))
            except:
                pass

        # elif caseNumber == 2:     # orange add all
        #     self.objectPicked._facecolor = (1.0, 0.64, 0.0,0.5)
        #     self.objectPicked._alpha  = 0.5
        #     self.objectPicked.addName ="addAll"
        # elif caseNumber == 3:     # black
        #     self.objectPicked._facecolor = (0,0, 0, 0.8)
        #     self.objectPicked._alpha = 0.8
        #     self.objectPicked.addName ="eraseBox"
        # elif caseNumber == 4:
        #     self.objectPicked._facecolor = ( 0, 0, 0, 0.2)
        #     self.objectPicked._alpha = 0.2
        #     self.objectPicked.addName ="deleteAll"
        # elif caseNumber == 5:
        #     self.objectPicked.set_color("C2")
        #     self._edgecolor = (0, 0, 0, 0)
        #     self.objectPicked.addName ="addBox"

        self.canvas.draw()
        #print(len(self.canvas.axes.patches))
        #self.canvas.draw()
        #self.on_release_for_annotate(None)

    def initializeAnnotationDictionary(self):
        self.currentAnnotationFrame = None
        self.annotationRecordDictionary = {}

    def updateAnnotationDictionary(self):

        # When you move away from current Frame call this
        previousFrame = self.currentAnnotationFrame
        if previousFrame is not None:
            self.annotationRecordDictionary[str(
                previousFrame)] = self.canvas.axes.patches

    def getAnnotationDictionary(self):
        return self.annotationRecordDictionary

    def applyAnnotationDictionary(self, frameNumber):
        self.currentAnnotationFrame = frameNumber
        self.canvas.axes.patches = []
        if str(frameNumber) in self.annotationRecordDictionary.keys():
            for patch in self.annotationRecordDictionary[str(frameNumber)]:
                self.canvas.axes.add_patch(patch)

    def setAnnotationDictionary(self):
        pass
Exemple #13
0
def handle_event():
    global command
    global command_meta
    global main_pic
    global history
    global patch
    global patches
    global click_handlers
    global G

    if command == "horizontal_line" or command == "vertical_line":
        h, w = main_pic.shape[:2]
        if patch is not None:
            w1, h1 = patch.get_xy()
            if command == "horizontal_line":
                line = Line(0, int(h1), w, int(h1), int(patch.get_height()),
                            magenta)
            else:
                line = Line(int(w1), 0, int(w1), h, int(patch.get_width()),
                            magenta)
            main_pic = draw_line_on_picture(main_pic, line)
            patch = None
        else:
            if command == "horizontal_line":
                patch = Rectangle((0, 0), w, 1, edgecolor='magenta', alpha=1)
            else:
                patch = Rectangle((0, 0), 1, h, edgecolor='magenta', alpha=1)

    if command == "needle" or command == "angle_needle":
        G["needle"]["active"] = True
        just_added_patch = False
        if "pt1" in G["needle"] and "pt2" in G["needle"]:
            if patch is None:
                print "Drawing needle patch"
                pt1 = G["needle"]["pt1"]
                pt2 = G["needle"]["pt2"]
                if command == "needle":
                    patch = Rectangle((pt1[0], pt1[1]),
                                      abs(pt2[0] - pt1[0]),
                                      abs(pt2[1] - pt1[1]),
                                      edgecolor='magenta',
                                      alpha=1,
                                      facecolor='magenta')
                else:
                    patch = Polygon(np.array([pt1, pt2,
                                              p(pt1), p(pt2)]),
                                    closed=False,
                                    edgecolor='magenta',
                                    alpha=1,
                                    facecolor='magenta')
                    angle = get_angle(pt1, pt2)
                    print("Angle :{}".format(angle))
                    # how to add text?
                just_added_patch = True

        if patch is not None and not just_added_patch:
            if isinstance(patch, Polygon):
                patches.append(patch)
                patch = None
            else:
                print "finalize"
                w1, h1 = patch.get_xy()
                w = patch.get_width()
                h = patch.get_height()

                if w > h:
                    print("horizontal patch")
                    line = Line(int(w1), int(h1), int(w1 + w), int(h1), 3,
                                magenta)
                else:
                    line = Line(int(w1), int(h1), int(w1), int(h1 + h), 3,
                                magenta)

                main_pic = draw_line_on_picture(main_pic, line)
            G["needle"] = {}

    if command == "divide":
        divide(command_meta.xdata, command_meta.ydata)
    if command == "brighten":
        main_pic = do_brighten(main_pic)
    if command == "mirror":
        main_pic = np.fliplr(main_pic)
    if command == "zoom":
        click_handlers = not click_handlers
    if command == "darken":
        main_pic = do_darken(main_pic)
    if command == "edge":
        main_pic = edge_detect(main_pic)
    if command == "resize_patch":
        if patch is not None:
            h = patch.get_height()
            w = patch.get_width()
            patch.set_width(int(w * 0.9))
            patch.set_height(int(h * 0.9))

    if command == "crop":
        if patch is not None:
            # apply patch
            # crop main_pic
            h = patch.get_height()
            w = patch.get_width()
            w1, h1 = patch.get_xy()
            main_pic = main_pic[slice(h1, h1 + h),
                                slice(w1, w1 + w),
                                slice(None)]
            patch = None

        else:
            # create patch
            # TODO: can read this from settings :))
            portrait_ratio = 14.8 / 20.8
            if orientation == "portrait":
                w_to_h = portrait_ratio
            else:
                w_to_h = 1.0 / portrait_ratio
            shape = main_pic.shape
            border = 15
            hp = shape[0] - border
            wp = shape[1] - border

            if w_to_h * hp > wp:
                tw = wp
                th = wp / w_to_h
            else:
                th = hp
                tw = w_to_h * hp
            print th, tw
            patch = Rectangle((0, 0),
                              tw,
                              th,
                              edgecolor='magenta',
                              alpha=1,
                              facecolor='none')
    if command == "undo":
        print "Undoing"
        print len(history)
        if len(history) >= 2:
            main_pic, cmd = history[-2]
            print cmd
            history = history[:-1]

    if command != "undo":
        history.append((np.copy(main_pic), command))
    if command not in [
            "crop", "horizontal_line", "vertical_line", "needle",
            "angle_needle", "resize_patch"
    ]:
        patch = None
    command = None
    command_meta = None
    plot(patch=patch, click_handlers=click_handlers)
    if command is not None:
        handle_event()