def create_ellipse_ax(self, ax):
        elliprops = dict(edgecolor = 'black', fill = False,
                         linewidth = 5, linestyle= '-')

        self._ellipse_selector = EllipseSelector(ax, self._callback_ellipse,
                                    drawtype= 'box', useblit= True, rectprops= elliprops,
                                    button= [1,3], minspanx = 5, minspany=5,
                                        spancoords='pixels', interactive=True)

        self._disable_ellipse()
Example #2
0
    def drawCircle(self, click):
        print("Click, hold, and drag to draw circle.\n\n")

        self.rs = EllipseSelector(self.ax,
                                  self._drawCircleEvent,
                                  lineprops=dict(linewidth=1,
                                                 alpha=0.6,
                                                 color='k'),
                                  drawtype='box',
                                  useblit=False,
                                  button=[1])
    def configure_selector(self, frange=False, peaks=False):
        self.range_selector = RectangleSelector(self.axs[0], self.rect_onselect,
                          drawtype='box', useblit=True,
                          button=[1, 3],  # don't use middle button
                          minspanx=15, minspany=15,
                          spancoords='pixels',
                          #interactive=True,
                          rectprops=dict(alpha=0.5, facecolor='g'))


        self.peaks_selector = EllipseSelector(self.axs[0], self.ellipse_onselect,
                                              drawtype='line',
                                              button=[1, 3],  # don't use middle button
                                              spancoords='pixels',
                                              useblit=True,
                                              minspanx=10,
                                              minspany=10,
                                              rectprops=dict(alpha=0.5, facecolor='red'))

        self.peaks_selector.set_active(peaks)
        self.range_selector.set_active(frange)
Example #4
0
 def __init__(self, axes, roi_type):
     self.axes = axes
     self.roi_type = roi_type
     self.patch = None
     self.lasso_switch = False
     self.verts = None
     self.title = 'N/A'
     self.annotate = None
     self.intensity = 0
     self.global_switch = False
     if self.roi_type == 'rectangle':
         self.roi = RectangleSelector(self.axes, self.onselect, drawtype='box', interactive=True)
     elif self.roi_type == 'ellipse':
         self.roi = EllipseSelector(self.axes, self.onselect, drawtype='box', interactive=True)
     else:
         self.roi = LassoSelector(self.axes, onselect=self.lasso_select)
Example #5
0
 def __init__(self, RA, DEC, canvas, figure):
     self.canvas = canvas
     self.ax = figure
     self.ax.scatter(RA, DEC)  ## Picker = 5 for close radius
     self.RA = RA
     self.DEC = DEC
     self.RA_subset = []
     self.DEC_subset = []
     self.cache = []
     self.ind = []
     self.ellipse = EllipseSelector(
         self.ax,
         self.line_select_callback,
         drawtype='box',
         useblit=False,
         button=[1, 3],  ## No mousewheel
         minspanx=5,
         minspany=5,
         spancoords='pixels',
         interactive=True)
Example #6
0
    def refreshLassoWidget(self, keep_paths=False):
        self.roi_ax.clear()
        init_lasso = False
        if self.roi_image is not None:
            if len(self.roi_mask) > 0:
                newImage = plot_tools.overlayImage(
                    self.roi_image[:, :, self.current_z_slice],
                    self.roi_mask,
                    0.5,
                    self.colors,
                    z=self.current_z_slice)
            else:
                newImage = self.roi_image[:, :, self.current_z_slice]
            self.roi_ax.imshow(newImage, cmap=cm.gray)
            init_lasso = True
        else:
            self.roi_ax.imshow(self.blank_image)
        self.roi_ax.set_axis_off()

        self.roi_canvas.draw()

        if not keep_paths:
            self.roi_path_list = []

        if init_lasso:
            if self.roi_type == 'circle':
                self.lasso_1 = EllipseSelector(self.roi_ax,
                                               onselect=self.newEllipse,
                                               button=1)
            elif self.roi_type == 'freehand':
                self.lasso_1 = LassoSelector(self.roi_ax,
                                             onselect=self.newFreehand,
                                             button=1)
                self.lasso_2 = LassoSelector(self.roi_ax,
                                             onselect=self.appendFreehand,
                                             button=3)
            else:
                print(
                    'Warning ROI type not recognized. Choose circle or freehand'
                )
Example #7
0
    def define_roi(self, frame_number=0):
        if type(frame_number) != int:
            raise TypeError('frame number is required to be an int')
        image = self.read_frames(frame_number)[0, :, :]

        def line_select_callback(eclick, erelease):
            'eclick and erelease are the press and release events'
            x1, y1 = eclick.xdata, eclick.ydata
            x2, y2 = erelease.xdata, erelease.ydata


        def toggle_selector(event):
            if event.key in ['Q', 'q'] and toggle_selector.ES.active:
                toggle_selector.ES.set_active(False)
                plt.close()

        fig, ax = plt.subplots()
        ax.imshow(image)
        fig.tight_layout()

        toggle_selector.ES = EllipseSelector(ax, line_select_callback,
                                             drawtype='box', useblit=True,
                                             button=[1, 3],  # don't use middle button
                                             minspanx=5, minspany=5,
                                             spancoords='pixels',
                                             interactive=True,
                                             lineprops=dict(color='black', linestyle='-',
                                                            linewidth=2, alpha=0.5))
        plt.connect('key_press_event', toggle_selector)
        plt.show()
        def ellipse_dimensions(extents):
            center = (abs(extents[0] - extents[1]) / 2 + min(extents[0:2]),
                  abs(extents[2] - extents[3]) / 2 + min(extents[2:]))
            radius = (abs(extents[0] - extents[1]), abs(extents[2] - extents[3]))
            return center, radius[0], radius[1]

        self.roi_center, self.roi_width, self.roi_height= ellipse_dimensions(toggle_selector.ES.extents)
        roi_patch = mp.Ellipse(self.roi_center, self.roi_width, self.roi_height, fill=False, hatch='\\')
        return roi_patch
Example #8
0
def selectROI_ellipse(matrice_immagine, titolo='Immagine'):
    ''' 
    input:
        ax --> axis su cui fare la selezione della roi
    output:
        (x1,y1,x2,y2)
    '''
    (t_lim_inf, t_lim_sup) = set_cmap(matrice_immagine)
    _, ax = plt.subplots()
    ax.imshow(matrice_immagine, clim=[t_lim_inf, t_lim_sup])
    ax.set(title=titolo)
    __toggle_selector.ES = EllipseSelector(
        ax,
        __onselect,
        drawtype='box',
        useblit=True,
        button=[1, 3],  # don't use middle button
        minspanx=5,
        minspany=5,
        spancoords='pixels',
        interactive=True)
    plt.connect('key_press_event', __toggle_selector)
    plt.show()
    return cordinate
