Ejemplo n.º 1
0
    def addItem(self, x, y, legend, shape, color, fill, overlay, z):
        xView = numpy.array(x, copy=False)
        yView = numpy.array(y, copy=False)

        if shape == "line":
            item = self.ax.plot(x, y, label=legend, color=color,
                                linestyle='-', marker=None)[0]

        elif shape == "hline":
            if hasattr(y, "__len__"):
                y = y[-1]
            item = self.ax.axhline(y, label=legend, color=color)

        elif shape == "vline":
            if hasattr(x, "__len__"):
                x = x[-1]
            item = self.ax.axvline(x, label=legend, color=color)

        elif shape == 'rectangle':
            xMin = numpy.nanmin(xView)
            xMax = numpy.nanmax(xView)
            yMin = numpy.nanmin(yView)
            yMax = numpy.nanmax(yView)
            w = xMax - xMin
            h = yMax - yMin
            item = Rectangle(xy=(xMin, yMin),
                             width=w,
                             height=h,
                             fill=False,
                             color=color)
            if fill:
                item.set_hatch('.')

            self.ax.add_patch(item)

        elif shape in ('polygon', 'polylines'):
            xView = xView.reshape(1, -1)
            yView = yView.reshape(1, -1)
            item = Polygon(numpy.vstack((xView, yView)).T,
                           closed=(shape == 'polygon'),
                           fill=False,
                           label=legend,
                           color=color)
            if fill and shape == 'polygon':
                item.set_hatch('/')

            self.ax.add_patch(item)

        else:
            raise NotImplementedError("Unsupported item shape %s" % shape)

        item.set_zorder(z)

        if overlay:
            item.set_animated(True)
            self._overlays.add(item)

        return item
Ejemplo n.º 2
0
    def addItem(self, x, y, legend, shape, color, fill, overlay, z):
        xView = numpy.array(x, copy=False)
        yView = numpy.array(y, copy=False)

        if shape == "line":
            item = self.ax.plot(x, y, label=legend, color=color,
                                linestyle='-', marker=None)[0]

        elif shape == "hline":
            if hasattr(y, "__len__"):
                y = y[-1]
            item = self.ax.axhline(y, label=legend, color=color)

        elif shape == "vline":
            if hasattr(x, "__len__"):
                x = x[-1]
            item = self.ax.axvline(x, label=legend, color=color)

        elif shape == 'rectangle':
            xMin = numpy.nanmin(xView)
            xMax = numpy.nanmax(xView)
            yMin = numpy.nanmin(yView)
            yMax = numpy.nanmax(yView)
            w = xMax - xMin
            h = yMax - yMin
            item = Rectangle(xy=(xMin, yMin),
                             width=w,
                             height=h,
                             fill=False,
                             color=color)
            if fill:
                item.set_hatch('.')

            self.ax.add_patch(item)

        elif shape in ('polygon', 'polylines'):
            xView = xView.reshape(1, -1)
            yView = yView.reshape(1, -1)
            item = Polygon(numpy.vstack((xView, yView)).T,
                           closed=(shape == 'polygon'),
                           fill=False,
                           label=legend,
                           color=color)
            if fill and shape == 'polygon':
                item.set_hatch('/')

            self.ax.add_patch(item)

        else:
            raise NotImplementedError("Unsupported item shape %s" % shape)

        item.set_zorder(z)

        if overlay:
            item.set_animated(True)
            self._overlays.add(item)

        return item
