diff --git a/README.md b/README.md index 9924bfa..965a7e1 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ empanada-napari works with python=3.9 or lower It's recommended to have installed napari through [conda](https://docs.conda.io/en/latest/miniconda.html). Then to install this plugin: ```shell -pip install empanada-napari==1.1.0 +pip install empanada-napari==1.1.1 ``` Launch napari: @@ -68,7 +68,7 @@ pip uninstall empanada-napari Then install the newest version: ```shell -pip install empanada-napari==1.1.0 +pip install empanada-napari==1.1.1 ``` diff --git a/empanada_napari/_filter_small_labels.py b/empanada_napari/_filter_small_labels.py index 723f0c2..f5b88b6 100644 --- a/empanada_napari/_filter_small_labels.py +++ b/empanada_napari/_filter_small_labels.py @@ -104,9 +104,18 @@ def widget( plane = viewer.dims.current_step[0] if remove_opt == 'Small labels': - labels[plane], labels_removed = filter_out_small_label_areas(labels[plane], min_area) + labels_, labels_removed = filter_out_small_label_areas(labels[plane] if labels.ndim > 2 else labels, min_area) + if labels.ndim > 2: + labels[plane] = labels_ + + else: + labels = labels_ elif remove_opt == 'Boundary labels': - labels[plane], labels_removed = remove_boundary_labels(labels[plane]) + labels_, labels_removed = remove_boundary_labels(labels[plane] if labels.ndim > 2 else labels) + if labels.ndim > 2: + labels[plane] = labels_ + else: + labels = labels_ elif labels.ndim == 3 and apply_to == '2D patches': for label in tqdm(range(labels.shape[0])): diff --git a/empanada_napari/_label_counter_widget.py b/empanada_napari/_label_counter_widget.py index 17a413c..a28cb2b 100644 --- a/empanada_napari/_label_counter_widget.py +++ b/empanada_napari/_label_counter_widget.py @@ -110,9 +110,9 @@ def count_labels(label_values, label_divisor): class_ids = np.unique(np.floor_divide(label_values, label_divisor)).tolist() for ci in class_ids: - min_id = ci * label_divisor + 1 + min_id = ci * label_divisor max_id = (ci + 1) * label_divisor - label_ids = label_values[np.logical_and(label_values >= min_id, label_values < max_id)] + label_ids = label_values[(label_values >= min_id) & (label_values < max_id)] label_queue[ci] = label_ids.tolist() return label_queue, class_ids @@ -161,6 +161,7 @@ def widget( if export_xlsx: # folder_name = f'{labels_layer.name}_label_ids' folder_path = os.path.join(save_dir, folder_name) + # Create the save directory if it doesn't exist save_dir = folder_path if not os.path.exists(save_dir): @@ -174,20 +175,60 @@ def widget( labels = labels_layer.data + def _get_current_image(labels_layer): + cursor_pos = viewer.cursor.position + + labels_ = labels_layer.data + + y, x = 0, 0 + if labels.ndim == 4: + axis = tuple(viewer.dims.order[:2]) + plane = ( + int(labels_layer.world_to_data(cursor_pos)[axis[0]]), + int(labels_layer.world_to_data(cursor_pos)[axis[1]]) + ) + + slices = [slice(None), slice(None), slice(None), slice(None)] + + slices[axis[0]] = plane[0] + slices[axis[1]] = plane[1] + + elif labels.ndim == 3: + axis = viewer.dims.order[0] + plane = int(labels_layer.world_to_data(cursor_pos)[axis]) + + slices = [slice(None), slice(None), slice(None)] + slices[axis] = plane + + else: + slices = [slice(None), slice(None)] + axis = None + plane = None + + labels_slice = labels_[tuple(slices)] + unique_labels = np.unique(labels_slice) + + return labels_slice, unique_labels, axis, plane, y, x + if labels.ndim > 2 and label_type == 'Current image': - # assert viewer.dims.order[0] == 0, "Must be viewing axis 0 (xy plane)!" plane = viewer.dims.current_step[0] + # print(f'Viewing plane: {plane}') else: plane = 'null' if plane != 'null': - labels = labels[plane] + label_slice, unique_labels, axis, plane, y, x = _get_current_image(labels_layer) + labels = unique_labels class_names = {} for seg_class in label_text.split(): class_id, class_name = seg_class.split(',') class_num = class_id.strip() class_name = class_name.strip() + + if not class_num.isdigit(): + print(f'The class number you entered is invalid. Please provide an integer value!') + return class_names[int(class_num)] = class_name print(f'Class names: {class_names}') diff --git a/empanada_napari/_volume_inference.py b/empanada_napari/_volume_inference.py index 5a8e01d..2e6c49c 100644 --- a/empanada_napari/_volume_inference.py +++ b/empanada_napari/_volume_inference.py @@ -4,7 +4,7 @@ from napari.layers import Image from napari_plugin_engine import napari_hook_implementation from magicgui import magicgui, widgets -#from qtpy.QtWidgets import QScrollArea +from qtpy.QtWidgets import QScrollArea def volume_inference_widget(): from napari.qt.threading import thread_worker @@ -48,7 +48,7 @@ def orthoplane_inference(engine, volume): label_head=dict(widget_type='Label', label=f'

'), call_button='Run 3D Inference', layout='vertical', - #scrollable=True, + scrollable=True, model_config=dict(widget_type='ComboBox', label='model', choices=list(model_configs.keys()), value=list(model_configs.keys())[0], tooltip='Model to use for inference'), use_gpu=dict(widget_type='CheckBox', text='Use GPU', value=device_count() >= 1, tooltip='If checked, run on GPU 0'), @@ -318,12 +318,13 @@ def start_consensus_worker(trackers_dict): pbar.show() # make the scroll available - #scroll = QScrollArea() - #scroll.setWidget(widget._widget._qwidget) - #widget._widget._qwidget = scroll + scroll = QScrollArea() + scroll.setWidget(widget._widget._qwidget) + widget._widget._qwidget = scroll return widget + @napari_hook_implementation(specname='napari_experimental_provide_dock_widget') def volume_dock_widget(): - return volume_inference_widget, {'name': '3D Inference'} \ No newline at end of file + return volume_inference_widget, {'name': '3D Inference'} diff --git a/requirements.txt b/requirements.txt index 868ef14..88d099c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ -napari[all]>=0.4.15 +opencv-python==4.9.0.80 +opencv-python-headless==4.9.0.80 +napari[all]==0.4.18 scikit-image>=0.18 empanada-dl>=0.1.5 napari-plugin-engine>=0.1.4 imagecodecs +numba==0.59.0 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index a3b1b41..15e8e45 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = empanada-napari -version = 1.1.0 +version = 1.1.1 author = Madeline Barry, Abhishek Bhardwaj, Ryan Conrad author_email = abhishek.bhardwaj@nih.gov url = https://github.com/volume-em/empanada-napari @@ -33,11 +33,14 @@ setup_requires = setuptools_scm include_package_data = True # add your package requirements here install_requires = - napari>=0.4.16 + opencv-python==4.9.0.80 + opencv-python-headless==4.9.0.80 + napari==0.4.18 numpy==1.22 napari-plugin-engine>=0.1.4 scikit-image>=0.19 empanada-dl>=0.1.7 + numba==0.59.0 imagecodecs openpyxl imagehash