Example #9
0
	def drawAOI(self):
		"""Function that allows speicification of area of interest (AOI) for analysis.

		"""

		with open(self.json_file, "r") as f:
			json_data = json.load(f)

		aoi_left_x = 0
		aoi_left_y = 0
		aoi_right_x = 0
		aoi_right_y = 0

		display_width = json_data["Analysis_Params"]["EyeTracker"]["Display_width"]
		display_height = json_data["Analysis_Params"]["EyeTracker"]["Display_height"]

		cnt = 0
		img = None

		if os.path.isdir(self.path + "/Stimuli/"):
			for f in os.listdir(self.path + "/Stimuli/"):
				if f.split(".")[-1] in ['jpg', 'jpeg', 'png']:
					img = plt.imread(self.path + "/Stimuli/" + f)
					cnt += 1
					break

		if cnt == 0:
			img = np.zeros((display_height, display_width, 3))

		fig, ax = plt.subplots()
		fig.canvas.set_window_title("Draw AOI")
		ax.imshow(img)

		if self.aoi == "p":

			def onselect(verts):
				nonlocal vertices, canvas
				print('\nSelected points:')
				x = []
				y = []
				for i, j in vertices:
					print(round(i, 3), ",", round(j, 3))
					x.append(i)
					y.append(j)

				vertices = verts
				canvas.draw_idle()

			canvas = ax.figure.canvas
			_ = PolygonSelector(ax, onselect, lineprops=dict(color='r', linestyle='-', linewidth=2, alpha=0.5), markerprops=dict(marker='o', markersize=7, mec='r', mfc='k', alpha=0.5))
			vertices = []

			print("1) 'esc' KEY: START A NEW POLYGON")
			print("2) 'shift' KEY: MOVE ALL VERTICES BY DRAGGING ANY EDGE")
			print("3) 'ctrl' KEY: MOVE A SINGLE VERTEX")

			plt.show()
			return vertices

		elif self.aoi == "r":
			def line_select_callback(eclick, erelease):
				nonlocal aoi_left_x, aoi_left_y, aoi_right_x, aoi_right_y
				aoi_left_x, aoi_left_y = round(eclick.xdata, 3), round(eclick.ydata, 3)
				aoi_right_x, aoi_right_y = round(erelease.xdata, 3), round(erelease.ydata, 3)
				print("Coordinates [(start_x, start_y), (end_x, end_y)]: ", "[(%6.2f, %6.2f), (%6.2f, %6.2f)]" % (aoi_left_x, aoi_left_y, aoi_right_x, aoi_right_y))

			RS = RectangleSelector(ax, line_select_callback, drawtype='box', useblit=False, interactive=True)
			RS.to_draw.set_visible(True)

			plt.show()
			return [aoi_left_x, aoi_left_y, aoi_right_x, aoi_right_y]

		elif self.aoi == "e":
			x_dia = 0
			y_dia = 0
			centre = (0,0)
			def onselect(eclick, erelease):
				nonlocal x_dia, y_dia, centre
				x_dia = (erelease.xdata - eclick.xdata)
				y_dia = (erelease.ydata - eclick.ydata)
				centre = [round(eclick.xdata + x_dia/2., 3), round(eclick.ydata + y_dia/2., 3)]
				print("Centre: ", centre)
				print("X Diameter: ", x_dia)
				print("Y Diameter: ", y_dia)
				print()

			ES = EllipseSelector(ax, onselect, drawtype='box', interactive=True, lineprops=dict(color='g', linestyle='-', linewidth=2, alpha=0.5), marker_props=dict(marker='o', markersize=7, mec='g', mfc='k', alpha=0.5))
			plt.show()

			return [centre, x_dia, y_dia]
    def _set_interactive_tool(self, ax_area, ax_button, ax_slider):
        self.drag_id = None
        self.area_bbox = ax_area.get_window_extent()

        self.selector_pen = patches.Circle(
            xy=(0, 0), edgecolor='black',
            radius=0.0, fc='gray',
            alpha=0.5, zorder=5)
        ax_area.add_patch(self.selector_pen)
        self.selector_pen.set_visible(True)

        self.fig._fig.canvas.mpl_connect(
            'button_press_event', self._on_click_pen)
        self.fig._fig.canvas.mpl_connect(
            'motion_notify_event', self._on_click_pen)

        self.selector_rect = RectangleSelector(
            ax_area, self._on_select_rect,
            drawtype='box', button=1,
            rectprops=dict(
                facecolor='gray', edgecolor='black',
                alpha=0.5, fill=True, zorder=5),
            state_modifier_keys=dict(
                move=' ', clear='escape',
                square='control', center='space'))
        self.selector_rect.visible = False

        self.selector_ellipse = EllipseSelector(
            ax_area, self._on_select_ellipse,
            drawtype='box', button=1,
            rectprops=dict(
                facecolor='gray', edgecolor='black',
                alpha=0.5, fill=True, zorder=5),
            state_modifier_keys=dict(
                move=' ', clear='escape',
                square='control', center='space'))
        self.selector_ellipse.visible = False

        def _press(ls, event):
            ls.verts = [ls._get_data(event)]
            ls.line.set_visible(ls.visible)

        def _release(ls, event):
            if ls.verts is not None:
                ls.verts.append(ls._get_data(event))
                ls.onselect(ls.verts, event)
            ls.line.set_data([[], []])
            ls.line.set_visible(False)
            ls.verts = None

        LassoSelector._press = _press
        LassoSelector._release = _release
        self.selector_lasso = LassoSelector(
            ax_area, onselect=self._on_select_lasso,
            button=1, useblit=False,
            lineprops=dict(linewidth=2.0, color="gray", zorder=1))
        self.selector_lasso.visible = False

        self.button_radio = RadioButtons(
            ax_button, ["pen", "rectangle", "ellipse", "lasso"])
        for _label in self.button_radio.labels:
            _label.set_fontsize(12)
        self.button_radio.on_clicked(self._on_change_radio)

        self.slider_radius = Slider(
            ax_slider, 'pen\nsize', 0.0, 50.0,
            valinit=BaseEditor.pen_size, valfmt='%.1f')
        self.slider_radius.on_changed(self._on_change_radius)
Example #11
0
def select_pts(nodepts,
               elements,
               values=None,
               selection=None,
               shape='ellipse',
               add=True):
    '''
    This function allows you to interactively select a point, rectangle or ellipse.
    This info can then be fed to functions to remove nodes/elements or query their properties
    '''
    if selection is None:
        selection = np.zeros(np.shape(nodepts)[0], dtype=bool)

    def line_select_callback(eclick, erelease):
        'eclick and erelease are the press and release events'

        x1, y1 = eclick.xdata, eclick.ydata

        x2, y2 = erelease.xdata, erelease.ydata

        print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
        print(" The button you used were: %s %s" %
              (eclick.button, erelease.button))

    def toggle_selector(event):
        print(' Key pressed.')
        if event.key in ['Q', 'q'] and RS.active:
            print(' RectangleSelector deactivated.')
            RS.set_active(False)
        if event.key in ['A', 'a'] and not RS.active:
            print(' RectangleSelector activated.')
            RS.set_active(True)

    def rect_select_node(rect, selected):
        for index, node in enumerate(nodepts):
            if (node[0] > rect[0]) & (node[0] < (rect[0] + rect[2])):
                if (node[1] > rect[1]) & (node[1] < (rect[1] + rect[3])):
                    selected[index] = add
        return selected

    def ellipse_select_node(rect, selected):
        el = patches.Ellipse((rect[0], rect[1]), rect[2], rect[3])
        for index, node in enumerate(nodepts):
            if el.contains_point(node):
                selected[index] = add
        return selected

    if values is None:
        values = mesh.default_values(elements)

    fig, ax = tri_mesh_select_plot(nodepts, elements, selection, show=False)
    if shape == 'rectangle':
        RS = RectangleSelector(
            ax,
            line_select_callback,
            drawtype='box',
            useblit=True,
            button=[1, 3],  # don't use middle button
            minspanx=5,
            minspany=5,
            spancoords='pixels',
            interactive=True)

    elif shape == 'ellipse':
        RS = EllipseSelector(
            ax,
            line_select_callback,
            drawtype='box',
            useblit=True,
            button=[1, 3],  # don't use middle button
            minspanx=5,
            minspany=5,
            spancoords='pixels',
            interactive=True)

    plt.connect('key_press_event', toggle_selector)
    plt.show()

    if shape == 'rectangle':
        edge_centers = RS.edge_centers
        #[(x,y),width,height]
        rect = [
            edge_centers[0][0], edge_centers[1][1],
            edge_centers[0][2] - edge_centers[0][0],
            edge_centers[1][3] - edge_centers[1][1]
        ]
    elif shape == 'ellipse':
        edge_centers = RS.edge_centers
        rect = [
            edge_centers[0][1], edge_centers[1][0],
            edge_centers[0][2] - edge_centers[0][0],
            edge_centers[1][3] - edge_centers[1][1]
        ]

    if shape == 'rectangle':
        selection = rect_select_node(rect, selection)
    elif shape == 'ellipse':
        selection = ellipse_select_node(rect, selection)

    tri_mesh_select_plot(nodepts, elements, selection, show=True)

    return selection