Ejemplo n.º 3
0
class RectArea:
    #because rectangle or circle were not added to figure a priori - figure and axes must be passed
    def __init__(self, fig, axes, xi, yi):
        self.width = 20
        self.height = 10
        self.x0 = xi
        self.y0 = yi
        self.edgecol = "red"
        self.r = 4
        #angle is anticlockwise
        self.angle = 0.0
        #storing the background of rectangle
        self.background = None
        #storing the backgroud of circle
        self.backgroundc = None
        #indicator of the selection of the rectangle - creating an instance makes it selected
        self.is_Recselected = True
        #indicator of the selection of circle
        self.is_Circselected = False
        self.rect = Rectangle((self.x0, self.y0),
                              self.width,
                              self.height,
                              ec=self.edgecol,
                              fill=False,
                              ls="solid")
        #upper right circle - draggable
        self.xr = self.x0 + self.width
        self.yr = self.y0 + self.height
        self.circle = Circle((self.xr, self.yr), radius=self.r)
        #circle - origin of the rectangle -> left, bottom corner of the rectangle
        self.circle_o = Circle((self.xo, self.y0), radius=self.r)
        #pressing the button on the canvas creates new rectangle - it is inside the constructor
        canvas = fig.canvas
        axes = axes
        self.rect.set_animated(True)
        self.circle.set_animated(True)
        canvas.draw()
        self.background = canvas.copy_from_bbox(axes.bbox)
        axes.draw_artist(self.rect)
        axes.draw_artist(self.circle)
        canvas.blit(axes.bbox)
Ejemplo n.º 4
0
    def addItem(self, x, y, shape, color, fill, overlay, z,
                linestyle, linewidth, linebgcolor):
        if (linebgcolor is not None and
                shape not in ('rectangle', 'polygon', 'polylines')):
            _logger.warning(
                'linebgcolor not implemented for %s with matplotlib backend',
                shape)
        xView = numpy.array(x, copy=False)
        yView = numpy.array(y, copy=False)

        linestyle = normalize_linestyle(linestyle)

        if shape == "line":
            item = self.ax.plot(x, y, color=color,
                                linestyle=linestyle, linewidth=linewidth,
                                marker=None)[0]

        elif shape == "hline":
            if hasattr(y, "__len__"):
                y = y[-1]
            item = self.ax.axhline(y, color=color,
                                   linestyle=linestyle, linewidth=linewidth)

        elif shape == "vline":
            if hasattr(x, "__len__"):
                x = x[-1]
            item = self.ax.axvline(x, color=color,
                                   linestyle=linestyle, linewidth=linewidth)

        elif shape == 'rectangle':
            xMin = numpy.nanmin(xView)
            xMax = numpy.nanmax(xView)
            yMin = numpy.nanmin(yView)
            yMax = numpy.nanmax(yView)
            w = xMax - xMin
            h = yMax - yMin
            item = Rectangle(xy=(xMin, yMin),
                             width=w,
                             height=h,
                             fill=False,
                             color=color,
                             linestyle=linestyle,
                             linewidth=linewidth)
            if fill:
                item.set_hatch('.')

            if linestyle != "solid" and linebgcolor is not None:
                item = _DoubleColoredLinePatch(item)
                item.linebgcolor = linebgcolor

            self.ax.add_patch(item)

        elif shape in ('polygon', 'polylines'):
            points = numpy.array((xView, yView)).T
            if shape == 'polygon':
                closed = True
            else:  # shape == 'polylines'
                closed = numpy.all(numpy.equal(points[0], points[-1]))
            item = Polygon(points,
                           closed=closed,
                           fill=False,
                           color=color,
                           linestyle=linestyle,
                           linewidth=linewidth)
            if fill and shape == 'polygon':
                item.set_hatch('/')

            if linestyle != "solid" and linebgcolor is not None:
                item = _DoubleColoredLinePatch(item)
                item.linebgcolor = linebgcolor

            self.ax.add_patch(item)

        else:
            raise NotImplementedError("Unsupported item shape %s" % shape)

        item.set_zorder(z + 1)
        item.set_animated(True)

        return item
