plantcv
plantcv copied to clipboard
Multi ROI
Hello Everyone, Is there any way of doing multi ROI plot with a customized ROI option?
Thanks
Hi @ozgurculfa, am I understanding correctly that you are looking to use pcv.roi.custom
but to create multiple ROIs?
It is possible to create custom placed ROIs (but only circles) with pcv.roi.multi
, but not yet possible to have pcv.roi.custom
create multiple ROIs.
Technically you could make this work by semi-manually building a multi-ROI object like this:
from plantcv import plantcv as pcv
# Read RGB image
img, imgpath, imgname = pcv.readimage(filename="myimage.png")
# Convert to grayscale
gray_img = pcv.rgb2gray_lab(rgb_img=img, channel="a")
# Threshold to segment
bin_img = pcv.threshold.otsu(gray_img=gray_img, object_type="dark")
# Create empty ROIs object
rois = pcv.Objects()
# Create custom ROI 1 and append to rois
roi = pcv.roi.custom(img=img, vertices=[(338, 578), (591, 589), (580, 804), (354, 804)])
rois.append(contour=roi.contours[0], h=roi.hierarchy[0])
# Create custom ROI 2 and append to rois
roi = pcv.roi.custom(img=img, vertices=[(1632, 1057), (1900, 1078), (1890, 1294), (1637, 1272)])
rois.append(contour=roi.contours[0], h=roi.hierarchy[0])
# Create a labeled mask for the 2 ROIs
lbl_mask, num = pcv.create_labels(mask=bin_img, rois=rois)
Hi Noah, Thank you so much for your reply. I was able to get multi roi images finally. But would you be able to tell me how to analyze each roi ? I am trying to get the integral of each roi separately but I was not able to save and load data for that purpose. I appreciate your help. Thanks again, Ozgur
Hi Ozgur,
The built-in analysis methods in PlantCV will all iterate over each ROI, but I think you are looking to store a custom measurement if I understand correctly.
We do not have a user method for using multiple ROIs like that (but it is an interesting idea).
In the meantime, it is possible to use the same method we use for iteration in our analysis functions directly. Here's an example using an extension of the code above:
import numpy as np
from plantcv import plantcv as pcv
from plantcv.plantcv._helpers import _iterate_analysis
# Read RGB image
img, imgpath, imgname = pcv.readimage(filename="myimage.png")
# Convert to grayscale
gray_img = pcv.rgb2gray_lab(rgb_img=img, channel="a")
# Threshold to segment
bin_img = pcv.threshold.otsu(gray_img=gray_img, object_type="dark")
# Create empty ROIs object
rois = pcv.Objects()
# Create custom ROI 1 and append to rois
roi = pcv.roi.custom(img=img, vertices=[(338, 578), (591, 589), (580, 804), (354, 804)])
rois.append(contour=roi.contours[0], h=roi.hierarchy[0])
# Create custom ROI 2 and append to rois
roi = pcv.roi.custom(img=img, vertices=[(1632, 1057), (1900, 1078), (1890, 1294), (1637, 1272)])
rois.append(contour=roi.contours[0], h=roi.hierarchy[0])
# Create a labeled mask for the 2 ROIs
lbl_mask, num = pcv.create_labels(mask=bin_img, rois=rois)
# Create a function to do one or more custom measurements
# The function must have the inputs img, mask, label
def my_func(img, mask, label):
# Custom measurement example
px_count = np.count_nonzero(mask)
# Store the custom measurement
pcv.outputs.add_observation(sample=label, variable='px_count', trait='pixel count',
method='custom', scale='pixels', datatype=int,
value=px_count, label='pixels')
return img
# Apply your custom function to each submask (each ROI region)
outimg = _iterate_analysis(img=img, labeled_mask=lbl_mask, n_labels=num, label=pcv.params.sample_label, function=my_func)
# Print observations just to show it is working
print(pcv.outputs.observations)
# {'default_1': {'px_count': {'trait': 'pixel count',
# 'method': 'custom',
# 'scale': 'pixels',
# 'datatype': "<class 'int'>",
# 'value': 13872,
# 'label': 'pixels'}},
# 'default_2': {'px_count': {'trait': 'pixel count',
# 'method': 'custom',
# 'scale': 'pixels',
# 'datatype': "<class 'int'>",
# 'value': 16876,
# 'label': 'pixels'}}}
Hi Noah, I really appreciate your help and still trying to figure out the same problem. I need to go through each ROI and do some calculations on them. I couldn't quite understand how data is stored. Would you be able to tell me how to access matrix of each roi and extract them so I can manipulate each matrix I get from each roi. Thanks Ozgur
Hi @ozgurculfa ,
The last step in a PlantCV workflow is pcv.outputs.save_results(filename= imgname + "_results.txt")
. The default format is JSON so if you are analyzing images one by one it can be helpful to use outformat = "csv"
and then concatenate the results files from all your images. From there you can analyze your resulting data with R or your favorite software.