Example #12
0
    def init_plot(self,
                  embedding,
                  weights,
                  on_selection,
                  on_close,
                  disable_select,
                  top_level=False,
                  labels=None,
                  color_norm=None):
        """ Set the initial embedding and point weights
            to create and display the plot at iteration step=0"""
        # pylint: disable=attribute-defined-outside-init
        self.top_level = top_level
        self.labels = labels
        self.color_norm = color_norm
        self.disable_select = disable_select
        self.selection_mask = np.full(weights.shape, False)

        # Plot and image definition
        # self.rect = None
        self.extent = 2.8
        self.cleanup = True
        self.rectangle_selector = None
        self.lasso_selector = None

        # Callbacks
        self.fig.canvas.mpl_connect('motion_notify_event', self.on_over)
        self.fig.canvas.mpl_connect('key_press_event', self.on_keypress)
        self.fig.canvas.mpl_connect('button_press_event', self.on_start_select)
        self.fig.canvas.mpl_connect('close_event', self.handle_close)

        # Brush support values
        self.in_selection = False
        self.in_paint = False
        self.dim_xy = (None, None)  # displacement
        self.rorg_xy = (None, None)  # The bottom left corner

        print("Show plot")
        plt.show(block=False)  # Need no block for cooperation with tkinter

        self.embedding = embedding
        self.on_selection = on_selection
        self.on_close = on_close
        # pylint: enable=attribute-defined-outside-init
        x = embedding[:, 0]
        y = embedding[:, 1]
        if self.labels is None:
            self.scatter = self.ax.scatter(x,
                                           y,
                                           s=weights * 8,
                                           c='b',
                                           alpha=0.4,
                                           picker=10)
        else:
            self.scatter = self.ax.scatter(
                x,
                y,
                s=weights * 8,
                c=self.labels,
                # TODO make color map user selectable pylint: disable=fixme
                cmap=plt.cm.rainbow_r,  # # pylint: disable=no-member
                norm=self.color_norm,
                alpha=0.4,
                picker=10)

        self.update_scatter_plot_limits(embedding)

        # Drawing selectors
        rectangle_selector = RectangleSelector(self.ax,
                                               self.on_end_rectangle_select,
                                               drawtype='box',
                                               useblit=True,
                                               button=[1, 3],
                                               rectprops=dict(
                                                   facecolor=(1, 0, 0, 0.1),
                                                   edgecolor=(1, 0, 0, 0.5),
                                                   fill=False),
                                               minspanx=5,
                                               minspany=5,
                                               spancoords='pixels')
        lasso_selector = LassoSelector(self.ax,
                                       onselect=self.on_end_lasso_select,
                                       lineprops=dict(color=(1, 0, 0, 0.5)))
        ellipse_selector = EllipseSelector(self.ax,
                                           onselect=self.on_end_ellipse_select,
                                           drawtype='line',
                                           lineprops=dict(color=(1, 0, 0,
                                                                 0.5)))
        polygon_selector = PolygonSelector(self.ax,
                                           onselect=self.on_end_lasso_select,
                                           lineprops=dict(color=(1, 0, 0,
                                                                 0.5)))

        self.selectors = {
            DrawingShape.Lasso: lasso_selector,
            DrawingShape.Ellipse: ellipse_selector,
            DrawingShape.Rectangle: rectangle_selector,
            DrawingShape.Polygon: polygon_selector
        }
        # pylint: disable=attribute-defined-outside-init
        self.set_selector()
        # force rendering of facecolors
        self.fig.canvas.draw()
        self.facecolors = self.scatter.get_facecolors()
Example #13
0
    def process(self, image, **kwargs):
        if "DISPLAY" not in os.environ:
            raise Exception("Can't run selectors without a display!")

        if kwargs["method"] == "mask":
            mask = np.zeros(image.shape, np.uint8)

            global drawing
            drawing = False

            def paint_draw(event, x, y, flags, param):
                global ix, iy, drawing

                if event == cv2.EVENT_LBUTTONDOWN:
                    drawing = True
                elif event == cv2.EVENT_LBUTTONUP:
                    drawing = False
                elif event == cv2.EVENT_MOUSEMOVE and drawing:
                    cv2.line(mask, (ix, iy), (x, y), kwargs["color"], kwargs["brush"])

                ix, iy = x, y

                return x, y

            cv2.namedWindow("Select Mask", cv2.WINDOW_KEEPRATIO)
            cv2.resizeWindow("Select Mask", image.shape[0], image.shape[1])
            cv2.setMouseCallback("Select Mask", paint_draw)

            while cv2.getWindowProperty("Select Mask", cv2.WND_PROP_VISIBLE) >= 1:
                cv2.imshow("Select Mask", cv2.addWeighted(image, 0.8, mask, 0.2, 0))
                key_code = cv2.waitKey(1)

                if (key_code & 0xFF) == ord("q"):
                    cv2.destroyAllWindows()
                    break
                elif (key_code & 0xFF) == ord("+"):
                    kwargs["brush"] += 1
                elif (key_code & 0xFF) == ord("-") and kwargs["brush"] > 1:
                    kwargs["brush"] -= 1

            mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
            mask[mask != 0] = 255

            return {"mask": easycv.image.Image(mask)}

        mpl.use("Qt5Agg")

        fig, current_ax = plt.subplots()
        plt.tick_params(
            axis="both",
            which="both",
            bottom=False,
            top=False,
            left=False,
            right=False,
            labelbottom=False,
            labelleft=False,
        )

        def empty_callback(e1, e2):
            pass

        def selector(event):
            if event.key in ["Q", "q"]:
                plt.close(fig)

        res = []
        current_ax.imshow(prepare_image_to_output(image))
        plt.gcf().canvas.set_window_title("Selector")

        if kwargs["method"] == "rectangle":
            selector.S = RectangleSelector(
                current_ax,
                empty_callback,
                useblit=True,
                button=[1, 3],
                minspanx=5,
                minspany=5,
                spancoords="pixels",
                interactive=True,
            )
        elif kwargs["method"] == "ellipse":
            selector.S = EllipseSelector(
                current_ax,
                empty_callback,
                drawtype="box",
                interactive=True,
                useblit=True,
            )
        else:

            def onclick(event):
                if event.xdata is not None and event.ydata is not None:
                    res.append((int(event.xdata), int(event.ydata)))
                    plt.plot(
                        event.xdata, event.ydata, marker="o", color="cyan", markersize=4
                    )
                    fig.canvas.draw()
                    if len(res) == kwargs["n"]:
                        plt.close(fig)

            plt.connect("button_press_event", onclick)

        plt.connect("key_press_event", selector)
        plt.show(block=True)

        if kwargs["method"] == "rectangle":
            x, y = selector.S.to_draw.get_xy()
            x = int(round(x))
            y = int(round(y))
            width = int(round(selector.S.to_draw.get_width()))
            height = int(round(selector.S.to_draw.get_height()))

            if width == 0 or height == 0:
                raise InvalidSelectionError("Must select a rectangle.")

            return {"rectangle": [(x, y), (x + width, y + height)]}

        elif kwargs["method"] == "ellipse":
            width = int(round(selector.S.to_draw.width))
            height = int(round(selector.S.to_draw.height))
            center = [int(round(x)) for x in selector.S.to_draw.get_center()]
            if width == 0 or height == 0:
                raise InvalidSelectionError("Must select an ellipse.")
            return {"ellipse": [tuple(center), int(width / 2), int(height / 2)]}
        else:
            if len(res) != kwargs["n"]:
                raise InvalidSelectionError(
                    "Must select {} points.".format(kwargs["n"])
                )
            return {"points": res}