class WindowSelectionRectangle(object):
    def __init__(self, event, axis, on_window_selection_callback):
        self.axis = axis
        if event.inaxes != self.axis:
            return
        # Store the axes it has been initialized in.
        self.axes = event.inaxes
        ymin, ymax = self.axes.get_ylim()
        self.min_x = event.xdata
        self.intial_selection_active = True
        self.rect = Rectangle((event.xdata, ymin), 0, ymax - ymin, color="0.3",
            alpha=0.5, edgecolor="0.5")
        self.axes.add_patch(self.rect)
        # Get the canvas.
        self.canvas = self.rect.figure.canvas

        # Use blittig for fast animations.
        self.rect.set_animated(True)
        self.background = self.canvas.copy_from_bbox(self.rect.axes.bbox)

        self._connect()

        self.on_window_selection_callback = on_window_selection_callback

    #def __del__(self):
        #"""
        #Disconnect the events upon deallocating.
        #"""
        #self.canvas.mpl_disconnect(self.conn_button_press)
        #self.canvas.mpl_disconnect(self.conn_button_release)
        #self.canvas.mpl_disconnect(self.conn_mouse_motion)

    def _connect(self):
        """
        Connect to the necessary events.
        """
        self.conn_button_press = self.rect.figure.canvas.mpl_connect(
            'button_press_event', self.on_button_press)
        self.conn_button_release = self.rect.figure.canvas.mpl_connect(
            'button_release_event', self.on_button_release)
        self.conn_mouse_motion = self.rect.figure.canvas.mpl_connect(
            'motion_notify_event', self.on_mouse_motion)

    def on_button_press(self, event):
        pass

    def on_button_release(self, event):
        if event.inaxes != self.axis:
            return

        if event.button != 1:
            return
        # turn off the rect animation property and reset the background
        self.rect.set_animated(False)
        self.background = None

        self.intial_selection_active = False
        self.canvas.draw()

        x = self.rect.get_x()
        width = self.rect.get_width()

        if width < 0:
            x = x + width
            width = abs(width)

        self.on_window_selection_callback(x, width, self.axis)

    def on_mouse_motion(self, event):
        if event.button != 1 or \
                self.intial_selection_active is not True:
            return
        if event.xdata is not None:
            self.rect.set_width(event.xdata - self.min_x)

        # restore the background region
        self.canvas.restore_region(self.background)
        # redraw just the current rectangle
        self.axes.draw_artist(self.rect)
        # blit just the redrawn area
        self.canvas.blit(self.axes.bbox)
