plantcv icon indicating copy to clipboard operation
plantcv copied to clipboard

Multi ROI

Open ozgurculfa opened this issue 10 months ago • 5 comments

Hello Everyone, Is there any way of doing multi ROI plot with a customized ROI option?

Thanks

ozgurculfa avatar Apr 13 '24 00:04 ozgurculfa

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)

Figure 1 Figure 2 Figure 3 (1) Figure 6 (1)

nfahlgren avatar Apr 13 '24 16:04 nfahlgren

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

ozgurculfa avatar Apr 15 '24 23:04 ozgurculfa

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'}}}

nfahlgren avatar Apr 16 '24 01:04 nfahlgren

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

ozgurculfa avatar Apr 18 '24 00:04 ozgurculfa

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.

HaleySchuhl avatar Apr 22 '24 14:04 HaleySchuhl