Example #14
0
    def imshow(self,
               image,
               slider=False,
               normalize=True,
               roi_callback=None,
               roi_drawtype='box',
               **kwargs):
        '''
        Showing an image on the canvas, and optional sliders for colour adjustments.
        
        Redrawing image afterwards is quite fast because set_data is used
        instead imshow (matplotlib).

        INPUT ARGUMENTS
        slider          Whether to draw the sliders for setting image cap values
        roi_callback    A callable taking in x1,y1,x2,y2
        roi_drawtype    "box", "ellipse" "line" or "polygon"
        *kwargs     go to imshow

        Returns the object returned by matplotlib's axes.imshow.
        '''

        if image is None:
            image = self.imshow_image

        self.imshow_image = image

        # Slider
        if slider:
            # Check if the sliders exist. If not, create
            try:
                self.imshow_sliders
            except AttributeError:
                self.slider_axes = [
                    self.figure.add_axes(rect)
                    for rect in ([0.2, 0.05, 0.6, 0.05], [0.2, 0, 0.6, 0.05])
                ]

                self.imshow_sliders = []
                self.imshow_sliders.append(
                    matplotlib.widgets.Slider(self.slider_axes[0],
                                              'Upper %',
                                              0,
                                              100,
                                              valinit=90,
                                              valstep=1))
                self.imshow_sliders.append(
                    matplotlib.widgets.Slider(self.slider_axes[1],
                                              'Lower %',
                                              0,
                                              100,
                                              valinit=5,
                                              valstep=1))
                for slider in self.imshow_sliders:
                    slider.on_changed(lambda slider_val: self.imshow(
                        None, slider=slider, **kwargs))

            for ax in self.slider_axes:
                if ax.get_visible() == False:
                    ax.set_visible(True)

            # Normalize using the known clipping values
            #image = image - lower_clip
            #image = image / upper_clip
        else:
            # Hide the sliders if they exist
            if getattr(self, 'imshow_sliders', None):
                for ax in self.slider_axes:
                    if ax.get_visible() == True:
                        ax.set_visible(False)
                        print('axes not visible not')

        if getattr(self, 'imshow_sliders', None):
            # Check that the lower slider cannot go above the upper.
            if self.imshow_sliders[0].val < self.imshow_sliders[1].val:
                self.imshow_sliders[0].val = self.imshow_sliders[1].val

            upper_clip = np.percentile(image, self.imshow_sliders[0].val)
            lower_clip = np.percentile(image, self.imshow_sliders[1].val)
            image = np.clip(image, lower_clip, upper_clip)

        if normalize:
            image = image - np.min(image)
            image = image / np.max(image)

        # Just set the data or make an imshow plot
        if self._previous_shape == image.shape and (
                roi_callback is None
                or roi_drawtype == self._previous_roi_drawtype):
            self.imshow_obj.set_data(image)
        else:
            if hasattr(self, 'imshow_obj'):
                # Fixed here. Without removing the AxesImages object plotting
                # goes increacingly slow every time when visiting this else block
                # Not sure if this is the best fix (does it free all memory) but
                # it seems to work well
                self.imshow_obj.remove()

            self.imshow_obj = self.ax.imshow(image, **kwargs)
            self.figure.subplots_adjust(left=0,
                                        bottom=0,
                                        right=1,
                                        top=1,
                                        wspace=None,
                                        hspace=None)
            self.ax.xaxis.set_major_locator(matplotlib.ticker.NullLocator())
            self.ax.yaxis.set_major_locator(matplotlib.ticker.NullLocator())
            if callable(roi_callback):

                if getattr(self, "roi_rectangle", None):
                    if self._previous_roi_drawtype == 'line':
                        self.roi_rectangle.disconnect()
                    else:
                        self.roi_rectangle.disconnect_events()

                if roi_drawtype == 'box':
                    self.roi_rectangle = RectangleSelector(
                        self.ax, self.__onSelectRectangle, useblit=True)
                elif roi_drawtype == 'ellipse':
                    self.roi_rectangle = EllipseSelector(
                        self.ax, self.__onSelectRectangle, useblit=True)
                elif roi_drawtype == 'line':
                    self.roi_rectangle = ArrowSelector(
                        self.ax, self.__onSelectRectangle)
                elif roi_drawtype == 'polygon':
                    self.roi_rectangle = PolygonSelector(
                        self.ax, self.__onSelectPolygon, useblit=True)
                else:
                    raise ValueError(
                        'roi_drawtype either "box", "ellipse", "line", or "polygon", got {}'
                        .format(roi_drawtype))

                self.roi_callback = roi_callback
                self._previous_roi_drawtype = roi_drawtype

        self._previous_shape = image.shape
        self.canvas.draw()

        return self.imshow_obj