Ejemplo n.º 6
0
class Selector:
    def __init__(self, filenames):
        self.filenames = filenames

        try:
            self.filename = next(self.filenames)
        except:
            print("No more images to be labelled")

        self.image = Image.open(RAW_FOLDER + self.filename)
        print("Labeling", self.filename)

        self.counter = 0
        self.fig, self.ax = plt.subplots(1, 1, figsize=(14, 8))
        plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
        self.x = [0, 0]
        self.y = [0, 0]
        self.samples = {}
        self.on = False
        self.hasNext = True
        self.options = None

        self.ax.imshow(self.image)

        self.rect = Rectangle((0, 0), 0, 0, fill=None, linewidth=2, color="r")
        self.ax.add_patch(self.rect)

        self.ax.figure.canvas.mpl_connect('button_press_event', self.press)
        self.ax.figure.canvas.mpl_connect('motion_notify_event', self.move)
        self.ax.figure.canvas.mpl_connect('button_release_event', self.release)

        self.fig.canvas.mpl_connect('key_press_event', self.terminate)
        self.fig.canvas.mpl_connect('close_event', self.close)

        plt.show()

    def terminate(self, event):
        """
        x: close and save
        c: close without saving
        """

        if event.key:
            if event.key == "x":
                self.hasNext = False
                plt.close()
                self.close()
            elif event.key == "c":
                plt.close()

    def press(self, event):
        """
        Mouse click event
        """

        if (-1 < event.xdata < self.image.size[0]) and (-1 < event.ydata <
                                                        self.image.size[1]):
            self.on = True
            self.x[0], self.y[0] = event.xdata, event.ydata

            self.rect.set_visible(True)
            self.rect.set_animated(True)
            self.fig.canvas.draw()
            self.background = self.fig.canvas.copy_from_bbox(
                self.rect.axes.bbox)
            self.ax.draw_artist(self.rect)
            self.fig.canvas.blit(self.ax.bbox)

    def move(self, event):
        """
        Mousemove event
        """

        if self.on:
            if event.xdata is not None and event.ydata is not None:
                self.x[1], self.y[1] = event.xdata, event.ydata
                self.rect.set_width(abs(self.x[1] - self.x[0]))
                self.rect.set_height(abs(self.y[1] - self.y[0]))
                self.rect.set_xy((min(self.x), min(self.y)))

                self.fig.canvas.restore_region(self.background)
                self.ax.draw_artist(self.rect)
                self.fig.canvas.blit(self.ax.bbox)

    def release(self, event):
        """
        Mouse release event
        """

        if self.on:
            self.on = False
            self.background = None

            if self.options is not None:
                self.options.window.destroy()

            self.options = Select()
            self.options.window.mainloop()
            self.rect.set_width(0)
            self.rect.set_height(0)
            self.rect.set_visible(False)
            self.fig.canvas.draw()
            self.rect.set_animated(False)

            if self.options.selected != "None":
                points = (int(min(self.x)), int(min(self.y)), int(max(self.x)),
                          int(max(self.y)))

                self.ax.add_patch(
                    Rectangle(points[:2],
                              points[2] - points[0],
                              points[3] - points[1],
                              fill=None,
                              linewidth=2,
                              hatch='\\',
                              color="y",
                              alpha=0.5))

                self.ax.text(points[0] + 6,
                             points[1] + 21,
                             self.options.selected,
                             color="w")
                self.ax.text(points[0] + 5,
                             points[1] + 20,
                             self.options.selected,
                             color="k")

                self.samples[self.counter] = (self.options.selected, points)
                self.counter += 1
                self.fig.canvas.draw()

            self.options = None

    def close(self, event):
        """
        Close the current image and open the next one
        """

        counts = {c: 0 for c in CATEGORIES}
        for i in self.samples:
            label = self.samples[i][0]
            filename = SAMPLE_FOLDER + label + "_"

            while os.path.exists(filename + str(counts[label]).zfill(5) +
                                 ".jpg"):
                counts[label] += 1

            self.image.crop(
                self.samples[i][1]).save(filename +
                                         str(counts[label]).zfill(5) + ".jpg")

        os.rename(RAW_FOLDER + self.filename, DONE_FOLDER + self.filename)

        if self.options is not None:
            self.options.window.destroy()
        if self.hasNext:
            global sel
            sel = Selector(self.filenames)
