def delete_mask(event): ''' deletes the mask of the dish area or the mask for bug selection if you click with the right mouse button :param event: :return: ''' global mask, im_mask, lasso2, mask_show, im_mask_bugs # deleting mask of dish area if exists if event.button == 3 and event.inaxes == ax and isinstance( mask, np.ndarray) and isinstance( im_mask, AxesImage ): # only on right click, only if clicked in main axes # chek if mask is already selected mask = 0 # reset mask mask_show = 0 im_mask.remove() # remove displaying mask im_mask = 0 lasso2._xs = [] lasso2._ys = [] lasso2._draw_polygon() # removes display of old verts lasso2 = PolygonSelector(ax, select_mask) # reinitalizing the selector fig.canvas.draw_idle() # plot update #print('you pressed', event.button, event.xdata, event.ydata) # deleting mask of bug segemetnation if exists # only on right click, only if clicked in main axes or in slider axis if event.button == 3 and isinstance(mask_bugs, np.ndarray) and isinstance( im_mask_bugs, AxesImage) and (event.inaxes == ax or event.inaxes == ax_slider): im_mask_bugs.remove() # im_mask_bugs = 0 fig.canvas.draw_idle() # plotupdate
def select_poly(self, filename): """Launch Poly Selector and update poly.""" matplot = self.windows[filename]['spematplot']['matplot'] matplot.poly = PolygonSelector( matplot.ax_mod, lambda v, f=filename: self.update_poly(f, v), )
def __init__(self, ax, row, col): self.canvas = ax.figure.canvas self.poly = PolygonSelector(ax, self.onselect, lineprops = dict(color = 'g', alpha = 1), markerprops = dict(mec = 'g', mfc = 'g', alpha = 1)) self.path = None
def setup(self): # Get figure objects and adjust for buttons self._fig = plt.figure() self._ax = self._fig.add_subplot(1, 1, 1) self._ax.set_title("Map Editor") self._fig.canvas.set_window_title('RoboLib') self._ax.set_xlim([0, self._w]) self._ax.set_ylim([0, self._h]) plt.subplots_adjust(bottom=0.2) # Build buttons button_location = plt.axes([0.8, 0.05, 0.15, 0.075]) self._add_object_button = Button(button_location, 'Add Object') self._add_object_button.on_clicked(self.click_add_object) button_location = plt.axes([0.6, 0.05, 0.18, 0.075]) self._clear_axes_button = Button(button_location, "Clear Objects") self._clear_axes_button.on_clicked(self.click_clear) button_location = plt.axes([0.4, 0.05, 0.15, 0.075]) self._finished_button = Button(button_location, 'Finished') self._finished_button.on_clicked(self.click_finished) # Clear from previous axis for patch in self._objects: patch.remove() for patch in self._objects: self._ax.add_patch(patch) self._poly_select = PolygonSelector(self._ax, self.on_poly_select) self._poly_select.set_active(False)
def __init__(self, ax, x, y, alpha_other=0.3): self.canvas = ax.figure.canvas self.x, self.y = x, y self.xys = np.vstack((x, y)) self.Npts = len(self.xys) # Ensure that we have separate colors for each object self.poly = PolygonSelector(ax, self.onselect) self.ind = []
def drawPolygon(self, click): print( "Click somewhere on the screen to start drawing the polygon.\n\n") self.rs = PolygonSelector(self.ax, self._drawPolygonEvent, markerprops=dict(markersize=1), lineprops=dict(linewidth=1, alpha=0.6, color='k'))
def get_mask(self): data = self.resized fig = plt.figure() ax1 = fig.add_subplot(121) ax1.imshow(data) ax2 = fig.add_subplot(122) ax2.imshow(np.zeros_like(data)) plt.subplots_adjust() self.fig = fig self.poly = PolygonSelector(ax1, self.onselect)
def __init__(self, ax, collection, alpha_other=0.3): self.canvas = ax.figure.canvas self.collection = collection self.prepare_coordinates() self.poly = PolygonSelector(ax, self.onselect) msg = "\nSelect points in the figure by enclosing them within a polygon.\n" msg += "Press the 'esc' key to start a new polygon.\n" msg += "Try hold to left key to move a single vertex.\n" msg += "After complete the selection, close the figure/window to continue.\n" print(msg)
def show_filtered_image(event): ''' shows the filtered image or the original image. If you press the button once, the respectively other option appears on the button. :param event: :return: ''' global sfi_button, im_f, im, im_mask, lasso2 # disconnects and stops the lassoselecto lasso2.disconnect_events() # showing the filtered image if sfi_button.label.get_text( ) == "show filtered\nimage": # checks the text displayed on the button im.remove() # removing unfiltered image im_f = ax.imshow(image_f) # showning filterd image lasso2 = PolygonSelector(ax, select_mask) # reinitalizing the selector if isinstance(mask_show, np.ndarray): # showing mask if already selected im_mask = ax.imshow(mask_show, alpha=0.2) sfi_button.label.set_text("show unfiltered\nimage") fig.canvas.draw_idle() # plot update return # showing the unfilterd image if sfi_button.label.get_text( ) == "show unfiltered\nimage": # checks the text displayed on the button im_f.remove() # removing unfiltered image im = ax.imshow(image) # showing filterd image lasso2 = PolygonSelector(ax, select_mask) # reinitalizing the selector if isinstance(mask_show, np.ndarray): # showing mask if alaready selected im_mask = ax.imshow(mask_show, alpha=0.2) sfi_button.label.set_text("show filtered\nimage") fig.canvas.draw_idle() # plot update return
def selectROI(region): import pylab from matplotlib.widgets import PolygonSelector fig, ax = plt.subplots() ax.imshow(frame) plt.title(region) def onselect(verts): np.savetxt(direc + '\\coordinates\\' + region, verts) polygon = PolygonSelector(ax, onselect) plt.show()
def selectROI(region, frame, main_dir): ## function that allows us to display a matplotlib interactive polygon selector to annotate the frame for each region (which is one of the arguments) ## fig, ax = plt.subplots() ax.imshow(frame) plt.title(region + ' - Press Q to move to the next location') ## this is the function that is fed to the polygon selector tool. All I am doing here is saving the coordinates for every polygon drawn to a text file of numpy coordinates ## ## this allows me to save them outside of the python kernel, and they can be pulled in later at any point ## def onselect(verts): np.savetxt(os.path.join(os.path.join(main_dir, 'coordinates'), region), verts) polygon = PolygonSelector(ax, onselect) plt.show()
def __init__(self, ax, collection, alpha_other=0.3): self.canvas = ax.figure.canvas self.collection = collection self.alpha_other = alpha_other self.xys = collection.get_offsets() self.Npts = len(self.xys) # Ensure that we have separate colors for each object self.fc = collection.get_facecolors() if len(self.fc) == 0: raise ValueError('Collection must have a facecolor') elif len(self.fc) == 1: self.fc = np.tile(self.fc, (self.Npts, 1)) self.poly = PolygonSelector(ax, self.onselect) self.ind = []
def getTargets(self, image, method, **kwargs): print("Add targets...\n") if method in ['poly', 'point']: figure = plt.figure() ax = plt.gca() plt.imshow(image) radius = kwargs['radius'] if 'radius' in kwargs else 2 n = kwargs['n'] if 'n' in kwargs else 100 if method == 'poly': ps = PolygonSelector(ax, lambda verts: self.computePolygon(verts, n = n) ) plt.show() elif method =='point': figure.canvas.mpl_connect('button_press_event', lambda event: self.computeCircle(event, radius = radius, n = n) ) plt.show() else: self.getTargetsFromImage( kwargs['L'], n )
def enter_draw_mode(self) : """ Ensure that the next click after this fcn call will start drawing the polygon. """ # Remove the previous polygon if self.poly and self.poly._polygon_completed : self.remove_polygon() # Reset the flag indicating the first completion of a new polygon #self.first_time_complete = True # Create a PolygonSelector object and attach the draw lock to # it self.poly = PolygonSelector(self, self._on_polygon_complete, lineprops=self.polylineprops, markerprops=self.polymarkerprops, useblit=self.useblit) self.figure.canvas.widgetlock(self.poly)
def __init__(self, image, atom_positions, invert_selection=False): """Get a subset of atom positions using interactive tool. Access the selected atom positions in the atom_positions_selected attribute. Parameters ---------- image : 2D HyperSpy signal or 2D NumPy array atom_positions : list of lists, NumPy array In the form [[x0, y0]. [x1, y1], ...] invert_selection : bool, optional Get the atom positions outside the region, instead of the ones inside it. Default False Attributes ---------- atom_positions_selected : NumPy array """ self.image = image self.atom_positions = np.array(atom_positions) self.invert_selection = invert_selection self.atom_positions_selected = [] self.fig, self.ax = plt.subplots(figsize=(6, 6)) self.ax.set_title("Use the left mouse button to make the polygon.\n" "Click the first position to finish the polygon.\n" "Press ESC to reset the polygon, and hold SHIFT to\n" "move the polygon.") self.cax = self.ax.imshow(self.image) self.line_non_selected = self.ax.plot(self.atom_positions[:, 0], self.atom_positions[:, 1], 'o', color='red')[0] self.line_selected = None markerprops = dict(color='blue') lineprops = dict(color='blue') self.poly = PolygonSelector(self.ax, self.onselect, markerprops=markerprops, lineprops=lineprops) self.fig.tight_layout()
def __init__(self, image, dataType='image', xlim=None, ylim=None): self.x1 = 0.0 self.x2 = 0.0 self.y1 = 0.0 self.y2 = 0.0 self.verts = [] # Print instructions for the user self.instructions = "\nINSTRUCTIONS TO DRAW THE POLYGON\n\n"+\ "Select points in the figure by enclosing them within a polygon.\n"+\ "Press the 'esc' key to start a new polygon.\n"+\ "Try holding the 'shift' key to move all of the vertices.\n"+\ "Try holding the 'ctrl' key to move a single vertex." lineprops = dict(color='r', linestyle='-', linewidth=2, alpha=0.5) markerprops = dict(marker='o', markersize=7, mec='r', mfc='r', alpha=0.5) # Create the figure and plot the image fig = plt.figure(1) self.ax1 = fig.add_subplot(111) if dataType == 'image': self.ax1.imshow(image.T) elif dataType == 'points': self.ax1.plot(*image.T[0:2], 'ob', markersize=3) if xlim is not None: self.ax1.set_xlim(xlim[0], xlim[1]) if ylim is not None: self.ax1.set_ylim(ylim[0], ylim[1]) self.ps = PolygonSelector(self.ax1, self.onselect, lineprops=lineprops, markerprops=markerprops) plt.show()
def _select_roi(self): if self._active == 'roi': self._active=None self._actions['roi'].setChecked(False) self.lasso=None else: self._active='roi' self._actions['roi'].setChecked(True) # lasso disappears if window closed and reopened. Must check super if not self.unsorted:#self.fig is None: ax=self.figure.gca() h=self.histo if h.dims==2: #from polygonlasso import MyLassoSelector #self.lasso=MyLassoSelector(ax,self.select2dGate,useblit=False) self.lasso=PolygonSelector(ax,self.select2dGate,useblit=False, lineprops=dict(color='c', linestyle='-', linewidth=2, alpha=0.5)) else: self.lasso=SpanSelector(ax,self.select1dregion,"horizontal", rectprops = dict(facecolor='blue', alpha=0.5))
def ask_file(event): ''' opens a tk inter file browser. The selected file is loaded as an image to the window. Additionally the filtered image is calculated immediately. :param event: :return: ''' # opens dialog box for image selection global fig, ax, image, pix, image_f, im, lasso2 root = tk.Tk() root.withdraw() # file_path = filedialog.askopenfile() # loading the image image = plt.imread(file_path.name) # grey scale conversion, one could use some wights here if len(image.shape) == 3: #image=image[:,:,0] image = np.mean(image, axis=2) # filtering image image_f = normalize(image, lb=0.1, ub=99.9) # normalization to a range from 0 to 1 image_f = gaussian(image_f, sigma=s1) - gaussian( image_f, sigma=s2) # difference of gaussian filtering # displaying unfiltered image first im = ax.imshow(image) # you can choose a diffrent color map here fig.canvas.draw_idle() #plot update # coordinate of the image, later needed for selction pixx = np.arange(image.shape[0]) pixy = np.arange(image.shape[1]) xv, yv = np.meshgrid(pixy, pixx) pix = np.vstack((xv.flatten(), yv.flatten())).T # (re)initialize polygon selector #lasso2.disconnect_events() seems to have some kind of bug... lasso2 = PolygonSelector(ax, select_mask) # selector on bf image
def __init__(self, ax, chart_center, chart_size): self.canvas = ax.figure.canvas chart_height, chart_width = chart_size vertices = np.array([[ chart_center[0] - chart_width / 2, chart_center[1] + chart_height / 2 ], [ chart_center[0] + chart_width / 2, chart_center[1] + chart_height / 2 ], [ chart_center[0] + chart_width / 2, chart_center[1] - chart_height / 2 ], [ chart_center[0] - chart_width / 2, chart_center[1] - chart_height / 2 ], [ chart_center[0] - chart_width / 2, chart_center[1] + chart_height / 2 ]]) self.poly = PolygonSelector(ax, self.onselect, lineprops=dict(color='g', linewidth=5, alpha=1), markerprops=dict(mfc='r', markersize=10, alpha=1)) self.poly._xs = vertices[:, 0] self.poly._ys = vertices[:, 1] self.poly._polygon_completed = True self.poly._draw_polygon() self.vertices = vertices[:-1, :]
def __init__( self, model_name=None, centerxy=np.array([]), blocks=np.array([]), values=np.array([]), values_log=0, bck=1, ): """ :param model_name: path to the file to be created containing the output :param centerxy: x-y coordinates of the center of the cells :param blocks: coordinates of the corners of the different blocks :param values: array containing the value assigned to each block :param values_log: flag indicating if values should be log transformed or not :param bck: background value """ if centerxy.any( ): # If block center coordinates are provided, plot them. xs = centerxy[:, 0] ys = centerxy[:, 1] fig, ax = plt.subplots() pts = ax.scatter(xs, ys, c="black", alpha=0.5) else: # Else, if only blocks are provided, the centers are computed based on the mean of the coordinates of # their corners try: centerxy = np.array([np.mean(b, axis=0) for b in blocks]) # Mean computed xs = centerxy[:, 0] ys = centerxy[:, 1] fig, ax = plt.subplots() pts = ax.scatter(xs, ys, c="black", alpha=0.5) except Exception as e: print(e) exit() # I use this option to put the points in first plan, as to always see them. pts.set_zorder(2) self.points = centerxy self.bck = bck self.model_name = model_name self.ax = ax # Axes object self.blocks = blocks self.ax.set_title("Now setting value: 0.0") # Initial title self.ax.set_facecolor((0.86, 0.86, 0.86)) # Set gray background # Adjusts plt dimensions to insert colorbar, textbox... plt.subplots_adjust(bottom=0.2, right=0.8) self.vals = ( [] ) # List that will contain the values assigned to the different polygons self.cmap = cm.get_cmap("jet") # Color map function to be later used # It is necessary to define a different axes for the box (normalized) axbox = plt.axes([0.4, 0.07, 0.1, 0.07]) # 4 - tuple of floats # rect = [left, bottom, width, height]. A new axes is added # with dimensions rect in normalized (0, 1) units using ~.Figure.add_axes on the current figure. # Location of colorbar for the user-defined polygons self.axcb = plt.axes([0.82, 0.07, 0.015, 0.83]) bounds = [0] + [1] # Adding one bound more to have enough intervals ticks = [0] # Ticks - default value cols = colors.ListedColormap([self.cmap(v) for v in ticks]) cbnorm = colors.BoundaryNorm(bounds, cols.N) mcb = colorbar.ColorbarBase( self.axcb, cmap=cols, norm=cbnorm, boundaries=bounds, ticks=ticks, ticklocation="right", orientation="vertical", ) # # textstr = """Select points in the figure by enclosing them within a polygon. # Press the 'esc' key to start a new polygon. # Try holding the 'shift' key to move all of the vertices. # Try holding the 'ctrl' key to move a single vertex.""" # # #axtxt = plt.axes([0.15, 0.0, 0.2, 0.15]) # props = dict(boxstyle='round', facecolor='green', alpha=0.5) # ax.text(0, -0.2, textstr, transform=ax.transAxes, fontsize=10, bbox=props) # Text box to input the value to input self.vinput = TextBox(axbox, label=None, initial="0") # What happens when pressing enter self.vinput.on_submit(self.button_submit) self.index = [] # List that will contain the final results ! # Creates a canvas from the ax of the scatter plot self.canvas = self.ax.figure.canvas self.collection = pts # 'collection' is the scatter plot # Necessary for later to define if points enclosed by polygon - basically self.xys = pts.get_offsets() # equals to the - x-y coordinates of the different points. self.Npts = len(self.xys) # Number of points # Ensure that we have separate colors for each object self.fc = pts.get_facecolors() # Gets the rgb of the points if not values.any(): facecolors = "gray" alpha = 0.35 # Opacity of the polygons - if no values assigned - soft gray else: cmap2 = cm.get_cmap("coolwarm") if values_log: # Making a nice linear space itv = 10**np.linspace(np.log10(min(values)), np.log10(max(values)), 12) # out ouf log values to represent some ticks on the colorbar norm2 = colors.LogNorm( vmin=min(values), vmax=max(values)) # Log norm for color bar # Necessary arg to produce the color scale formatter = LogFormatter(10, labelOnlyBase=False) else: itv = np.linspace(min(values), max(values), 8) # Linear space norm2 = colors.Normalize(vmin=min(values), vmax=max(values)) formatter = None # Individual color of each polygon facecolors = [cmap2(norm2(v)) for v in values] alpha = 0.6 # Opacity of the polygons # Colorbar if initial values present - plotting a nice color bar ticks2 = [round(v, 1) for v in itv] plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8) axcb1 = plt.axes([0.15, 0.07, 0.015, 0.83]) cb1 = colorbar.ColorbarBase( axcb1, cmap=cmap2, norm=norm2, ticks=ticks2, boundaries=None, ticklocation="left", format=formatter, orientation="vertical", ) cb1.set_ticklabels(ticks2) # Setting the proper labels if ( self.blocks.any() ): # If blocks are provided. I should change this as the direction this code is going is # to provide blocks by default xs = self.blocks[:, :, 0] # x-coordinates blocks corners ys = self.blocks[:, :, 1] # y-coordinates blocks corners patches = [ ] # Coloring the blocks, in gray or with different colors for b in blocks: polygon = Polygon(b, closed=True) patches.append(polygon) p = PatchCollection(patches, alpha=alpha, facecolors=facecolors, edgecolors="black") p.set_zorder(0) self.ax.add_collection(p) # 5% padding in x-direction for visualization padx = (xs.max() - xs.min()) * 0.05 pady = (ys.max() - ys.min()) * 0.05 # 5% padding self.ax.set_xlim(xs.min() - padx, xs.max() + padx) self.ax.set_ylim(ys.min() - pady, ys.max() + pady) self.collection.set_facecolors(facecolors) # Coloring the points # Polygon selector object self.poly = PolygonSelector(self.ax, self.onselect) self.ind = [] # Initiates the ind list for a new polygon! def handle_close(evt): # Function that disconnects the PolygonSelector self.disconnect() # When closing window, finishes the job self.canvas.mpl_connect("close_event", handle_close) # Final results, array filled with background value. self.final_results = np.ones(len(self.points)) * self.bck
def poly_select(self, event): self.disconnect() self.tool = PolygonSelector(self.ax, onselect=self.onselect, markerprops={'markersize': 3}) self.canvas.draw_idle()
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()
minsize = 0 # default value, you can change this # custom color map for showing the mask of segmentation cmap_mask = LinearSegmentedColormap.from_list('mycmap', ["red", "white"]) # initializing the interactive window fig, ax = plt.subplots() txt = plt.text(0.25, 0.15, str("")) # text over sliding bar plt.subplots_adjust(left=0.25, bottom=0.25) # adding the open image button to the window ax_file, file_select = set_button([0.02, 0.5, 0.17, 0.05], 'open image', ask_file) # initialyzing the polygone selector lasso2 = PolygonSelector(ax, select_mask) # ## adds functionality to delete the mask of segemntation or the dish area on rioght mouse click delete_mask_event = fig.canvas.mpl_connect('button_press_event', delete_mask) # buttton so save the mask of the dish area ax_save_changes, save_changes_button = set_button([0.02, 0.4, 0.17, 0.05], 'save mask', save_mask) # buttton to swithc between the filtered and unfiltered images ax_sfi, sfi_button = set_button([0.02, 0.15, 0.17, 0.1], "show filtered\nimage", show_filtered_image) # adding the slider for thresholding ax_slider_tresh = plt.axes([0.25, 0.1, 0.65, 0.03]) # axis for the slider slider1 = Slider(ax_slider_tresh,
Polygon Selector ================ Shows how to create a polygon programmatically or interactively """ import matplotlib.pyplot as plt from matplotlib.widgets import PolygonSelector ############################################################################### # # To create the polygon programmatically fig, ax = plt.subplots() fig.show() selector = PolygonSelector(ax, lambda *args: None) # Add three vertices selector.verts = [(0.1, 0.4), (0.5, 0.9), (0.3, 0.2)] ############################################################################### # # To create the polygon interactively fig2, ax2 = plt.subplots() fig2.show() selector2 = PolygonSelector(ax2, lambda *args: None) print("Click on the figure to create a polygon.") print("Press the 'esc' key to start a new polygon.")
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
polygonVertices = [(min(max(0, entry[0]), imageHandler.xMax), min(max(0, entry[1]), imageHandler.yMax)) for entry in polygonVertices] xPoints, yPoints = np.meshgrid(np.arange(outAveraged.shape[2]), np.arange(outAveraged.shape[1])) xPoints, yPoints = xPoints.flatten(), yPoints.flatten() points = np.vstack((xPoints, yPoints)).T polyPath = Path(polygonVertices) imageMask = polyPath.contains_points(points) imageHandler.imageMask = imageMask.reshape( (outAveraged.shape[1], outAveraged.shape[2])) imageHandler.boundaryPoly = polyPath poly = PolygonSelector(ax, PolySelection) plt.show() plt.close() # # outAveraged = outAveraged * imageHandler.imageMask + 1 for centerSlice in range(len(wavelengths)): CLFrame = outAveraged[centerSlice, :, :] backgroundPoints = getBackgroundPoints(CLFrame, 0.01) backgroundAverage = np.mean(backgroundPoints) outAveragedBlurred[centerSlice, :, :] = gaussian_filter( CLFrame, sigma=gaussianSigma, truncate=truncateWindow) + backgroundAverage / 2
def show_mask(prod, mask: np.ndarray) -> None: filter = (abs(prod.vh_image.mean() - (prod.vh_image.std( ) if prod.vh_image.mean() > 0.005 else prod.vh_image.min()))) min = 0.0 max = (prod.vh_image.mean() if prod.vv_image.mean() < prod.vh_image.mean() else prod.vh_image.mean()) # Update function for the PolygonSelector def onselect(verts): print("Creating Indices") # Path based on the verticies from the selection path = Path(verts) coords_pruned = prune(prod, verts) path_start = time.perf_counter() # Array of indices that are within the polygon ind = np.vstack( [[p[0] for p in coords_pruned if path.contains_point(p)], [p[1] for p in coords_pruned if path.contains_point(p)]]) path_end = time.perf_counter() print("Point in Polygon Time: ", path_end - path_start) mask_start = time.perf_counter() mask_edited = edit_mask_from_selection(mask, 1, verts, ind) mask_end = time.perf_counter() print("Mask Editing Time: ", mask_end - mask_start) return show_mask(prod, mask_edited) def update(val): show_mask(prod, create_mask(prod.vv_image, prod.vh_image, val)) mat = plt.matshow(mask) ax = plt.gca() # Calls onselect with an array of tuples defining the verticies of the polygon # Note: this is called any time the plot is clicked on! selector = PolygonSelector(plt.gca(), onselect) filter_slider = Slider(plt.axes([0.5, 0.025, 0.25, 0.04]), 'Filter', min, (max - min) / 2, valinit=filter, valstep=max / 10000) filter_slider.on_changed(update) button = Button(plt.axes([0.1, 0.025, 0.1, 0.04]), 'Save GeoTiff') button.on_clicked( lambda _: write_mask_to_file(mask, f'mask-{prod.mask_number}.tif', prod .projection, prod.geo_transform)) x = prod.vv_array y = prod.vh_array fig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True) axs[0].hist(x, bins=50) axs[1].hist(y, bins=50) plt.show()
def __init__( self, source=r"C:\Users\Molina\Documents\public\MATLAB\pupil\tracker\amph01_vid_15fps.mp4", export=False): # Hide private members. p = self.__private = Flexible() # Setup asynchronous video capture. p.stream = VideoCapture() p.stream.subscribe("grab", lambda stream: self.__onGrab()) # Show figure and wait for user interaction. if p.stream.open(source): p.nFrames = int(p.stream.get(cv.CAP_PROP_FRAME_COUNT)) p.fps = int(p.stream.get(cv.CAP_PROP_FPS)) p.resolution = np.array(p.stream.resolution) # width, height, 3 p.width = p.resolution[0].item() p.height = p.resolution[1].item() # Identify playback session. p.source = source sourcePL = Path(source) p.json = "%s/%s-annotations.json" % (str( sourcePL.parent), sourcePL.stem) p.csv = "%s/%s-tracking.csv" % (str( sourcePL.parent), sourcePL.stem) p.avi = "%s/%s-cropped.avi" % (str(sourcePL.parent), sourcePL.stem) p.timestamp = "%s" % datetime.datetime.now().strftime( "%Y%m%d%H%M%S%f") path = Path(p.source) p.session = path.stem # Initialize reusable matrices. Numpy expects images dimensions as (height, width, 3). p.raw = np.zeros((p.height, p.width, 3), np.uint8) p.rgb = np.zeros((p.height, p.width, 3), np.uint8) p.var = np.zeros((p.height, p.width, 3), np.uint8) p.processed = np.zeros((p.height, p.width, 3), np.uint8) # Initialize playback state. p.play = False p.run = True p.lock = Lock() # Setup graphics. p.figure = plt.figure() p.figure.canvas.set_window_title(source) p.figure.canvas.mpl_connect("key_press_event", self.__onKeyPress) p.figure.canvas.mpl_connect("close_event", self.__onClose) # Image inset. p.insetAxes = plt.axes() p.insetAxes.set_axis_off() p.insetImage = p.insetAxes.imshow(np.zeros((1, 1, 3), np.uint8)) # Initialize graphics. p.lastVertices = np.array([[0.07217742, -0.1916129], [-0.05201613, -0.24483871], [-0.00322581, -0.32763441], [0.05887097, -0.30989247]]) p.roiPolygonInset = plt.Polygon(p.lastVertices, closed=True, fill=False, linewidth=1, color="#FF0000") p.pupilPoints = plt.plot([], [], linestyle='None', marker='s', color="#0000FF", alpha=0.15)[0] p.pupilEllipse = Ellipse((0, 0), 1, 1, 0, edgecolor="#00FF00", facecolor="none", linewidth=2) p.roiSelector = PolygonSelector(p.insetAxes, lambda vertices: None) p.ellipseModel = EllipseModel() self.__setSelectorState(False) p.insetAxes.add_patch(p.roiPolygonInset) p.insetAxes.add_patch(p.pupilEllipse) # Mode: # bright: Brightest color down to a threshold. # dark: Darkest color up to a threshold. # cluster: Posterize and match an arbitrary color. # cluster for accuracy: Clustering method is GaussianMixture - heterogeneous covariances. # cluster for speed: Clustering method is k-means - homogeneous clusters. # Load saved session, if any. if Path(p.json).is_file(): with open(p.json) as f: entries = json.load(f) frame = entries["frame"] indices = entries["indices"] vertices = entries["vertices"] modes = entries["modes"] depths = entries["depths"] colors = entries["colors"] thresholds = entries["thresholds"] erosions = entries["erosions"] deltas = entries["deltas"] else: frame = 1 indices = [] vertices = [] modes = [] depths = [] colors = [] thresholds = [] erosions = [] deltas = [] p.indices = np.array(indices, dtype=np.uint32) p.vertices = [np.array(value) for value in vertices] p.modes = modes p.depths = depths p.colors = [np.array(value) for value in colors] p.thresholds = thresholds p.erosions = erosions p.deltas = deltas p.lastMode = "cluster:accuracy" if not modes else modes[-1] p.lastDepth = 5 if not depths else depths[-1] p.lastColor = Pupil.rgb2hsv([[255, 255, 255] ]) if not p.colors else p.colors[-1] p.lastThreshold = 0.5 if not p.thresholds else p.thresholds[-1] p.lastErosion = 0 if not p.erosions else p.erosions[-1] p.lastDelta = 0 if not p.deltas else p.deltas[-1] p.lastX = 0 p.lastY = 0 # Parsing states. p.videoWriter = cv.VideoWriter() p.addedIndex = -1 p.colorIndex = 0 p.showPosterization = True p.qHSV = np.zeros((p.lastDepth, 3), np.uint8) # Constants. p.kMeansCriteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 0.75) p.blurSizePixels = (9, 9) # Animate in the main thread. renderFrequency = 10 self.__animation = animation.FuncAnimation(fig=p.figure, func=self.__onRender, frames=1, interval=1000 / renderFrequency, repeat=True) # Run. plt.rcParams["keymap.all_axes"] = [ item for item in plt.rcParams["keymap.all_axes"] if item != 'a' ] plt.rcParams["keymap.save"] = [ item for item in plt.rcParams["keymap.save"] if item != 's' ] plt.rcParams["keymap.home"] = [ item for item in plt.rcParams["keymap.home"] if item != "home" ] plt.rcParams["keymap.back"] = [ item for item in plt.rcParams["keymap.back"] if item not in ['c', "left", "backspace"] ] plt.rcParams["keymap.forward"] = [ item for item in plt.rcParams["keymap.forward"] if item != "right" ] p.exporting = False p.closeWhenDone = False if export: # Export from the beginning. self.index = 1 if self.__export(): p.closeWhenDone = True p.stream.join() else: self.index = frame plt.show(block=True) # Release. p.stream.release() p.stream.join() if export: p.videoWriter.release() else: print("[error] Could not open video stream.")
def __init__(self, ax): self.canvas = ax.figure.canvas self.poly = PolygonSelector(ax, self.onselect) self.ind = []
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]