Example #15
0
class EllipsePixelRegion(PixelRegion):
    """
    An ellipse in pixel coordinates.

    Parameters
    ----------
    center : `~regions.PixCoord`
        The position of the center of the ellipse.
    width : `float`
        The width of the ellipse (before rotation) in pixels
    height : `float`
        The height of the ellipse (before rotation) in pixels
    angle : `~astropy.units.Quantity`, optional
        The rotation angle of the ellipse, measured anti-clockwise. If set to
        zero (the default), the width axis is lined up with the x axis.
    meta : `~regions.RegionMeta` object, optional
        A dictionary which stores the meta attributes of this region.
    visual : `~regions.RegionVisual` object, optional
        A dictionary which stores the visual meta attributes of this region.

    Examples
    --------

    .. plot::
        :include-source:

        import numpy as np
        from astropy.modeling.models import Ellipse2D
        from astropy.coordinates import Angle
        from regions import PixCoord, EllipsePixelRegion
        import matplotlib.pyplot as plt
        x0, y0 = 15, 10
        a, b = 8, 5
        theta = Angle(30, 'deg')
        e = Ellipse2D(amplitude=100., x_0=x0, y_0=y0, a=a, b=b, theta=theta.radian)
        y, x = np.mgrid[0:20, 0:30]
        fig, ax = plt.subplots(1, 1)
        ax.imshow(e(x, y), origin='lower', interpolation='none', cmap='Greys_r')

        center = PixCoord(x=x0, y=y0)
        reg = EllipsePixelRegion(center=center, width=2*a, height=2*b, angle=theta)
        patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2)
        ax.add_patch(patch)

    """
    _params = ('center', 'width', 'height', 'angle')
    center = ScalarPix('center')
    width = ScalarLength('width')
    height = ScalarLength('height')
    angle = QuantityLength('angle')

    def __init__(self, center, width, height, angle=0. * u.deg, meta=None,
                 visual=None):
        self.center = center
        self.width = width
        self.height = height
        self.angle = angle
        self.meta = meta or RegionMeta()
        self.visual = visual or RegionVisual()

    @property
    def area(self):
        """Region area (float)"""
        return math.pi / 4 * self.width * self.height

    def contains(self, pixcoord):
        pixcoord = PixCoord._validate(pixcoord, name='pixcoord')
        cos_angle = np.cos(self.angle)
        sin_angle = np.sin(self.angle)
        dx = pixcoord.x - self.center.x
        dy = pixcoord.y - self.center.y
        in_ell = ((2 * (cos_angle * dx + sin_angle * dy) / self.width) ** 2 +
                  (2 * (sin_angle * dx - cos_angle * dy) / self.height) ** 2 <= 1.)
        if self.meta.get('include', True):
            return in_ell
        else:
            return np.logical_not(in_ell)

    def to_sky(self, wcs):
        # TODO: write a pixel_to_skycoord_scale_angle
        center = pixel_to_skycoord(self.center.x, self.center.y, wcs)
        _, scale, north_angle = skycoord_to_pixel_scale_angle(center, wcs)
        height = Angle(self.height / scale, 'deg')
        width = Angle(self.width / scale, 'deg')
        return EllipseSkyRegion(center, width, height,
                                angle=self.angle - (north_angle - 90 * u.deg),
                                meta=self.meta, visual=self.visual)

    @property
    def bounding_box(self):
        """
        The minimal bounding box (`~regions.BoundingBox`) enclosing the
        exact elliptical region.
        """

        # We use the solution described in http://stackoverflow.com/a/88020
        # which is to use the parametric equation of an ellipse and to find
        # when dx/dt or dy/dt=0.

        cos_angle = np.cos(self.angle)
        sin_angle = np.sin(self.angle)
        tan_angle = np.tan(self.angle)

        t1 = np.arctan(-self.height * tan_angle / self.width)
        t2 = t1 + np.pi * u.rad

        dx1 = 0.5 * self.width * cos_angle * np.cos(t1) - 0.5 * self.height * sin_angle * np.sin(t1)
        dx2 = 0.5 * self.width * cos_angle * np.cos(t2) - 0.5 * self.height * sin_angle * np.sin(t2)

        if dx1 > dx2:
            dx1, dx2 = dx2, dx1

        t1 = np.arctan(self.height / tan_angle / self.width)
        t2 = t1 + np.pi * u.rad

        dy1 = 0.5 * self.height * cos_angle * np.sin(t1) + 0.5 * self.width * sin_angle * np.cos(t1)
        dy2 = 0.5 * self.height * cos_angle * np.sin(t2) + 0.5 * self.width * sin_angle * np.cos(t2)

        if dy1 > dy2:
            dy1, dy2 = dy2, dy1

        xmin = self.center.x + dx1
        xmax = self.center.x + dx2
        ymin = self.center.y + dy1
        ymax = self.center.y + dy2

        return BoundingBox.from_float(xmin, xmax, ymin, ymax)

    def to_mask(self, mode='center', subpixels=5):

        # NOTE: assumes this class represents a single circle

        self._validate_mode(mode, subpixels)

        if mode == 'center':
            mode = 'subpixels'
            subpixels = 1

        # Find bounding box and mask size
        bbox = self.bounding_box
        ny, nx = bbox.shape

        # Find position of pixel edges and recenter so that ellipse is at origin
        xmin = float(bbox.ixmin) - 0.5 - self.center.x
        xmax = float(bbox.ixmax) - 0.5 - self.center.x
        ymin = float(bbox.iymin) - 0.5 - self.center.y
        ymax = float(bbox.iymax) - 0.5 - self.center.y

        if mode == 'subpixels':
            use_exact = 0
        else:
            use_exact = 1

        fraction = elliptical_overlap_grid(
            xmin, xmax, ymin, ymax, nx, ny,
            0.5 * self.width, 0.5 * self.height,
            self.angle.to(u.rad).value,
            use_exact, subpixels,
        )

        return RegionMask(fraction, bbox=bbox)

    def as_artist(self, origin=(0, 0), **kwargs):
        """
        Matplotlib patch object for this region (`matplotlib.patches.Ellipse`).

        Parameters
        ----------
        origin : array_like, optional
            The ``(x, y)`` pixel position of the origin of the displayed image.
            Default is (0, 0).
        kwargs : `dict`
            All keywords that a `~matplotlib.patches.Ellipse` object accepts

        Returns
        -------
        patch : `~matplotlib.patches.Ellipse`
            Matplotlib ellipse patch

        """
        from matplotlib.patches import Ellipse
        xy = self.center.x - origin[0], self.center.y - origin[1]
        width = self.width
        height = self.height
        # From the docstring: MPL expects "rotation in degrees (anti-clockwise)"
        angle = self.angle.to('deg').value

        mpl_params = self.mpl_properties_default('patch')
        mpl_params.update(kwargs)

        return Ellipse(xy=xy, width=width, height=height, angle=angle,
                       **mpl_params)

    def _update_from_mpl_selector(self, *args, **kwargs):
        xmin, xmax, ymin, ymax = self._mpl_selector.extents
        self.center = PixCoord(x=0.5 * (xmin + xmax),
                               y=0.5 * (ymin + ymax))
        self.width = (xmax - xmin)
        self.height = (ymax - ymin)
        self.angle = 0. * u.deg
        if self._mpl_selector_callback is not None:
            self._mpl_selector_callback(self)

    def as_mpl_selector(self, ax, active=True, sync=True, callback=None, **kwargs):
        """
        Matplotlib editable widget for this region (`matplotlib.widgets.EllipseSelector`)

        Parameters
        ----------
        ax : `~matplotlib.axes.Axes`
            The Matplotlib axes to add the selector to.
        active : bool, optional
            Whether the selector should be active by default.
        sync : bool, optional
            If `True` (the default), the region will be kept in sync with the
            selector. Otherwise, the selector will be initialized with the
            values from the region but the two will then be disconnected.
        callback : func, optional
            If specified, this function will be called every time the region is
            updated. This only has an effect if ``sync`` is `True`. If a
            callback is set, it is called for the first time once the selector
            has been created.
        kwargs
            Additional keyword arguments are passed to matplotlib.widgets.EllipseSelector`

        Returns
        -------
        selector : `matplotlib.widgets.EllipseSelector`
            The Matplotlib selector.

        Notes
        -----
        Once a selector has been created, you will need to keep a reference to
        it until you no longer need it. In addition, you can enable/disable the
        selector at any point by calling ``selector.set_active(True)`` or
        ``selector.set_active(False)``.
        """

        from matplotlib.widgets import EllipseSelector

        if hasattr(self, '_mpl_selector'):
            raise Exception("Cannot attach more than one selector to a region.")

        if self.angle.value != 0:
            raise NotImplementedError("Cannot create matplotlib selector for rotated ellipse.")

        if sync:
            sync_callback = self._update_from_mpl_selector
        else:
            def sync_callback(*args, **kwargs):
                pass

        self._mpl_selector = EllipseSelector(ax, sync_callback, interactive=True,
                                             rectprops={'edgecolor': self.visual.get('color', 'black'),
                                                        'facecolor': 'none',
                                                        'linewidth': self.visual.get('linewidth', 1),
                                                        'linestyle': self.visual.get('linestyle', 'solid')})
        self._mpl_selector.extents = (self.center.x - self.width / 2,
                                      self.center.x + self.width / 2,
                                      self.center.y - self.height / 2,
                                      self.center.y + self.height / 2)
        self._mpl_selector.set_active(active)
        self._mpl_selector_callback = callback

        if sync and self._mpl_selector_callback is not None:
            self._mpl_selector_callback(self)

        return self._mpl_selector

    def rotate(self, center, angle):
        """Make a rotated region.

        Rotates counter-clockwise for positive ``angle``.

        Parameters
        ----------
        center : `PixCoord`
            Rotation center point
        angle : `~astropy.coordinates.Angle`
            Rotation angle

        Returns
        -------
        region : `EllipsePixelRegion`
            Rotated region (an independent copy)
        """
        center = self.center.rotate(center, angle)
        angle = self.angle + angle
        return self.copy(center=center, angle=angle)
