Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Napari join labels #13

Merged
merged 56 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
95f0ff2
added napari_keys function and test
maliagehan Mar 8, 2024
6b2608d
wrote tests.
maliagehan Mar 11, 2024
57c480f
made napari_label_classes more general
maliagehan Mar 12, 2024
ee6628d
fixed line length
maliagehan Mar 18, 2024
9a653f7
added napari_keys function and test
maliagehan Mar 8, 2024
53be1e5
wrote tests.
maliagehan Mar 11, 2024
b2e7fe8
made napari_label_classes more general
maliagehan Mar 12, 2024
65e55c7
fixed line length
maliagehan Mar 18, 2024
6020c80
add napari_open docs
maliagehan Mar 27, 2024
a3e224a
Merge branch 'napari-join-labels' of https://github.com/danforthcente…
maliagehan Mar 27, 2024
1585fdb
rename napari_keys to napari_classes
maliagehan Mar 27, 2024
8916e49
update docs for napari_label_classes
maliagehan Mar 27, 2024
2a464e3
adding dependencies
maliagehan Mar 27, 2024
99644a1
install dependencies
maliagehan Mar 27, 2024
e874cc9
fixed deepsource
maliagehan Mar 27, 2024
77c0ddb
deepsource complexity fix
maliagehan Mar 27, 2024
f42a315
Update napari_open.py
maliagehan Mar 27, 2024
3d2c16e
Update pyproject.toml
maliagehan Mar 27, 2024
5899f0f
Update pyproject.toml
maliagehan Mar 27, 2024
a736b68
Delete test_annotate.py
maliagehan Mar 27, 2024
1c9edd9
adding show for tests
maliagehan Mar 28, 2024
a72c963
update tests
maliagehan Mar 28, 2024
ec25b78
Update pyproject.toml
maliagehan Mar 28, 2024
4a2f82c
Update pyproject.toml
maliagehan Mar 28, 2024
7cffaa3
Update pyproject.toml
maliagehan Mar 28, 2024
f653fc3
Update pyproject.toml
maliagehan Mar 28, 2024
8e13ece
Update pyproject.toml
maliagehan Mar 28, 2024
f8a04cd
Add pytest-xvfb to test environment
nfahlgren Mar 28, 2024
970b033
Install system dependencies for handling displays
nfahlgren Mar 28, 2024
f48cbbc
Update continuous-integration.yml
maliagehan Mar 28, 2024
a3e5b83
Merge branch 'napari-join-labels' of https://github.com/danforthcente…
maliagehan Mar 28, 2024
968d25d
Update pyproject.toml
maliagehan Mar 28, 2024
a8a6990
Update continuous-integration.yml
maliagehan Mar 29, 2024
abc27cc
Update continuous-integration.yml
maliagehan Mar 29, 2024
0c0f38d
refactoring tests
maliagehan Mar 29, 2024
239379f
Update napari_open.py
maliagehan Mar 29, 2024
6843253
tests
maliagehan Mar 29, 2024
86115b4
update CI and toml
maliagehan Apr 1, 2024
838c2b8
refactoring functions back to how they were
maliagehan Apr 1, 2024
a3dc1b9
unused code
maliagehan Apr 1, 2024
d0835aa
refactoring to add show as an option
maliagehan Apr 1, 2024
4a03bc2
napari join label function
maliagehan Apr 2, 2024
e629d9b
Update napari_join_labels.py
maliagehan Apr 2, 2024
9ad45ff
working on tests
maliagehan Apr 2, 2024
5082ad1
Update test_napari_join_labels.py
maliagehan Apr 2, 2024
2371511
Update napari_join_labels.py
maliagehan Apr 2, 2024
cdff1ff
printed image adjusted
maliagehan Apr 2, 2024
f90801c
remove images
maliagehan Apr 11, 2024
b2daf46
Update test_napari_join_labels.py
maliagehan Apr 12, 2024
444919e
Update continuous-integration.yml
maliagehan Apr 12, 2024
ba0c941
Fix minor typos
k034b363 Apr 15, 2024
d029275
Merge branch 'main' into napari-join-labels
nfahlgren May 6, 2024
3dab75c
Omit temp files created during opencv install
nfahlgren May 6, 2024
6db3130
Add missing section header
nfahlgren May 6, 2024
3460b84
Restore license
nfahlgren May 6, 2024
73ce255
Minor formatting changes
nfahlgren May 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python-version }}

