danforthcenter / plantcv

Plant phenotyping with image analysis
Mozilla Public License 2.0
667 stars 265 forks source link

Release 4.0 - Update code base to utilize Objects class #945

Closed HaleySchuhl closed 1 year ago

HaleySchuhl commented 2 years ago

Is your feature request related to a problem? Please describe. Objects and contours are pervasive cv2 concepts that would require a code base overhaul to update all at once. We want to break up this large change through multiple, smaller pull requests.

Describe the solution you'd like There are many places where "contours" and "hierarchies" are utilized, and we wish to update each of these instances to allow users to utilize the Objects class. Make sure to create branches and open PR's against the release-4.0 branch.

Make each function update it's own PR. Developers, please note here in this issue which functionality you are working on so that multiple people don't try to update the same function twice. Update the function inputs & outputs, document these params in .md files, update tests, and reflect param changes in updating.md. Add name when started, check off when finished.

List of Functionality to update

List of functions requiring iteration

Deprecating

Wait to fix tutorials until we are done breaking stuff

Additional context Add any other context, sample data, or code relevant to the feature request here.

HaleySchuhl commented 2 years ago

Naming conventions

HaleySchuhl commented 1 year ago
# Single plant workflow
from plantcv import plantcv as pcv

# Open image - no change from v3
img = pcv.readimage()

# Convert image (ex.) - no change from v3
gray_img = pcv.rgb2gray_hsv()

# Threshold/segment - no change from v3
bin_img = pcv.threshold.binary()

# Define ROI (ex.) - utilizes Objects
roi = pcv.roi.rectangle()

# Filter binary image to make a clean mask
# What if we take the ROI and mask?
mask = pcv.roi_objects(mask=bin_img, roi=roi, roi_type="partial")

# Create a labeled mask (background = 0, then increment
# by one for each object
# This function would run findContours on the input mask
# then iterate over the ROIs and run roi_objects
labeled_mask = pcv.create_labels(mask=mask, rois=roi)

# Then jump directly to analysis
# For object and bound, object composition happens internally
# find_contours is done automatically, internally per label
shape_img = pcv.analyze_object(img=img, mask=labeled_mask)
hline_img = pcv.analyze_bound_horizontal(img=img, mask=labeled_mask, line_position=600)
color_hist = pcv.analyze_color(rgb_img=img, mask=labeled_mask, colorspaces="hsv")
HaleySchuhl commented 1 year ago

Updates to pcv.roi_objects. No longer want to input Objects. Instead, just take a mask and find_objects behind the scenes. Reduce visualizations to just the clean mask. Return only clean_mask instead of lots of stuff.