Skip to content

Commit

Permalink
interactive_mask: add invert button
Browse files Browse the repository at this point in the history
  • Loading branch information
sitic committed Nov 7, 2023
1 parent 62a5747 commit 0b0bab7
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
1 change: 1 addition & 0 deletions optimap/assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Icons are from [Google Material Symbols](https://fonts.google.com/icons) and are licensed under [Apache License Version 2.0.](https://www.apache.org/licenses/LICENSE-2.0.txt).
Binary file added optimap/assets/invert_symbol.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 38 additions & 25 deletions optimap/image/_segmenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
REDO_SYMBOL = ASSETS_DIR / "redo_symbol.png"
VISIBILITY_ON_SYMBOL = ASSETS_DIR / "visibility_on_symbol.png"
VISIBILITY_OFF_SYMBOL = ASSETS_DIR / "visibility_off_symbol.png"

INVERT_SYMBOL = ASSETS_DIR / "invert_symbol.png"

class ImageSegmenter:
"""Manually segment an image with the lasso selector."""
Expand All @@ -41,17 +41,17 @@ def __init__( # type: ignore
.. table:: **Keyboard Shortcuts**
========================= ===========================
Key Action
========================= ===========================
========================= ===========================
Key Action
========================= ===========================
``Scroll`` Zoom in/out
``ctrl+z`` or ``cmd+z`` Undo
``ctrl+y`` or ``cmd+y`` Redo
``v`` Toggle visibility of mask
``e`` Erase mode
``d`` Draw/Lasso mode
``ctrl+z`` or ``cmd+z`` Undo
``ctrl+y`` or ``cmd+y`` Redo
``v`` Toggle visibility of mask
``e`` Erase mode
``d`` Draw/Lasso mode
``q`` Quit
========================= ===========================
========================= ===========================
Parameters
----------
Expand Down Expand Up @@ -153,17 +153,7 @@ def _setup_gui(self) -> None:
BUTTON_WIDTH = 0.05
BUTTON_SPACING = 0.025
pos = [0.22, 0.92, BUTTON_WIDTH, BUTTON_WIDTH]

self.ax_draw = self.fig.add_axes(pos)
self.button_draw = Button(self.ax_draw, "", image=Image.open(DRAW_SYMBOL))
self.button_draw.on_clicked(self._disable_erasing)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING
self.ax_erase = self.fig.add_axes(pos)
self.button_erase = Button(self.ax_erase, "", image=Image.open(ERASER_SYMBOL))
self.button_erase.on_clicked(self._enable_erasing)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING

ax_undo = self.fig.add_axes(pos)
self.button_undo = Button(ax_undo, "", image=Image.open(UNDO_SYMBOL))
self.button_undo.on_clicked(self._undo)
Expand All @@ -174,12 +164,29 @@ def _setup_gui(self) -> None:
self.button_redo.on_clicked(self._redo)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING
self.ax_visibility = self.fig.add_axes(pos)
self._ax_visibility = self.fig.add_axes(pos)
self.button_viz = Button(
self.ax_visibility, "", image=Image.open(VISIBILITY_ON_SYMBOL)
self._ax_visibility, "", image=Image.open(VISIBILITY_ON_SYMBOL)
)
self.button_viz.on_clicked(self._toggle_visibility)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING
ax_inverse = self.fig.add_axes(pos)
self.button_invert = Button(
ax_inverse, "", image=Image.open(INVERT_SYMBOL)
)
self.button_invert.on_clicked(self._inverse_mask)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING
ax_draw = self.fig.add_axes(pos)
self.button_draw = Button(ax_draw, "", image=Image.open(DRAW_SYMBOL))
self.button_draw.on_clicked(self._disable_erasing)

pos[0] += BUTTON_WIDTH + BUTTON_SPACING
ax_erase = self.fig.add_axes(pos)
self.button_erase = Button(ax_erase, "", image=Image.open(ERASER_SYMBOL))
self.button_erase.on_clicked(self._enable_erasing)

def _on_key_press(self, event):
if event.key == "ctrl+z" or event.key == "cmd+z":
self._undo()
Expand All @@ -201,9 +208,9 @@ def _disable_erasing(self, event=None):
def _toggle_visibility(self, event=None) -> None:
self._visible = not self._visible
if self._visible:
self.ax_visibility.images[0].set_data(Image.open(VISIBILITY_ON_SYMBOL))
self._ax_visibility.images[0].set_data(Image.open(VISIBILITY_ON_SYMBOL))
else:
self.ax_visibility.images[0].set_data(Image.open(VISIBILITY_OFF_SYMBOL))
self._ax_visibility.images[0].set_data(Image.open(VISIBILITY_OFF_SYMBOL))
self._draw_mask()

def _undo(self, event=None) -> None:
Expand All @@ -218,6 +225,12 @@ def _redo(self, event=None) -> None:
self.mask = self._mask_future.pop()
self._draw_mask()

def _inverse_mask(self, event=None) -> None:
self._mask_history.append(self._mask.copy())
self._mask_future.clear()
self.mask = np.logical_not(self.mask)
self._draw_mask()

def _draw_mask(self) -> None:
if self._visible:
self._mask_im.set_data(self._mask)
Expand Down

0 comments on commit 0b0bab7

Please sign in to comment.