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

add save_counts and save_coords methods #22

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
159142a
add save_counts and save_coords methods
HaleySchuhl May 6, 2024
f42e7ff
update variable name in .save_coords and fix syntax
HaleySchuhl May 6, 2024
e836c07
write test for save_coords
HaleySchuhl May 6, 2024
52e890a
no need to enumerate
HaleySchuhl May 6, 2024
e07dee0
Merge branch 'main' into add_saving_methods
HaleySchuhl May 7, 2024
6a98b54
Update test_annotate_points.py
HaleySchuhl May 7, 2024
eaf93bf
Merge branch 'add_saving_methods' of https://github.com/danforthcente…
HaleySchuhl May 7, 2024
5e96360
add test for save_counts which I forgot
HaleySchuhl May 7, 2024
4b2f862
deepsource iterate dictionary
HaleySchuhl May 7, 2024
22e23ff
remove unused code from new test
HaleySchuhl May 7, 2024
fe9a092
whitespace deepsource
HaleySchuhl May 7, 2024
7585393
wrong place
HaleySchuhl May 7, 2024
cf2b959
deepsource dictionary iteration
HaleySchuhl May 7, 2024
b0e6441
update sample with "class label" and remove unused label
HaleySchuhl May 8, 2024
117fd4b
remove unused import
HaleySchuhl May 8, 2024
f2f2c6c
Merge branch 'main' into add_saving_methods
HaleySchuhl May 17, 2024
c48e1ed
add doc page for save_coords and save_counts
HaleySchuhl May 17, 2024
5d92c55
Update mkdocs.yml
HaleySchuhl May 17, 2024
c571456
move content into the same doc page for style matching
HaleySchuhl Jun 4, 2024
0b63e6f
Delete points_save.md
HaleySchuhl Jun 4, 2024
1c19864
no longer planning to link out for now
HaleySchuhl Jun 4, 2024
6dc1f67
Merge branch 'main' into add_saving_methods
HaleySchuhl Oct 9, 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
83 changes: 80 additions & 3 deletions docs/Points.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ closest collected point.

- **Context:**
- Used to define a list of coordinates of interest.
-
- **Example use:**
- (pcv.roi.multi)
- (pcv.roi.custom)
- pcv.roi.multi
- pcv.roi.custom


```python
Expand All @@ -45,5 +44,83 @@ roi = pcv.roi.custom(img=img, vertices=marker.coords['default'])

```

**plantcv.annotate.Points.save_coords**()

- **Context:**
- Once point annotations are collected, save the list of coordinates with their class label to Outputs and later saved out to file

**plantcv.annotate.Points.save_counts**()

- **Context:**
- Once point annotations are collected, save the dictionary of counts with their class label to Outputs and later saved out to file

- **Example use:**
- Remove noise from a microscopy image that is otherwise difficult to filter out with traditional computer vision
techniques, and recover stomata that were filtered out during mask cleaning.

**Original Image with Annotations: "total" pollen**

![Screenshot](img/documentation_images/points_save/all_pollen.png)

**Original Image with Annotations: "germinated" pollen**

![Screenshot](img/documentation_images/points_save/germinated_pollen.png)

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

# Create an instance of the Points class
img, path, name = pcv.readimage("stomata.tif")

# Segmentation & mask clean up steps here

# Create an instance of the Points class & click on stomata
marker = pcvan.Points(img=img, figsize=(12,6))

marker.save_coords()
marker.save_counts()

pcv.outputs.observations

{'total': {'coordinates': {'trait': 'collected coordinates',
'method': 'annotation',
'scale': 'none',
'datatype': "<class 'list'>",
'value': [(113, 58),
(353, 105),
(74, 240),
(103, 297),
(278, 333),
(185, 350),
(237, 335),
(244, 285),
(300, 192),
(295, 151),
(262, 178),
(321, 44),
(187, 158),
(160, 187),
(65, 186)],
'label': 'none'},
'object_count': {'trait': 'count of category',
'method': 'count',
'scale': 'count',
'datatype': "<class 'int'>",
'value': 15,
'label': 'none'}},
'germinated': {'coordinates': {'trait': 'collected coordinates',
'method': 'annotation',
'scale': 'none',
'datatype': "<class 'list'>",
'value': [(64, 186), (244, 286)],
'label': 'none'},
'object_count': {'trait': 'count of category',
'method': 'count',
'scale': 'count',
'datatype': "<class 'int'>",
'value': 2,
'label': 'none'}}}
```

**Source Code:** [Here](https://github.com/danforthcenter/plantcv-annotate/blob/main/plantcv/annoate/classes.py)
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.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ nav:
- Napari Read Coor: napari_read_coor.md
- Napari Save Coor: napari_save_coor.md
- Points: Points.md
- Points Save: points_save.md
- Get Centroids: get_centroids.md
markdown_extensions:
- toc:
Expand Down
20 changes: 19 additions & 1 deletion plantcv/annotate/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import json
from math import floor
import matplotlib.pyplot as plt
from plantcv.plantcv import warn, outputs
from plantcv.plantcv.annotate.points import _find_closest_pt
from plantcv.plantcv import warn


class Points:
Expand Down Expand Up @@ -79,6 +79,24 @@ def print_coords(self, filename):
# Save the data in JSON format with indentation
json.dump(obj=self.coords, fp=fp, indent=4)

def save_counts(self):
"""Save collected coordinates to Outputs.observations"""
for key in self.count:
value = self.count[key]
outputs.add_observation(sample=key, variable="object_count",
trait='count of category',
method='count', scale='count', datatype=int,
value=value, label='none')

def save_coords(self):
"""Save collected coordinates to Outputs.observations"""
for key in self.count:
value = self.coords[key]
outputs.add_observation(sample=key, variable="coordinates",
trait='collected coordinates',
method='annotation', scale='none', datatype=list,
value=value, label='none')

def import_list(self, coords, label="default"):
"""Import coordinates.

Expand Down
20 changes: 20 additions & 0 deletions tests/test_annotate_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cv2
import matplotlib
from plantcv.annotate.classes import Points
from plantcv.plantcv import outputs


def test_points(test_data):
Expand Down Expand Up @@ -157,3 +158,22 @@ def test_points_view_warn(test_data):
drawer_rgb.view(label="new", color='r')

assert str(drawer_rgb.fig) == "Figure(500x500)"

def test_points_save_coords(test_data):
img = cv2.imread(test_data.small_rgb_img)
drawer = Points(img=img)
# Populate attribute with coords
totalpoints1 = [(158, 531), (361, 112), (500, 418)]
drawer.coords = {'default': totalpoints1}
drawer.save_coords()

assert outputs.observations["default"]["coordinates"]["value"] == [(158, 531), (361, 112), (500, 418)]

def test_points_save_counts(test_data):
img = cv2.imread(test_data.small_rgb_img)
drawer = Points(img=img)
# Populate attribute with coords
drawer.count = {'default': 1}
drawer.save_counts()

assert outputs.observations["default"]["object_count"]["value"] == 1