Ejemplo n.º 7
0
class SpanSelector(_SelectorWidget):
    """Custom SpanSelector."""

    # pylint: disable=too-many-instance-attributes
    # pylint: disable=too-many-arguments
    # pylint: disable=attribute-defined-outside-init
    # pylint: disable=invalid-name
    def __init__(self,
                 ax,
                 onselect,
                 direction,
                 minspan=None,
                 useblit=False,
                 rectprops=None,
                 onmove_callback=None,
                 span_stays=False,
                 button=None):

        _SelectorWidget.__init__(self,
                                 ax,
                                 onselect,
                                 useblit=useblit,
                                 button=button)

        if rectprops is None:
            rectprops = dict(facecolor='red', alpha=0.5)

        rectprops['animated'] = self.useblit

        if direction not in ['horizontal', 'vertical']:
            msg = "direction must be in [ 'horizontal' | 'vertical' ]"
            raise ValueError(msg)
        self.direction = direction

        self.rect = None
        self.pressv = None

        self.rectprops = rectprops
        self.onmove_callback = onmove_callback
        self.minspan = minspan
        self.span_stays = span_stays

        # 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)

    def new_axes(self, ax):
        """Set SpanSelector to operate on a new Axes"""
        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()

        if self.direction == 'horizontal':
            trans = blended_transform_factory(self.ax.transData,
                                              self.ax.transAxes)
            w, h = 0, 2
        else:
            trans = blended_transform_factory(self.ax.transAxes,
                                              self.ax.transData)
            w, h = 1, 0
        self.rect = Rectangle((0, -0.5),
                              w,
                              h,
                              transform=trans,
                              visible=False,
                              **self.rectprops)
        if self.span_stays:
            self.stay_rect = Rectangle((0, 0),
                                       w,
                                       h,
                                       transform=trans,
                                       visible=False,
                                       **self.rectprops)
            self.stay_rect.set_animated(False)
            self.ax.add_patch(self.stay_rect)

        self.ax.add_patch(self.rect)
        self.artists = [self.rect]

    def set_rectprops(self, rectprops):
        """Custom: set new rectprops."""
        self.rectprops = rectprops
        self.new_axes(self.ax)

    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"""
        if self.ignore(event):
            return True
        self.rect.set_visible(self.visible)
        if self.span_stays:
            self.stay_rect.set_visible(False)
            # really force a draw so that the stay rect is not in
            # the blit background
            if self.useblit:
                self.canvas.draw()
        xdata, ydata = self._get_data(event)
        if self.direction == 'horizontal':
            self.pressv = xdata
        else:
            self.pressv = ydata
        return False

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

        self.rect.set_visible(False)

        if self.span_stays:
            self.stay_rect.set_x(self.rect.get_x())
            self.stay_rect.set_y(self.rect.get_y())
            self.stay_rect.set_width(self.rect.get_width())
            self.stay_rect.set_height(self.rect.get_height())
            self.stay_rect.set_visible(True)

        self.canvas.draw_idle()
        vmin = self.pressv
        xdata, ydata = self._get_data(event)
        if self.direction == 'horizontal':
            vmax = xdata or self.prev[0]
        else:
            vmax = ydata or self.prev[1]

        if vmin > vmax:
            vmin, vmax = vmax, vmin
        span = vmax - vmin
        if self.minspan is not None and span < self.minspan:
            return True
        self.onselect(vmin, vmax)
        self.pressv = None
        return False

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

        self.prev = x, y
        if self.direction == 'horizontal':
            v = x
        else:
            v = y

        minv, maxv = v, self.pressv
        if minv > maxv:
            minv, maxv = maxv, minv
        if self.direction == 'horizontal':
            self.rect.set_x(minv)
            self.rect.set_width(maxv - minv)
        else:
            self.rect.set_y(minv)
            self.rect.set_height(maxv - minv)

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

            if vmin > vmax:
                vmin, vmax = vmax, vmin
            self.onmove_callback(vmin, vmax)

        self.update()
        return False
Ejemplo n.º 8
0
    def addItem(self, x, y, legend, shape, color, fill, overlay, z,
                linestyle, linewidth, linebgcolor):
        if (linebgcolor is not None and
                shape not in ('rectangle', 'polygon', 'polylines')):
            _logger.warning(
                'linebgcolor not implemented for %s with matplotlib backend',
                shape)
        xView = numpy.array(x, copy=False)
        yView = numpy.array(y, copy=False)

        linestyle = normalize_linestyle(linestyle)

        if shape == "line":
            item = self.ax.plot(x, y, label=legend, color=color,
                                linestyle=linestyle, linewidth=linewidth,
                                marker=None)[0]

        elif shape == "hline":
            if hasattr(y, "__len__"):
                y = y[-1]
            item = self.ax.axhline(y, label=legend, color=color,
                                   linestyle=linestyle, linewidth=linewidth)

        elif shape == "vline":
            if hasattr(x, "__len__"):
                x = x[-1]
            item = self.ax.axvline(x, label=legend, color=color,
                                   linestyle=linestyle, linewidth=linewidth)

        elif shape == 'rectangle':
            xMin = numpy.nanmin(xView)
            xMax = numpy.nanmax(xView)
            yMin = numpy.nanmin(yView)
            yMax = numpy.nanmax(yView)
            w = xMax - xMin
            h = yMax - yMin
            item = Rectangle(xy=(xMin, yMin),
                             width=w,
                             height=h,
                             fill=False,
                             color=color,
                             linestyle=linestyle,
                             linewidth=linewidth)
            if fill:
                item.set_hatch('.')

            if linestyle != "solid" and linebgcolor is not None:
                item = _DoubleColoredLinePatch(item)
                item.linebgcolor = linebgcolor

            self.ax.add_patch(item)

        elif shape in ('polygon', 'polylines'):
            points = numpy.array((xView, yView)).T
            if shape == 'polygon':
                closed = True
            else:  # shape == 'polylines'
                closed = numpy.all(numpy.equal(points[0], points[-1]))
            item = Polygon(points,
                           closed=closed,
                           fill=False,
                           label=legend,
                           color=color,
                           linestyle=linestyle,
                           linewidth=linewidth)
            if fill and shape == 'polygon':
                item.set_hatch('/')

            if linestyle != "solid" and linebgcolor is not None:
                item = _DoubleColoredLinePatch(item)
                item.linebgcolor = linebgcolor

            self.ax.add_patch(item)

        else:
            raise NotImplementedError("Unsupported item shape %s" % shape)

        item.set_zorder(z)

        if overlay:
            item.set_animated(True)
            self._overlays.add(item)

        return item
Ejemplo n.º 9
0
class Selector:
    def __init__(self, filenames):
        self.filenames = filenames

        try:
            self.filename = next(self.filenames)            
        except:
            print("No more images to be labelled")
        
        self.image = Image.open(RAW_FOLDER + self.filename)
        print("Labeling", self.filename)

        self.counter = 0
        self.fig, self.ax = plt.subplots(1, 1, figsize=(14, 8))
        plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
        self.x = [0, 0]
        self.y = [0, 0]
        self.samples = {}
        self.on = False
        self.hasNext = True
        self.options = None

        self.ax.imshow(self.image)      

        self.rect = Rectangle((0,0), 0, 0, fill=None, linewidth=2, color="r")
        self.ax.add_patch(self.rect)
        
        self.ax.figure.canvas.mpl_connect('button_press_event', self.press)
        self.ax.figure.canvas.mpl_connect('motion_notify_event', self.move)
        self.ax.figure.canvas.mpl_connect('button_release_event', self.release)
        
        self.fig.canvas.mpl_connect('key_press_event', self.terminate)
        self.fig.canvas.mpl_connect('close_event', self.close)

        plt.show()
        
    def terminate(self, event):
        """
        x: close and save
        c: close without saving
        """
        
        if event.key:
            if event.key == "x":
                self.hasNext = False
                plt.close()
                self.close()
            elif event.key == "c":
                plt.close()
        
    def press(self, event):
        """
        Mouse click event
        """

        if (-1 < event.xdata < self.image.size[0]) and (-1 < event.ydata < self.image.size[1]):
            self.on = True
            self.x[0], self.y[0] = event.xdata, event.ydata

            self.rect.set_visible(True)
            self.rect.set_animated(True)
            self.fig.canvas.draw()
            self.background = self.fig.canvas.copy_from_bbox(self.rect.axes.bbox)
            self.ax.draw_artist(self.rect)
            self.fig.canvas.blit(self.ax.bbox)

    def move(self, event):
        """
        Mousemove event
        """        
        
        if self.on:
            if event.xdata is not None and event.ydata is not None:
                self.x[1], self.y[1] = event.xdata, event.ydata
                self.rect.set_width(abs(self.x[1] - self.x[0]))
                self.rect.set_height(abs(self.y[1] - self.y[0]))
                self.rect.set_xy((min(self.x), min(self.y)))
                
                self.fig.canvas.restore_region(self.background)
                self.ax.draw_artist(self.rect)
                self.fig.canvas.blit(self.ax.bbox)

    def release(self, event):
        """
        Mouse release event
        """
        
        if self.on:
            self.on = False
            self.background = None

            if self.options is not None:
                self.options.window.destroy()
  
            self.options = Select()
            self.options.window.mainloop()            
            self.rect.set_width(0)
            self.rect.set_height(0)
            self.rect.set_visible(False)
            self.fig.canvas.draw()
            self.rect.set_animated(False)

            if self.options.selected != "None":
                points = (int(min(self.x)), int(min(self.y)), 
                          int(max(self.x)), int(max(self.y)))

                self.ax.add_patch(
                    Rectangle(points[:2], 
                              points[2] - points[0], 
                              points[3] - points[1], 
                              fill=None, linewidth=2, 
                              hatch='\\', color="y", alpha=0.5))

                self.ax.text(points[0] + 6, points[1] + 21, 
                             self.options.selected, color="w")
                self.ax.text(points[0] + 5, points[1] + 20, 
                             self.options.selected, color="k")

                self.samples[self.counter] = (self.options.selected, points)
                self.counter += 1
                self.fig.canvas.draw()

            self.options = None        
        
    def close(self, event):
        """
        Close the current image and open the next one
        """
        
        counts = {c: 0 for c in CATEGORIES}
        for i in self.samples:
            label = self.samples[i][0]
            filename = SAMPLE_FOLDER + label + "_" 

            while os.path.exists(filename + str(counts[label]).zfill(5) + ".jpg"):
                counts[label] += 1
                
            self.image.crop(self.samples[i][1]).save(filename + str(counts[label]).zfill(5) + ".jpg")
            
        os.rename(RAW_FOLDER + self.filename, DONE_FOLDER + self.filename)

        if self.options is not None:
            self.options.window.destroy()
        if self.hasNext:
            global sel
            sel = Selector(self.filenames)
class WindowSelectionRectangle(object):
    def __init__(self, event, axis, on_window_selection_callback):
        self.axis = axis
        if event.inaxes != self.axis:
            return
        # Store the axes it has been initialized in.
        self.axes = event.inaxes
        ymin, ymax = self.axes.get_ylim()
        self.min_x = event.xdata
        self.intial_selection_active = True
        self.rect = Rectangle((event.xdata, ymin),
                              0,
                              ymax - ymin,
                              color="0.3",
                              alpha=0.5,
                              edgecolor="0.5")
        self.axes.add_patch(self.rect)
        # Get the canvas.
        self.canvas = self.rect.figure.canvas

        # Use blittig for fast animations.
        self.rect.set_animated(True)
        self.background = self.canvas.copy_from_bbox(self.rect.axes.bbox)

        self._connect()

        self.on_window_selection_callback = on_window_selection_callback

    #def __del__(self):
    #"""
    #Disconnect the events upon deallocating.
    #"""
    #self.canvas.mpl_disconnect(self.conn_button_press)
    #self.canvas.mpl_disconnect(self.conn_button_release)
    #self.canvas.mpl_disconnect(self.conn_mouse_motion)

    def _connect(self):
        """
        Connect to the necessary events.
        """
        self.conn_button_press = self.rect.figure.canvas.mpl_connect(
            'button_press_event', self.on_button_press)
        self.conn_button_release = self.rect.figure.canvas.mpl_connect(
            'button_release_event', self.on_button_release)
        self.conn_mouse_motion = self.rect.figure.canvas.mpl_connect(
            'motion_notify_event', self.on_mouse_motion)

    def on_button_press(self, event):
        pass

    def on_button_release(self, event):
        if event.inaxes != self.axis:
            return

        if event.button != 1:
            return
        # turn off the rect animation property and reset the background
        self.rect.set_animated(False)
        self.background = None

        self.intial_selection_active = False
        self.canvas.draw()

        x = self.rect.get_x()
        width = self.rect.get_width()

        if width < 0:
            x = x + width
            width = abs(width)

        self.on_window_selection_callback(x, width, self.axis)

    def on_mouse_motion(self, event):
        if event.button != 1 or \
                self.intial_selection_active is not True:
            return
        if event.xdata is not None:
            self.rect.set_width(event.xdata - self.min_x)

        # restore the background region
        self.canvas.restore_region(self.background)
        # redraw just the current rectangle
        self.axes.draw_artist(self.rect)
        # blit just the redrawn area
        self.canvas.blit(self.axes.bbox)