diff --git a/examples/launch.py b/examples/launch.py index 9bc9b64..5e7d1bb 100644 --- a/examples/launch.py +++ b/examples/launch.py @@ -1,6 +1,5 @@ import os import napari -from segmentify import segmentation import numpy as np @@ -11,17 +10,6 @@ with napari.gui_qt(): viewer = napari.Viewer() - # instantiate the widget - gui = segmentation.Gui() - - # add our new widget to the napari viewer - viewer.window.add_dock_widget(gui) - - # keep the dropdown menus in the gui in sync with the layer model - viewer.layers.events.changed.connect(lambda x: gui.refresh_choices()) - - gui.refresh_choices() - # load data viewer.open(example_image) viewer.open(example_labels, layer_type='labels') diff --git a/segmentify/__init__.py b/segmentify/__init__.py index 3ec1fd0..5e45b20 100644 --- a/segmentify/__init__.py +++ b/segmentify/__init__.py @@ -1,9 +1,9 @@ -__version__ = '0.1.0' +from .segmentify import segmentation +from ._hookimpl import napari_experimental_provide_function_widget -from .gui import segmentation -from . import _key_bindings +# from . import _key_bindings -# Note that importing _key_bindings is needed as the Labels layer gets -# decorated with keybindings during that process, but it is not directly needed -# by our users and so is deleted below -del _key_bindings +# # Note that importing _key_bindings is needed as the Labels layer gets +# # decorated with keybindings during that process, but it is not directly needed +# # by our users and so is deleted below +# del _key_bindings diff --git a/segmentify/_hookimpl.py b/segmentify/_hookimpl.py new file mode 100644 index 0000000..5a7082f --- /dev/null +++ b/segmentify/_hookimpl.py @@ -0,0 +1,7 @@ +from napari_plugin_engine import napari_hook_implementation +from .segmentify import segmentation + + +@napari_hook_implementation +def napari_experimental_provide_function_widget(): + return (segmentation, {'call_button': "execute"}) diff --git a/segmentify/_key_bindings.py b/segmentify/_key_bindings.py index 9f90fbb..dbbe3e2 100644 --- a/segmentify/_key_bindings.py +++ b/segmentify/_key_bindings.py @@ -1,118 +1,118 @@ -from napari.layers.labels import Labels -import math -import os -from skimage import morphology, measure -from scipy import stats -from .util import erode_img - - -@Labels.bind_key('Shift-C') -def closing(self, layer): - """Apply the closing operation (key-binding: SHIFT-C) - - This function applies the closing operation by dilating the selected label - pixels, following by erosion - - Parameters - ---------- - layer : napari.layers.Labels - """ - dilation(layer) - erosion(layer) - - -@Labels.bind_key('Shift-O') -def opening(self, layer): - """Apply the opening operation (key-binding: SHIFT-O) - - This function applies the opening operation by eroding the selected label - pixels, following by dilation - - Parameters - ---------- - layer : napari.layers.Labels - """ - erosion(layer) - dilation(layer) - - -@Labels.bind_key('Shift-E') -def erosion(self, layer): - """Apply the erosion operation (key-binding: SHIFT-E) - - This function applies the erosion operation on selected label pixels - - Parameters - ---------- - layer : napari.layers.Labels - """ - labeled = extract_label(layer.data, layer.selected_label) - selem = morphology.selem.square(3) - processed_img = erode_img(layer.data, target_label=layer.selected_label) - merged = merge_label(processed_img, layer.data, layer.selected_label) - layer.data = merged - - -@Labels.bind_key('Shift-D') -def dilation(self, layer): - """Apply the dilation operation (key-binding: SHIFT-D) - - This function applies the dilation operation on selected label pixels - - Parameters - ---------- - layer : napari.layers.Labels - """ - labeled = extract_label(layer.data, layer.selected_label) - selem = morphology.selem.square(3) - processed_img = morphology.dilation(labeled, selem) - merged = merge_label(processed_img, layer.data, layer.selected_label) - layer.data = merged - - -@Labels.bind_key('Shift-F') -def fill_holes(self, layer): - """apply the fill holes operation (key-binding: SHIFT-D) - - This function applies the fill holes operation on the selected label pixels - - Parameters - ---------- - viewer : Segmentify Viewer - - Returns - ------- - The procssed image - """ - labeled = extract_label(layer.data, layer.selected_label) - if len(labeled.shape) > 2: - processed_imgs = [] - for i in range(labeled.shape[0]): - processed_img = morphology.remove_small_holes(labeled[i].astype(bool)).astype(int) - processed_imgs.append(processed_img) - processed_img = np.stack(processed_imgs, 0) - else: - processed_img = morphology.remove_small_holes(labeled.astype(bool)).astype(int) - merged = merge_label(processed_img, layer.data, layer.selected_label) - layer.data = merged - - -def extract_label(data, label): - """Extract data pixels with selected label""" - labeled = np.zeros_like(data) - labeled[data == label] = 1 - return labeled - - -def merge_label(processed, data, label): - """Extract data pixels with selected label""" - # merge processed image with original - stored_background_label = 1 - all_labels = np.unique(data) - if len(all_labels) == 2: - background_label = all_labels[all_labels != label][0] - data[(processed == 0) & (data == label)] = background_label - else: - data[(processed == 0) & (original == curr_label)] = stored_background_label - data[processed == 1] = curr_label - return data +# from napari.layers.labels import Labels +# import math +# import os +# from skimage import morphology, measure +# from scipy import stats +# from .util import erode_img + + +# @Labels.bind_key('Shift-C') +# def closing(self, layer): +# """Apply the closing operation (key-binding: SHIFT-C) + +# This function applies the closing operation by dilating the selected label +# pixels, following by erosion + +# Parameters +# ---------- +# layer : napari.layers.Labels +# """ +# dilation(layer) +# erosion(layer) + + +# @Labels.bind_key('Shift-O') +# def opening(self, layer): +# """Apply the opening operation (key-binding: SHIFT-O) + +# This function applies the opening operation by eroding the selected label +# pixels, following by dilation + +# Parameters +# ---------- +# layer : napari.layers.Labels +# """ +# erosion(layer) +# dilation(layer) + + +# @Labels.bind_key('Shift-E') +# def erosion(self, layer): +# """Apply the erosion operation (key-binding: SHIFT-E) + +# This function applies the erosion operation on selected label pixels + +# Parameters +# ---------- +# layer : napari.layers.Labels +# """ +# labeled = extract_label(layer.data, layer.selected_label) +# selem = morphology.selem.square(3) +# processed_img = erode_img(layer.data, target_label=layer.selected_label) +# merged = merge_label(processed_img, layer.data, layer.selected_label) +# layer.data = merged + + +# @Labels.bind_key('Shift-D') +# def dilation(self, layer): +# """Apply the dilation operation (key-binding: SHIFT-D) + +# This function applies the dilation operation on selected label pixels + +# Parameters +# ---------- +# layer : napari.layers.Labels +# """ +# labeled = extract_label(layer.data, layer.selected_label) +# selem = morphology.selem.square(3) +# processed_img = morphology.dilation(labeled, selem) +# merged = merge_label(processed_img, layer.data, layer.selected_label) +# layer.data = merged + + +# @Labels.bind_key('Shift-F') +# def fill_holes(self, layer): +# """apply the fill holes operation (key-binding: SHIFT-D) + +# This function applies the fill holes operation on the selected label pixels + +# Parameters +# ---------- +# viewer : Segmentify Viewer + +# Returns +# ------- +# The procssed image +# """ +# labeled = extract_label(layer.data, layer.selected_label) +# if len(labeled.shape) > 2: +# processed_imgs = [] +# for i in range(labeled.shape[0]): +# processed_img = morphology.remove_small_holes(labeled[i].astype(bool)).astype(int) +# processed_imgs.append(processed_img) +# processed_img = np.stack(processed_imgs, 0) +# else: +# processed_img = morphology.remove_small_holes(labeled.astype(bool)).astype(int) +# merged = merge_label(processed_img, layer.data, layer.selected_label) +# layer.data = merged + + +# def extract_label(data, label): +# """Extract data pixels with selected label""" +# labeled = np.zeros_like(data) +# labeled[data == label] = 1 +# return labeled + + +# def merge_label(processed, data, label): +# """Extract data pixels with selected label""" +# # merge processed image with original +# stored_background_label = 1 +# all_labels = np.unique(data) +# if len(all_labels) == 2: +# background_label = all_labels[all_labels != label][0] +# data[(processed == 0) & (data == label)] = background_label +# else: +# data[(processed == 0) & (original == curr_label)] = stored_background_label +# data[processed == 1] = curr_label +# return data diff --git a/segmentify/gui.py b/segmentify/segmentify.py similarity index 76% rename from segmentify/gui.py rename to segmentify/segmentify.py index d10835a..aa536c8 100644 --- a/segmentify/gui.py +++ b/segmentify/segmentify.py @@ -2,16 +2,13 @@ """ import numpy as np -from magicgui import magicgui -from napari import layers from .semantic import fit, predict from .util import Featurizers, norm_entropy -@magicgui(call_button="execute") -def segmentation(base_image: layers.Image, - initial_labels: layers.Labels, - featurizer:Featurizers) -> layers.Labels: +def segmentation(base_image: 'napari.layers.Image', + initial_labels: 'napari.layers.Labels', + featurizer:Featurizers) -> 'napari.layers.Labels': """Segment an image based on an initial labeling.""" print("Segmenting...") @@ -35,6 +32,6 @@ def segmentation(base_image: layers.Image, entropy = (entropy - np.min(entropy)) / np.ptp(entropy) entropy = np.squeeze(entropy) - print("... Completed") + print("... Completed") return np.squeeze(segmentation) diff --git a/setup.py b/setup.py index 3dbaf50..edfb7ad 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ def parse_requirements_file(filename): setup( name='segmentify', packages=find_packages(), - version='0.1.1', + version='0.2.0', description='Python image segmentation plugin.', maintainer='Nicholas Sofroniew', maintainer_email='sofroniewn@gmail.com', @@ -44,5 +44,9 @@ def parse_requirements_file(filename): ], install_requires=INSTALL_REQUIRES, include_package_data=True, - entry_points={}, + entry_points={ + 'napari.plugin': [ + 'segmentify = segmentify', + ], + }, )