DISPLAY: ':99.0'
steps:
- uses: actions/checkout@main
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -30,19 +30,27 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends libyaml-dev libegl1-mesa libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 xserver-xephyr xvfb
python -m pip install --upgrade pip
pip install flake8 pytest pytest-cov ipython
pip install flake8 pytest pytest-cov pytest-qt pytest-xvfb ipython anyio
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test and generate coverage report
- uses: tlambert03/setup-qt-libs@v1
- name: Install plantcv-annotate
# Run coverage analysis on pytest tests
run: |
pip install .
py.test --cov-report=xml --cov=./
pip uninstall -y opencv-python
pip install opencv-python-headless
- name: Tests
uses: aganders3/headless-gui@v2
with:
run: pytest --cov-report=xml --cov=./
- name: Upload coverage to Deepsource
uses: deepsourcelabs/test-coverage-action@master
with:
Expand Down
373 changes: 0 additions & 373 deletions LICENSE

This file was deleted.

2 changes: 1 addition & 1 deletion docs/Points.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Interactive Point Annotation Tool

Using [Jupyter Notebooks](jupyter.md) it is possible to interactively click to collect coordinates from an image, which can be used in various downstream applications. Left click on the image to collect a point. Right click removes the
Using [Jupyter Notebooks](https://plantcv.readthedocs.io/en/stable/jupyter/) it is possible to interactively click to collect coordinates from an image, which can be used in various downstream applications. Left click on the image to collect a point. Right click removes the
closest collected point.

**plantcv.annotate.Points**(*img, figsize=(12,6), label="dafault"*)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions docs/napari_classes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
## Open Image with Napari

Get class names from Napari Viewer Object.

**plantcv.annotate.napari_classes**(*viewer*)

**returns** list of napari classes

- **Parameters:**
- viewer - Napari viewer object

- **Context:**
- Get names of Napari classes. This is mainly an internal function but can be useful in other context.

- **Example use:**
- Get names of Napari classes/labels.


```python
import plantcv.plantcv as pcv
import plantcv.annotate as pcvan

# Create an instance of the Points class
img, path, name = pcv.readimage("./grayimg.png")

viewer = pcvan.napari_label_classes(img=img, classes=['background', 'wing', 'seed'])

classes = pcvan.napari_classes(viewer)

```

**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annotate/napari_classes.py)
45 changes: 45 additions & 0 deletions docs/napari_join_labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Join Labels with Napari

This function joins classes with the same label. This function would be run after classes are labeled with napari_label_classes.

**plantcv.annotate.napari_join_labels*(*img, viewer*)

**returns** relabeled mask, dictionary of masks for each class

- **Parameters:**
- img - image data (compatible with gray, RGB, and hyperspectral data. If data is hyperspecral it should be the array e.g. hyperspectral.array_data)
- viewer - viewer with labeled classes. If no points are selected for a class,
data without labels will default to this class when napari_join_labels
is run. If all classes have points labeled, any clusters not labeled
will default to the last class in the list if napari_join_labels is
run.

- **Context:**
- This function would be run after labeling classes in Napari is complete.

- **Example use:**
- Joining classes labeled as the same, for example for joining classes from output of kmeans clustering


```python
import plantcv.plantcv as pcv
import plantcv.annotate as pcvan
import napari

# Create an instance of the Points class
img, path, name = pcv.readimage("./grayimg.png")

viewer = pcvan.napari_label_classes(img=img, ['background', 'wing','seed'])

# Should open interactive napari viewer

labeledmask, mask_dict = pcvan.napari_join_lables(img=img, viewer=viewer)

```

![Screenshot](img/documentation_images/napari_label_classes/napari_label_classes.png)

![Screenshot](img/documentation_images/napari_join_labels/1_labeled_mask.png)


**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annotate/napari_label_classes.py)
43 changes: 43 additions & 0 deletions docs/napari_label_classes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## Label Image with Napari

This function opens an image in Napari and then defines a set of classes to label. A random shape label is assigned to each class.
Image can be annotated as long as viewer is open.

**plantcv.annotate.napari_label_classes*(*img, classes, show=True*)

**returns** napari viewer object

