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

Bug in logic behind roi_type="largest" option inside pcv.roi.filter #1507

Closed
HaleySchuhl opened this issue May 1, 2024 · 0 comments · Fixed by #1518
Closed

Bug in logic behind roi_type="largest" option inside pcv.roi.filter #1507

HaleySchuhl opened this issue May 1, 2024 · 0 comments · Fixed by #1518
Assignees
Labels
help wanted Request help
Projects
Milestone

Comments

@HaleySchuhl
Copy link
Contributor

HaleySchuhl commented May 1, 2024

Describe the bug
A bug was found in some applications of roi_type="largest" within the pcv.roi.filter function recently, uncovered by @sdkenney42 . Instead of returning the largest object in the mask it was consistently returning the second largest object for a specific image. We did a little digging into the function at lab meeting. The logic behind this function is unsound because it is checking the length of a contour rather than actually filtering on contour size. One option for updating _helpers.py instead of checking the length at line 96 we should actually judge by contour area.

To Reproduce

%matplotlib widget 

from plantcv import plantcv as pcv 
import numpy as np 
import cv2

# Make a blank mask
mask = np.zeros((1000,1000), dtype=np.uint8)
start_point = (10, 10) 
end_point = (110,110) 
# Draw 100x100 pixel square 
mask = cv2.rectangle(mask, start_point, end_point, 255, -1) 
#pcv.plot_image(mask) 

# Calculate radius (based on h=100 in our square) that will give nearly equal areas 
circle_r = int(100/np.sqrt(np.pi)) + 1
#print(circle_r)
mask = cv2.circle(mask, (500,500), circle_r, 255, -1) # circle with radius of 3

roi = pcv.roi.rectangle(img=mask, x=1, y=1, h=49, w=49)

pcv.params.debug = "plot" 
filtered_mask = pcv.roi.filter(mask=mask, roi=roi, roi_type='largest')  # Square gets kept 
vis = pcv.visualize.obj_sizes(img=mask, mask=mask)  # But the area of the circle is larger 

Expected behavior
A clear and concise description of what you expected to happen.

Local environment (please complete the following information):

  • OS: [macOS]
  • Environment [conda.]
  • PlantCV Version [main branch 4.2.2.dev432+g8844cfc8.d20240426 ]

Additional context
I believe len(contour) is more equivalent to taking the perimeter vs the area. Instead need to judge which contour to keep with more sound logic, perhaps the solution below.

c = max(contours, key = cv2.contourArea)

or ID the largest contour after filtering on ROI, and then pcv.fill anything smaller than the known largest object size.

@HaleySchuhl HaleySchuhl added the help wanted Request help label May 1, 2024
@HaleySchuhl HaleySchuhl self-assigned this May 9, 2024
@HaleySchuhl HaleySchuhl added this to New Issues in PlantCV4 via automation May 9, 2024
@HaleySchuhl HaleySchuhl added this to the PlantCV v4.3 milestone May 9, 2024
PlantCV4 automation moved this from New Issues to Done May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Request help
Projects
PlantCV4
  
Done
Development

Successfully merging a pull request may close this issue.

1 participant