Example #16
0
    def __init__(self):
        self.window = Tk()
        self.window.title("Artefact Labeling")
        self.window.geometry('1425x770')  #self.window.geometry('1920x1080')
        self.window.configure(background="gray38")

        self.mrt_layer_set = []
        self.optionlist = []
        self.mrt_layer_names = []

        # TODO: replace by dbinfo = DatabaseInfo()
        # self.mrt_model = dbinfo.get_mrt_model
        self.mrt_model = {
            't1_tse_tra_fs_Becken_0008': '0008',
            't1_tse_tra_fs_Becken_Motion_0010': '0010',
            't1_tse_tra_fs_mbh_Leber_0004': '0004',
            't1_tse_tra_fs_mbh_Leber_Motion_0005': '0005',
            't1_tse_tra_Kopf_0002': '0002',
            't1_tse_tra_Kopf_Motion_0003': '0003',
            't2_tse_tra_fs_Becken_0009': '0009',
            't2_tse_tra_fs_Becken_Motion_0011': '0011',
            't2_tse_tra_fs_Becken_Shim_xz_0012': '0012',
            't2_tse_tra_fs_navi_Leber_0006': '0006',
            't2_tse_tra_fs_navi_Leber_Shim_xz_0007': '0007'
        }
        self.mrt_smodel = {
            't1_tse_tra_fs_Becken_0008': 'Becken',
            't1_tse_tra_fs_Becken_Motion_0010': 'Becken',
            't1_tse_tra_fs_mbh_Leber_0004': 'Leber',
            't1_tse_tra_fs_mbh_Leber_Motion_0005': 'Leber',
            't1_tse_tra_Kopf_0002': 'Kopf',
            't1_tse_tra_Kopf_Motion_0003': 'Kopf',
            't2_tse_tra_fs_Becken_0009': 'Becken',
            't2_tse_tra_fs_Becken_Motion_0011': 'Becken',
            't2_tse_tra_fs_Becken_Shim_xz_0012': 'Becken',
            't2_tse_tra_fs_navi_Leber_0006': 'Leber',
            't2_tse_tra_fs_navi_Leber_Shim_xz_0007': 'Leber'
        }
        self.mrt_artefact = {
            't1_tse_tra_fs_Becken_0008': '',
            't1_tse_tra_fs_Becken_Motion_0010': 'Move',
            't1_tse_tra_fs_mbh_Leber_0004': '',
            't1_tse_tra_fs_mbh_Leber_Motion_0005': 'Move',
            't1_tse_tra_Kopf_0002': '',
            't1_tse_tra_Kopf_Motion_0003': 'Move',
            't2_tse_tra_fs_Becken_0009': '',
            't2_tse_tra_fs_Becken_Motion_0011': 'Move',
            't2_tse_tra_fs_Becken_Shim_xz_0012': 'Shim',
            't2_tse_tra_fs_navi_Leber_0006': '',
            't2_tse_tra_fs_navi_Leber_Shim_xz_0007': 'Shim'
        }
        self.col_list = {"red": "1", "green": "2", "blue": "3"}
        self.res_col_list = {"1": "red", "2": "green", "3": "blue"}
        self.artefact_list = [
            "Movement-Artefact", "Shim-Artefact", "Noise-Artefact"
        ]
        self.mark_list = ["Rectangle", "Ellipse", "Lasso"]
        self.list_of_images = [
            "icons/Move.png", "icons/Rectangle.png", "icons/Ellipse.png",
            "icons/Lasso.png", "icons/Lupe.png", "icons/3D.png"
        ]
        # TODO: adapt paths
        self.sFolder = "C:/Users/Sebastian Milde/Pictures/MRT"
        self.Path_marking = "C:/Users/Sebastian Milde/Pictures/Universitaet/Masterarbeit/Markings/"
        self.proband = os.listdir(self.sFolder)
        self.artefact = os.listdir(self.sFolder + "/ab/dicom_sorted")

        self.panel = Label(self.window, bg="black")

        self.rahmen1 = Frame(self.window, bg="gray65", bd=3, relief="sunken")
        self.rahmen1.place(x=5, y=5, width=215, height=250)

        self.rahmen2 = Frame(self.window, bg="gray65", bd=3, relief="sunken")
        self.rahmen2.place(x=5, y=260, width=215, height=200)

        self.text_r1 = Text(self.rahmen1, height=10, width=200)
        self.text_r1.insert(INSERT, "Choose MRT-Layer")

        # Define buttons and option menus
        image = Image.open("icons/open.png")
        img_open = ImageTk.PhotoImage(image)
        label = Label(image=img_open)
        label.image = img_open
        self.load_button = Button(self.rahmen1,
                                  image=img_open,
                                  text="Load MRT-Layer",
                                  font=('Arial', 11, 'bold'),
                                  bg="gray56",
                                  activeforeground='grey',
                                  borderwidth=4,
                                  compound=LEFT,
                                  command=self.load_MRT)

        self.path_entry = Entry(self.rahmen1)
        self.path_entry.place(x=5, y=50, width=200, height=25)
        self.path_entry.insert(0, self.sFolder)

        self.tool_buttons = []
        self.activated_button = 0
        self.button1_activated = True
        self.x_clicked = None
        self.y_clicked = None
        self.mouse_second_clicked = False

        def onClick(i):
            old_button = self.activated_button
            self.activated_button = i
            if self.activated_button == 0:
                toggle_selector.ES.set_active(False)
                toggle_selector.RS.set_active(False)
                toggle_selector.LS.set_active(False)
                self.button1_activated = True
            if self.activated_button == 2:
                toggle_selector.ES.set_active(True)
                toggle_selector.RS.set_active(False)
                toggle_selector.LS.set_active(False)
                self.button1_activated = False
            if self.activated_button == 1:
                toggle_selector.ES.set_active(False)
                toggle_selector.RS.set_active(True)
                toggle_selector.LS.set_active(False)
                self.button1_activated = False
            if self.activated_button == 3:
                toggle_selector.ES.set_active(False)
                toggle_selector.RS.set_active(False)
                toggle_selector.LS.set_active(True)
                self.button1_activated = False
            if old_button == i:
                pass
            else:
                self.tool_buttons[old_button].configure(relief=RAISED)
                self.tool_buttons[self.activated_button].configure(
                    relief=SUNKEN)
            return

        column = 5
        for i in range(0, len(self.list_of_images), 1):
            image = Image.open(self.list_of_images[i])
            img_tool = ImageTk.PhotoImage(image)
            label = Label(image=img_tool)
            label.image = img_tool
            b = Button(self.rahmen2,
                       image=img_tool,
                       bg="gray56",
                       borderwidth=2,
                       command=lambda i=i: onClick(i))
            if i == 5:
                row = 45
                column = 5
            else:
                row = 5

            b.place(x=column, y=row)
            column += 40
            self.tool_buttons.append(b)
            self.tool_buttons[self.activated_button].configure(relief=SUNKEN)

        self.proband_str = StringVar(self.window)
        self.proband_str.set(self.proband[0])
        self.proband_option = OptionMenu(self.rahmen1, self.proband_str,
                                         *self.proband)
        self.proband_option.config(bg="gray56")

        self.artefact_str = StringVar(self.window)
        self.artefact_str.set(self.artefact[0])
        self.artefact_option = OptionMenu(self.rahmen1, self.artefact_str,
                                          *self.artefact)
        self.artefact_option.config(bg="gray56")

        self.layer = StringVar(self.window)
        self.layer.set("(empty)")
        self.option_layers = OptionMenu(self.rahmen1,
                                        self.layer,
                                        "(empty)",
                                        command=self.change_layer)
        self.option_layers.config(bg="gray56")

        self.chooseArtefact = StringVar(self.window)
        self.chooseArtefact.set(self.artefact_list[0])
        self.chooseArtefact_option = OptionMenu(self.rahmen2,
                                                self.chooseArtefact,
                                                *self.artefact_list)
        self.chooseArtefact_option.config(bg="gray56")

        self.set_cnn = Button(self.window,
                              text="Settings for CNN",
                              bg="gray56",
                              font=('Arial', 11, 'bold'),
                              command=self.chooseData)
        image = Image.open("icons/save.png")
        img = ImageTk.PhotoImage(image)
        label = Label(image=img)
        label.image = img
        image = Image.open("icons/exit.png")
        img_exit = ImageTk.PhotoImage(image)
        label = Label(image=img_exit)
        label.image = img_exit

        self.save_button = Button(self.window,
                                  image=img,
                                  text="Save",
                                  bg="gray56",
                                  font=('Arial', 11, 'bold'),
                                  borderwidth=4,
                                  compound=LEFT)
        self.exit_button = Button(self.window,
                                  image=img_exit,
                                  text="Exit",
                                  bg="gray56",
                                  font=('Arial', 11, 'bold'),
                                  borderwidth=4,
                                  compound=LEFT,
                                  command=self.exit)

        self.number_mrt_label = Label(self.window,
                                      bg="#000000",
                                      fg="white",
                                      font="Aral 23 bold")
        self.art_mod_label = Label(self.panel,
                                   bg="#000000",
                                   fg="white",
                                   font="Aral 12 bold")
        self.hint_label = Label(self.window,
                                text="Please load MRT-Layer",
                                bg="#000000",
                                fg="white",
                                font="Aral 25 bold")

        self.load_button.place(
            x=5, y=5, width=200,
            height=40)  #self.load_button.place(x=5, y=5, width=200, height=40)

        self.proband_option.place(
            x=5, y=80, width=200, height=50
        )  #self.proband_option.place(x=5, y=55, width=200, height=50)
        self.artefact_option.place(
            x=5, y=135, width=200, height=50
        )  # self.artefact_option.place(x=5, y=105, width=200, height=50)
        self.option_layers.place(
            x=5, y=190, width=200, height=50
        )  #self.option_layers.place(x=5, y=155, width=200, height=50)
        self.chooseArtefact_option.place(x=5, y=85, width=200, height=50)

        self.set_cnn.place(x=12.5, y=470, width=200, height=40)
        self.exit_button.place(x=12, y=725, width=200, height=40)
        self.save_button.place(x=12, y=680, width=200, height=40)
        self.panel.place(x=225, y=5, width=1204, height=764)

        # Visualisation
        self.fig = plt.figure(dpi=50)
        #self.fig.patch.set_facecolor('black')
        self.ax = plt.gca()
        self.pltc = None
        #self.ax.set_axis_bgcolor('black')
        self.ax.text(0.5,
                     0.5,
                     'To label MRT-Artefacts load MRT-Layer',
                     horizontalalignment='center',
                     verticalalignment='center',
                     color='white',
                     fontsize=20,
                     transform=self.ax.transAxes)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.window)
        self.canvas.show()
        self.canvas.get_tk_widget().place(x=600, y=250)  # expand=1

        def lasso_onselect(verts):
            print(verts)
            p = path.Path(verts)
            current_mrt_layer = self.get_currentLayerNumber()
            proband = self.art_mod_label['text'][10:self.art_mod_label['text'].
                                                 find('\n')]
            model = self.art_mod_label[
                'text'][self.art_mod_label['text'].find('\n') +
                        9:len(self.art_mod_label['text'])]
            print(proband)
            print(model)
            saveFile = shelve.open(self.Path_marking + proband + ".slv",
                                   writeback=True)
            print(p)
            patch = None
            col_str = None
            if self.chooseArtefact.get() == self.artefact_list[0]:
                col_str = "31"
                patch = patches.PathPatch(p, fill=False, edgecolor='red', lw=2)
            elif self.chooseArtefact.get() == self.artefact_list[1]:
                col_str = "32"
                patch = patches.PathPatch(p,
                                          fill=False,
                                          edgecolor='green',
                                          lw=2)
            elif self.chooseArtefact.get() == self.artefact_list[2]:
                col_str = "33"
                patch = patches.PathPatch(p,
                                          fill=False,
                                          edgecolor='blue',
                                          lw=2)
            self.ax.add_patch(patch)
            layer_name = model
            if saveFile.has_key(layer_name):
                number_str = str(
                    self.mrt_layer_set[current_mrt_layer].get_current_Number(
                    )) + "_" + col_str + "_" + str(len(self.ax.patches) - 1)
                saveFile[layer_name].update({number_str: p})
            else:
                number_str = str(
                    self.mrt_layer_set[current_mrt_layer].get_current_Number(
                    )) + "_" + col_str + "_" + str(len(self.ax.patches) - 1)
                saveFile[layer_name] = {number_str: p}

            saveFile.close()
            self.fig.canvas.draw_idle()

        def ronselect(eclick, erelease):
            'eclick and erelease are matplotlib events at press and release'
            col_str = None
            rect = None
            ell = None
            x1, y1 = eclick.xdata, eclick.ydata
            x2, y2 = erelease.xdata, erelease.ydata
            current_mrt_layer = self.get_currentLayerNumber()
            proband = self.art_mod_label['text'][10:self.art_mod_label['text'].
                                                 find('\n')]
            model = self.art_mod_label[
                'text'][self.art_mod_label['text'].find('\n') +
                        9:len(self.art_mod_label['text'])]
            print(proband)
            print(model)
            saveFile = shelve.open(self.Path_marking + proband + ".slv",
                                   writeback=True)
            p = np.array(([x1, y1, x2, y2]))

            layer_name = model

            if toggle_selector.RS.active and not toggle_selector.ES.active:
                if self.chooseArtefact.get() == self.artefact_list[0]:
                    col_str = "11"
                    rect = plt.Rectangle((min(x1, x2), min(y1, y2)),
                                         np.abs(x1 - x2),
                                         np.abs(y1 - y2),
                                         fill=False,
                                         edgecolor="red",
                                         lw=2)
                elif self.chooseArtefact.get() == self.artefact_list[1]:
                    col_str = "12"
                    rect = plt.Rectangle((min(x1, x2), min(y1, y2)),
                                         np.abs(x1 - x2),
                                         np.abs(y1 - y2),
                                         fill=False,
                                         edgecolor="green",
                                         lw=2)
                elif self.chooseArtefact.get() == self.artefact_list[2]:
                    col_str = "13"
                    rect = plt.Rectangle((min(x1, x2), min(y1, y2)),
                                         np.abs(x1 - x2),
                                         np.abs(y1 - y2),
                                         fill=False,
                                         edgecolor="blue",
                                         lw=2)
                self.ax.add_patch(rect)
            elif toggle_selector.ES.active and not toggle_selector.RS.active:
                if self.chooseArtefact.get() == self.artefact_list[0]:
                    col_str = "21"
                    ell = Ellipse(xy=(min(x1, x2) + np.abs(x1 - x2) / 2,
                                      min(y1, y2) + np.abs(y1 - y2) / 2),
                                  width=np.abs(x1 - x2),
                                  height=np.abs(y1 - y2),
                                  edgecolor="red",
                                  fc='None',
                                  lw=2)
                elif self.chooseArtefact.get() == self.artefact_list[1]:
                    col_str = "22"
                    ell = Ellipse(xy=(min(x1, x2) + np.abs(x1 - x2) / 2,
                                      min(y1, y2) + np.abs(y1 - y2) / 2),
                                  width=np.abs(x1 - x2),
                                  height=np.abs(y1 - y2),
                                  edgecolor="green",
                                  fc='None',
                                  lw=2)
                elif self.chooseArtefact.get() == self.artefact_list[2]:
                    col_str = "23"
                    ell = Ellipse(xy=(min(x1, x2) + np.abs(x1 - x2) / 2,
                                      min(y1, y2) + np.abs(y1 - y2) / 2),
                                  width=np.abs(x1 - x2),
                                  height=np.abs(y1 - y2),
                                  edgecolor="blue",
                                  fc='None',
                                  lw=2)
                self.ax.add_patch(ell)

            if saveFile.has_key(layer_name):
                number_str = str(
                    self.mrt_layer_set[current_mrt_layer].get_current_Number(
                    )) + "_" + col_str + "_" + str(len(self.ax.patches) - 1)
                saveFile[layer_name].update({number_str: p})
            else:
                number_str = str(
                    self.mrt_layer_set[current_mrt_layer].get_current_Number(
                    )) + "_" + col_str + "_" + str(len(self.ax.patches) - 1)
                saveFile[layer_name] = {number_str: p}
            saveFile.close()
            print(' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata))
            print(' endposition   : (%f, %f)' %
                  (erelease.xdata, erelease.ydata))
            print(' used button   : ', eclick.button)

        def toggle_selector(event):
            print(' Key pressed.')
            if self.activated_button == 2 and not toggle_selector.ES.active and (
                    toggle_selector.LS.active or toggle_selector.RS.active):
                toggle_selector.ES.set_active(True)
                toggle_selector.RS.set_active(False)
                toggle_selector.LS.set_active(False)
            if self.activated_button == 1 and not toggle_selector.RS.active and (
                    toggle_selector.LS.active or toggle_selector.ES.active):
                toggle_selector.ES.set_active(False)
                toggle_selector.RS.set_active(True)
                toggle_selector.LS.set_active(False)
            if self.activated_button == 3 and (
                    toggle_selector.ES.active or toggle_selector.RS.active
            ) and not toggle_selector.LS.active:
                toggle_selector.ES.set_active(False)
                toggle_selector.RS.set_active(False)
                toggle_selector.LS.set_active(True)

        toggle_selector.RS = RectangleSelector(
            self.ax, ronselect, button=[1]
        )  #drawtype='box', useblit=False, button=[1], minspanx=5, minspany=5, spancoords='pixels', interactive=True

        toggle_selector.ES = EllipseSelector(
            self.ax,
            ronselect,
            drawtype='line',
            button=[1],
            minspanx=5,
            minspany=5,
            spancoords='pixels',
            interactive=True
        )  #drawtype='line', minspanx=5, minspany=5, spancoords='pixels', interactive=True

        toggle_selector.LS = LassoSelector(self.ax, lasso_onselect, button=[1])

        toggle_selector.ES.set_active(False)
        toggle_selector.RS.set_active(False)
        toggle_selector.LS.set_active(False)
        self.fig.canvas.mpl_connect('key_press_event', self.click)
        self.fig.canvas.mpl_connect('button_press_event', self.mouse_clicked)
        self.fig.canvas.mpl_connect('motion_notify_event', self.mouse_move)
        self.fig.canvas.mpl_connect('button_release_event', self.mouse_release)
        #self.fig.canvas.mpl_connect('key_press_event', toggle_selector)
        #lasso = LassoSelector(self.ax, self.onselect, button=[1])
        #self.hint_label.place(x=550, y=200, width = 400, height = 300)
        self.window.mainloop()
Example #17
0
    def as_mpl_selector(self, ax, active=True, sync=True, callback=None, **kwargs):
        """
        Matplotlib editable widget for this region (`matplotlib.widgets.EllipseSelector`)

        Parameters
        ----------
        ax : `~matplotlib.axes.Axes`
            The Matplotlib axes to add the selector to.
        active : bool, optional
            Whether the selector should be active by default.
        sync : bool, optional
            If `True` (the default), the region will be kept in sync with the
            selector. Otherwise, the selector will be initialized with the
            values from the region but the two will then be disconnected.
        callback : func, optional
            If specified, this function will be called every time the region is
            updated. This only has an effect if ``sync`` is `True`. If a
            callback is set, it is called for the first time once the selector
            has been created.
        kwargs
            Additional keyword arguments are passed to matplotlib.widgets.EllipseSelector`

        Returns
        -------
        selector : `matplotlib.widgets.EllipseSelector`
            The Matplotlib selector.

        Notes
        -----
        Once a selector has been created, you will need to keep a reference to
        it until you no longer need it. In addition, you can enable/disable the
        selector at any point by calling ``selector.set_active(True)`` or
        ``selector.set_active(False)``.
        """

        from matplotlib.widgets import EllipseSelector

        if hasattr(self, '_mpl_selector'):
            raise Exception("Cannot attach more than one selector to a region.")

        if self.angle.value != 0:
            raise NotImplementedError("Cannot create matplotlib selector for rotated ellipse.")

        if sync:
            sync_callback = self._update_from_mpl_selector
        else:
            def sync_callback(*args, **kwargs):
                pass

        self._mpl_selector = EllipseSelector(ax, sync_callback, interactive=True,
                                             rectprops={'edgecolor': self.visual.get('color', 'black'),
                                                        'facecolor': 'none',
                                                        'linewidth': self.visual.get('linewidth', 1),
                                                        'linestyle': self.visual.get('linestyle', 'solid')})
        self._mpl_selector.extents = (self.center.x - self.width / 2,
                                      self.center.x + self.width / 2,
                                      self.center.y - self.height / 2,
                                      self.center.y + self.height / 2)
        self._mpl_selector.set_active(active)
        self._mpl_selector_callback = callback

        if sync and self._mpl_selector_callback is not None:
            self._mpl_selector_callback(self)

        return self._mpl_selector
Example #18
0
#%%
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import EllipseSelector


def onselect(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)


def toggle_selector(event):
    print(' Key pressed.')
    if event.key in ['Q', 'q'] and toggle_selector.ES.active:
        print('EllipseSelector deactivated.')
        toggle_selector.RS.set_active(False)
    if event.key in ['A', 'a'] and not toggle_selector.ES.active:
        print('EllipseSelector activated.')
        toggle_selector.ES.set_active(True)


x = np.arange(100.) / 99
y = np.sin(x)
fig, ax = plt.subplots()
ax.plot(x, y)

toggle_selector.ES = EllipseSelector(ax, onselect, drawtype='line')
fig.canvas.mpl_connect('key_press_event', toggle_selector)
plt.show()
class FittingDataPlot2D(DataPlotEditorBase):
    nplots = 2
    layout = 'horizontal'
    range_rect = Any(transient=True)
    peaks_ellipses = List([],transient=True)

    frangex = Tuple((0.0, 0.0),transient=True)
    frangey = Tuple((0.0, 0.0),transient=True)
    peaks = List([],transient=True)
    range_selector = Any(transient=True)  # Instance(SpanSelector)
    peaks_selector = Any(transient=True)  # (SpanSelector)
    editing = Enum('Peaks', ['Range', 'Peaks'])
    has_frange = Property(Bool)
    has_peaks = Property(Bool)

    def _get_has_frange(self):
        if (self.frangex[1]-self.frangex[0])>10 and (self.frangey[1]-self.frangey[0])>10:
            return True
        else:
            return False

    def _get_has_peaks(self):
        if len(self.peaks):
            return True
        else:
            return False

    def clear_patches(self, frange=True, peaks=True):
        if frange:
            try:
                self.range_rect.remove()
                self.range_rect = None
            except:
                pass

        if peaks:
            for ellipse in self.peaks_ellipses:
                try:
                    ellipse.remove()
                    self.peaks_ellipses.remove(ellipse)
                except:
                    pass

    def clear_selections(self):
        self.clear_patches()
        self.peaks = []
        self.frangex = (0.0,0.0)
        self.frangey = (0.0, 0.0)

    def draw_patches(self, frange=True, peaks=True):
        if all([frange, len(self.axs), len(self.frangex), len(self.frangey)]):
            self.range_rect = self.draw_rectangle(self.frangex, self.frangey, color='g', alpha=0.15)

        if all([peaks, len(self.axs), len(self.peaks)]):
            for p in self.peaks:
                self.peaks_ellipses.append(self.draw_ellipse(*p, color='r', alpha=0.4))

        if self.figure is not None:
            if self.figure.canvas is not None:
                self.figure.canvas.draw()

    def mpl_setup(self):
        self.add_subplots(self.nplots)
        self.configure_selector(peaks=True)
        # self.figure.canvas.draw()
        # self.activate_selector()



    def draw_rectangle(self,xs,ys,alpha=0.2,color='g'):
        xy = (min(xs),min(ys))
        width = np.abs(np.diff(xs))
        height = np.abs(np.diff(ys))
        re = Rectangle(xy, width, height, angle=0.0)
        ax = self.axs[0]
        ax.add_artist(re)
        re.set_alpha(alpha=alpha)
        re.set_facecolor(color)
        return re

    def draw_ellipse(self,xmid,ymid,width,height,alpha=0.4,color='r'):
        el = Ellipse(xy=(xmid, ymid), width=width,
                     height=height, angle=0)
        ax = self.axs[0]
        ax.add_artist(el)
        #el.set_clip_box(ax.bbox)
        el.set_alpha(alpha=alpha)
        el.set_facecolor(color)
        return el

    def rect_onselect(self, eclick, erelease):
        xs = [eclick.xdata, erelease.xdata]
        ys = [eclick.ydata, erelease.ydata]
        #print xs, ys
        self.frangex = (min(xs), max(xs))
        self.frangey = (min(ys), max(ys))
        self.clear_patches(peaks=False)
        self.draw_patches(peaks=False)

    def ellipse_onselect(self, eclick, erelease):
        xs = [eclick.xdata, erelease.xdata]
        ys = [eclick.ydata, erelease.ydata]
        xmid, ymid = np.mean(xs), np.mean(ys)
        width, height = np.abs(np.diff(xs)), np.abs(np.diff(ys))
        #print [xmid, ymid, width, height]
        self.peaks.append([xmid, ymid, width, height])
        self.clear_patches(frange=False)
        self.draw_patches(frange=False)


    def configure_selector(self, frange=False, peaks=False):
        self.range_selector = RectangleSelector(self.axs[0], self.rect_onselect,
                          drawtype='box', useblit=True,
                          button=[1, 3],  # don't use middle button
                          minspanx=15, minspany=15,
                          spancoords='pixels',
                          #interactive=True,
                          rectprops=dict(alpha=0.5, facecolor='g'))


        self.peaks_selector = EllipseSelector(self.axs[0], self.ellipse_onselect,
                                              drawtype='line',
                                              button=[1, 3],  # don't use middle button
                                              spancoords='pixels',
                                              useblit=True,
                                              minspanx=10,
                                              minspany=10,
                                              rectprops=dict(alpha=0.5, facecolor='red'))

        self.peaks_selector.set_active(peaks)
        self.range_selector.set_active(frange)

    def activate_selector(self, frange=False, peaks=False):
        if self.peaks_selector is not None:
            self.peaks_selector.set_active(peaks)
        if self.range_selector is not None:
            self.range_selector.set_active(frange)

    def _editing_changed(self, new):
        if new == 'Range':
            self.configure_selector(frange=True, peaks=False)
        elif new == 'Peaks':
            self.configure_selector(frange=False, peaks=True)