- **Parameters:**
- img - image data (compatible with gray, RGB, and hyperspectral data. If data is hyperspecral it should be the array e.g. hyperspectral.array_data)
- classes - list of classes to label. If no points are selected for a class,
data without labels will default to this class when napari_join_labels
is run. If all classes have points labeled, any clusters not labeled
will default to the last class in the list if napari_join_labels is
run.
- show - if show = True, viewer is launched. False setting is useful for test purposes.

- **Context:**
- Adding class labels to images. Works best on an image that has objects segmented/classified with contours/clusters labeled with values (e.g. labeled mask, output of kmeans clustering).

- **Example use:**
- Labeling output of kmeans clustering into classes. Labeling points.


```python
import plantcv.plantcv as pcv
import plantcv.annotate as pcvan
import napari

# Create an instance of the Points class
img, path, name = pcv.readimage("./grayimg.png")

viewer = pcvan.napari_label_classes(img=img, classes=['background', 'wing','seed'])

# Should open interactive napari viewer

```

![Screenshot](img/documentation_images/napari_label_classes/napari_label_classes.png)


**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annotate/napari_label_classes.py)
36 changes: 36 additions & 0 deletions docs/napari_open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
## Open Image with Napari

Open image data (e.g. RGB, gray, hyperspectral) with an interactive Napari viewer. If a gray image is opened, the image will be pseudocolored for better visualization.

**plantcv.annotate.napari_open**(*img, show=True*)

**returns** napari viewer object

- **Parameters:**
- img - image data (compatible with gray, RGB, and hyperspectral data. If data is hyperspecral it should be the array e.g. hyperspectral.array_data)
- show - if show = True, viewer is launched. False setting is useful for test purposes.

- **Context:**
- Used to open image data with Napari.

- **Example use:**
- Open image data to annotate it with other Napari functions (e.g. napari_label_classes)


```python
import plantcv.plantcv as pcv
import plantcv.annotate as pcvan

# Create an instance of the Points class
img, path, name = pcv.readimage("./grayimg.png")

viewer = pcvan.napari_open(img=img)

# Should open interactive napari viewer

```

![Screenshot](img/documentation_images/napari_open/napari_open.png)


**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annotate/napari_open.py)
33 changes: 33 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# run: conda env create --file environment.yml
# optionally, change channel name with -n {plantcv-dev}
name: plantcv
dependencies:
- python=3.10
- matplotlib>=1.5
- numpy>=1.11
- pandas
- python-dateutil
- scipy
- scikit-image>=0.19
- scikit-learn
- dask
- dask-jobqueue
- opencv
- statsmodels
- xarray>=2022.11.0
- mkdocs
- pytest
- pytest-cov
- flake8
- ipympl
- nodejs
- jupyterlab
- altair
- vl-convert-python
- napari
- pyqt
- pytest-qt

channels:
- conda-forge
- defaults
5 changes: 5 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ nav:
- 'Adding/Editing Documentation': documentation.md
- 'PlantCV Namespace':
- 'Annotation Tools':
- Napari Classes: napari_classes.md
- Napari Join: napari_join_labels.md
- Napari Label: napari_label_classes.md
- Napari Open: napari_open.md
- Points: Points.md

markdown_extensions:
- toc:
permalink: True
Expand Down
12 changes: 12 additions & 0 deletions plantcv/annotate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from plantcv.annotate.napari_classes import napari_classes
from plantcv.annotate.napari_open import napari_open
from plantcv.annotate.napari_label_classes import napari_label_classes
from plantcv.annotate.napari_join_labels import napari_join_labels


__all__ = [
"napari_classes",
"napari_open",
"napari_label_classes",
"napari_join_labels"
]
31 changes: 31 additions & 0 deletions plantcv/annotate/napari_classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Get Napari Keys

import re


def napari_classes(viewer):
"""
get names of napari keys

Inputs:
viewer = napari viewer object

Returns:
classes = napari class value names

:param viewer: napari.viewer.Viewer
:return labels: numpy.ndarray, list
"""
keylist = list(viewer.layers)
keylist = ''.join(str(keylist))
keylist = keylist.split(',')

classes = []
for x in keylist:
if re.search('Image layer', x):
pass
else:
y = x.split(" ")
classes.append(y[3].strip("\'"))

return classes
Loading