def nonuniform_illumination(img, ksize):
    """Correct for non uniform illumination i.e. spotlight correction.

            Inputs:
            img       = RGB or grayscale image data
            ksize     = (optional) new minimum value for range of interest. default = 0

            Returns:
            corrected_img = rescaled image

            :param img: numpy.ndarray
            :param ksize: int
            :return corrected_img: numpy.ndarray
            """
    if len(np.shape(img)) == 3:
        img = rgb2gray(img)

    # Fill foreground objects
    kernel = np.ones((ksize, ksize), np.uint8)
    opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

    # Store debug mode
    debug = params.debug
    params.debug = None

    # Heavily blurred image acts like a background image
    blurred_img = gaussian_blur(opening, ksize=(ksize, ksize))
    img_mean = np.mean(blurred_img)
    corrected_img = img - blurred_img + img_mean
    corrected_img = rescale(gray_img=corrected_img, min_value=0, max_value=255)

    # Reset debug mode
    params.debug = debug
    # Autoincrement the device counter
    params.device += 1

    if params.debug == 'print':
        print_image(
            corrected_img,
            os.path.join(params.debug_outdir,
                         str(params.device) + '_correct_illumination' +
                         '.png'))
    elif params.debug == 'plot':
        plot_image(corrected_img, cmap='gray')

    return corrected_img
Пример #2
0
def main():
    # Create input arguments object
    args = options()

    # Set debug mode
    pcv.params.debug = args.debug

    # Open a single image
    img, imgpath, imgname = pcv.readimage(filename=args.image)

    # Visualize colorspaces
    all_cs = pcv.visualize.colorspaces(rgb_img=img)

    # Extract the Blue-Yellow ("b") channel from the LAB colorspace
    gray_img = pcv.rgb2gray_lab(rgb_img=img, channel="b")

    # Plot a histogram of pixel values for the Blue-Yellow ("b") channel.
    hist_plot = pcv.visualize.histogram(gray_img=gray_img)

    # Apply a binary threshold to the Blue-Yellow ("b") grayscale image.
    thresh_img = pcv.threshold.binary(gray_img=gray_img,
                                      threshold=140,
                                      max_value=255,
                                      object_type="light")

    # Apply a dilation with a 5x5 kernel and 3 iterations
    dil_img = pcv.dilate(gray_img=thresh_img, ksize=5, i=3)

    # Fill in small holes in the leaves
    closed_img = pcv.fill_holes(bin_img=dil_img)

    # Erode the plant pixels using a 5x5 kernel and 3 iterations
    er_img = pcv.erode(gray_img=closed_img, ksize=5, i=3)

    # Apply a Gaussian blur with a 5 x 5 kernel.
    blur_img = pcv.gaussian_blur(img=er_img, ksize=(5, 5))

    # Set pixel values less than 255 to 0
    blur_img[np.where(blur_img < 255)] = 0

    # Fill/remove objects less than 300 pixels in area
    cleaned = pcv.fill(bin_img=blur_img, size=300)

    # Create a circular ROI
    roi, roi_str = pcv.roi.circle(img=img, x=1725, y=1155, r=400)

    # Identify objects in the binary image
    cnts, cnts_str = pcv.find_objects(img=img, mask=cleaned)

    # Filter objects by region of interest
    plant_cnt, plant_str, plant_mask, plant_area = pcv.roi_objects(
        img=img,
        roi_contour=roi,
        roi_hierarchy=roi_str,
        object_contour=cnts,
        obj_hierarchy=cnts_str)

    # Combine objects into one
    plant, mask = pcv.object_composition(img=img,
                                         contours=plant_cnt,
                                         hierarchy=plant_str)

    # Measure size and shape properties
    shape_img = pcv.analyze_object(img=img, obj=plant, mask=mask)
    if args.writeimg:
        pcv.print_image(img=shape_img,
                        filename=os.path.join(args.outdir,
                                              "shapes_" + imgname))

    # Analyze color properties
    color_img = pcv.analyze_color(rgb_img=img, mask=mask, hist_plot_type="hsv")
    if args.writeimg:
        pcv.print_image(img=color_img,
                        filename=os.path.join(args.outdir,
                                              "histogram_" + imgname))

    # Save the measurements to a file
    pcv.print_results(filename=args.result)
Пример #3
0
# In[7]:

# An alternative to using median_blur is gaussian_blur, which applies
# a gaussian blur filter to the image. Depending on the image, one
# technique may be more effective than others.

# Inputs:
#   img - RGB or grayscale image data
#   ksize - Tuple of kernel size
#   sigma_x - Standard deviation in X direction; if 0 (default),
#            calculated from kernel size
#   sigma_y - Standard deviation in Y direction; if sigmaY is
#            None (default), sigmaY is taken to equal sigmaX
gaussian_img = pcv.gaussian_blur(img=s_thresh,
                                 ksize=(5, 5),
                                 sigma_x=0,
                                 sigma_y=None)
pcv.print_image(img=gaussian_img, filename="upload/output_imgs/Blur_img.jpg")

# In[8]:

# Convert RGB to LAB and extract the blue channel ('b')

# Input:
#   rgb_img - RGB image data
#   channel- Split by 'l' (lightness), 'a' (green-magenta), or 'b' (blue-yellow) channel
b = pcv.rgb2gray_lab(rgb_img=img, channel='b')

# Threshold the blue channel image
b_thresh = pcv.threshold.binary(gray_img=b,
                                threshold=160,
Пример #4
0
def root():
    				uploaded_file = st.file_uploader("Choose an image...", type="jpg")
    				if uploaded_file is not None:
    					inp = Image.open(uploaded_file)
    					inp.save('input.jpg')
    					img, path, filename = pcv.readimage(filename='input.jpg')
    					image = Image.open('input.jpg')
    					st.image(image, caption='Original Image',use_column_width=True)
                    # Convert RGB to HSV and extract the saturation channel
    # Inputs:
    #   rgb_image - RGB image data 
    #   channel - Split by 'h' (hue), 's' (saturation), or 'v' (value) channel
					
    					s = pcv.rgb2gray_hsv(rgb_img=img, channel='s')
    					pcv.print_image(s, "plant/rgbtohsv.png")
    					image = Image.open('plant/rgbtohsv.png')
    					st.image(image, caption='RGB to HSV', use_column_width=True)
    					s_thresh = pcv.threshold.binary(gray_img=s, threshold=85, max_value=255, object_type='light')
    					pcv.print_image(s_thresh, "plant/binary_threshold.png")
    					image = Image.open('plant/binary_threshold.png')
    					st.image(image, caption='Binary Threshold',use_column_width=True)
                   
    # Median Blur to clean noise 

    # Inputs: 
    #   gray_img - Grayscale image data 
    #   ksize - Kernel size (integer or tuple), (ksize, ksize) box if integer input,
    #           (n, m) box if tuple input 

    					s_mblur = pcv.median_blur(gray_img=s_thresh, ksize=5)
    					pcv.print_image(s_mblur, "plant/Median_blur.png")
    					image = Image.open('plant/Median_blur.png')
    					st.image(image, caption='Median Blur',use_column_width=True)
                    
     # An alternative to using median_blur is gaussian_blur, which applies 
    # a gaussian blur filter to the image. Depending on the image, one 
    # technique may be more effective than others. 

    # Inputs:
    #   img - RGB or grayscale image data
    #   ksize - Tuple of kernel size
    #   sigma_x - Standard deviation in X direction; if 0 (default), 
    #            calculated from kernel size
    #   sigma_y - Standard deviation in Y direction; if sigmaY is 
    #            None (default), sigmaY is taken to equal sigmaX
                
    					gaussian_img = pcv.gaussian_blur(img=s_thresh, ksize=(5, 5), sigma_x=0, sigma_y=None)
    # Convert RGB to LAB and extract the blue channel ('b')

    # Input:
    #   rgb_img - RGB image data 
    #   channel- Split by 'l' (lightness), 'a' (green-magenta), or 'b' (blue-yellow) channel
    					b = pcv.rgb2gray_lab(rgb_img=img, channel='b')
    					b_thresh = pcv.threshold.binary(gray_img=b, threshold=160, max_value=255, 
                                object_type='light')
                     # Join the threshold saturation and blue-yellow images with a logical or operation 

    # Inputs: 
    #   bin_img1 - Binary image data to be compared to bin_img2
    #   bin_img2 - Binary image data to be compared to bin_img1

    
    					bs = pcv.logical_or(bin_img1=s_mblur, bin_img2=b_thresh)
    					pcv.print_image(bs, "plant/threshold comparison.png")
    					image = Image.open('plant/threshold comparison.png')
    					st.image(image, caption='Threshold Comparision',use_column_width=True)
                    
 # Appy Mask (for VIS images, mask_color='white')

    # Inputs:
    #   img - RGB or grayscale image data 
    #   mask - Binary mask image data 
    #   mask_color - 'white' or 'black' 
    
    					masked = pcv.apply_mask(img=img, mask=bs, mask_color='white')
    					pcv.print_image(masked, "plant/Apply_mask.png")
    					image = Image.open('plant/Apply_mask.png')
    					st.image(image, caption='Applied Mask',use_column_width=True)
                   # Convert RGB to LAB and extract the Green-Magenta and Blue-Yellow channels
    					masked_a = pcv.rgb2gray_lab(rgb_img=masked, channel='a')
    					masked_b = pcv.rgb2gray_lab(rgb_img=masked, channel='b')
                     # Threshold the green-magenta and blue images
    					maskeda_thresh = pcv.threshold.binary(gray_img=masked_a, threshold=115, max_value=255, object_type='dark')
    					maskeda_thresh1 = pcv.threshold.binary(gray_img=masked_a, threshold=135,max_value=255, object_type='light')
    					maskedb_thresh = pcv.threshold.binary(gray_img=masked_b, threshold=128, max_value=255, object_type='light')
    					pcv.print_image( maskeda_thresh, "plant/maskeda_thresh.png")
    					pcv.print_image(maskeda_thresh1, "plant/maskeda_thresh1.png")
    					pcv.print_image(maskedb_thresh, "plant/maskedb_thresh1.png")
  
    					image = Image.open('plant/maskeda_thresh.png')
    					st.image(image, caption='Threshold green-magneta and blue image',use_column_width=True)


   # Join the thresholded saturation and blue-yellow images (OR)
    					ab1 = pcv.logical_or(bin_img1=maskeda_thresh, bin_img2=maskedb_thresh)
    					ab = pcv.logical_or(bin_img1=maskeda_thresh1, bin_img2=ab1)
        # Opening filters out bright noise from an image.

# Inputs:
#   gray_img - Grayscale or binary image data
#   kernel - Optional neighborhood, expressed as an array of 1's and 0's. If None (default),
#   uses cross-shaped structuring element.
    					opened_ab = pcv.opening(gray_img=ab)

# Depending on the situation it might be useful to use the 
# exclusive or (pcv.logical_xor) function. 

# Inputs: 
#   bin_img1 - Binary image data to be compared to bin_img2
#   bin_img2 - Binary image data to be compared to bin_img1
    					xor_img = pcv.logical_xor(bin_img1=maskeda_thresh, bin_img2=maskedb_thresh)
# Fill small objects (reduce image noise) 

# Inputs: 
#   bin_img - Binary image data 
#   size - Minimum object area size in pixels (must be an integer), and smaller objects will be filled
    					ab_fill = pcv.fill(bin_img=ab, size=200)
# Closing filters out dark noise from an image.

# Inputs:
#   gray_img - Grayscale or binary image data
#   kernel - Optional neighborhood, expressed as an array of 1's and 0's. If None (default),
#   uses cross-shaped structuring element.
    					closed_ab = pcv.closing(gray_img=ab_fill)
# Apply mask (for VIS images, mask_color=white)
    					masked2 = pcv.apply_mask(img=masked, mask=ab_fill, mask_color='white')
# Identify objects
# Inputs: 
#   img - RGB or grayscale image data for plotting 
#   mask - Binary mask used for detecting contours 
    					id_objects, obj_hierarchy = pcv.find_objects(img=masked2, mask=ab_fill)
# Define the region of interest (ROI) 
# Inputs: 
#   img - RGB or grayscale image to plot the ROI on 
#   x - The x-coordinate of the upper left corner of the rectangle 
#   y - The y-coordinate of the upper left corner of the rectangle 
#   h - The height of the rectangle 
#   w - The width of the rectangle 
    					roi1, roi_hierarchy= pcv.roi.rectangle(img=masked2, x=50, y=50, h=100, w=100)
# Decide which objects to keep
# Inputs:
#    img            = img to display kept objects
#    roi_contour    = contour of roi, output from any ROI function
#    roi_hierarchy  = contour of roi, output from any ROI function
#    object_contour = contours of objects, output from pcv.find_objects function
#    obj_hierarchy  = hierarchy of objects, output from pcv.find_objects function
#    roi_type       = 'partial' (default, for partially inside the ROI), 'cutto', or 
#                     'largest' (keep only largest contour)
    					roi_objects, hierarchy3, kept_mask, obj_area = pcv.roi_objects(img=img, roi_contour=roi1, 
                                                               roi_hierarchy=roi_hierarchy, 
                                                               object_contour=id_objects, 
                                                               obj_hierarchy=obj_hierarchy,
                                                               roi_type='partial')
# Object combine kept objects
# Inputs:
#   img - RGB or grayscale image data for plotting 
#   contours - Contour list 
#   hierarchy - Contour hierarchy array 
    					obj, mask = pcv.object_composition(img=img, contours=roi_objects, hierarchy=hierarchy3)
############### Analysis ################ 
# Find shape properties, data gets stored to an Outputs class automatically
# Inputs:
#   img - RGB or grayscale image data 
#   obj- Single or grouped contour object
#   mask - Binary image mask to use as mask for moments analysis 
    					analysis_image = pcv.analyze_object(img=img, obj=obj, mask=mask)
    					pcv.print_image(analysis_image, "plant/analysis_image.png")
    					image = Image.open('plant/analysis_image.png')
    					st.image(image, caption='Analysis_image',use_column_width=True)
# Shape properties relative to user boundary line (optional)
# Inputs:
#   img - RGB or grayscale image data 
#   obj - Single or grouped contour object 
#   mask - Binary mask of selected contours 
#   line_position - Position of boundary line (a value of 0 would draw a line 
#                   through the bottom of the image) 
    					boundary_image2 = pcv.analyze_bound_horizontal(img=img, obj=obj, mask=mask, 
                                               line_position=370)
    					pcv.print_image(boundary_image2, "plant/boundary_image2.png")
    					image = Image.open('plant/boundary_image2.png')
    					st.image(image, caption='Boundary Image',use_column_width=True)
# Determine color properties: Histograms, Color Slices and Pseudocolored Images, output color analyzed images (optional)
# Inputs:
#   rgb_img - RGB image data
#   mask - Binary mask of selected contours 
#   hist_plot_type - None (default), 'all', 'rgb', 'lab', or 'hsv'
#                    This is the data to be printed to the SVG histogram file  
    					color_histogram = pcv.analyze_color(rgb_img=img, mask=kept_mask, hist_plot_type='all')
# Print the histogram out to save it 
    					pcv.print_image(img=color_histogram, filename="plant/vis_tutorial_color_hist.jpg")
    					image = Image.open('plant/vis_tutorial_color_hist.jpg')
    					st.image(image, caption='Color Histogram',use_column_width=True)
# Divide plant object into twenty equidistant bins and assign pseudolandmark points based upon their 
# actual (not scaled) position. Once this data is scaled this approach may provide some information 
# regarding shape independent of size.
# Inputs:
#   img - RGB or grayscale image data 
#   obj - Single or grouped contour object 
#   mask - Binary mask of selected contours 
    					top_x, bottom_x, center_v_x = pcv.x_axis_pseudolandmarks(img=img, obj=obj, mask=mask)
    					top_y, bottom_y, center_v_y = pcv.y_axis_pseudolandmarks(img=img, obj=obj, mask=mask)
# The print_results function will take the measurements stored when running any (or all) of these functions, format, 
# and print an output text file for data analysis. The Outputs class stores data whenever any of the following functions
# are ran: analyze_bound_horizontal, analyze_bound_vertical, analyze_color, analyze_nir_intensity, analyze_object, 
# fluor_fvfm, report_size_marker_area, watershed. If no functions have been run, it will print an empty text file 
    					pcv.print_results(filename='vis_tutorial_results.txt')
Пример #5
0
def shoot():
    				uploaded_file = st.file_uploader("Choose an image...", type="jpg")
    				if uploaded_file is not None:
    					inp = Image.open(uploaded_file)
    					inp.save('input.jpg')
    					img, path, filename = pcv.readimage(filename='input.jpg')
    					image = Image.open('input.jpg')
    					st.image(image, caption='Original Image',use_column_width=True)
                    # Convert RGB to HSV and extract the saturation channel
    # Inputs:
    #   rgb_image - RGB image data 
    #   channel - Split by 'h' (hue), 's' (saturation), or 'v' (value) channel
					
    					s = pcv.rgb2gray_hsv(rgb_img=img, channel='s')
    					pcv.print_image(s, "plant/rgbtohsv.png")
    					image = Image.open('plant/rgbtohsv.png')
    					st.image(image, caption='RGB to HSV', use_column_width=True)
    					s_thresh = pcv.threshold.binary(gray_img=s, threshold=85, max_value=255, object_type='light')
    					pcv.print_image(s_thresh, "plant/binary_threshold.png")
    					image = Image.open('plant/binary_threshold.png')
    					st.image(image, caption='Binary Threshold',use_column_width=True)
                   
    # Median Blur to clean noise 

    # Inputs: 
    #   gray_img - Grayscale image data 
    #   ksize - Kernel size (integer or tuple), (ksize, ksize) box if integer input,
    #           (n, m) box if tuple input 

    					s_mblur = pcv.median_blur(gray_img=s_thresh, ksize=5)
    					pcv.print_image(s_mblur, "plant/Median_blur.png")
    					image = Image.open('plant/Median_blur.png')
    					st.image(image, caption='Median Blur',use_column_width=True)
                    
     # An alternative to using median_blur is gaussian_blur, which applies 
    # a gaussian blur filter to the image. Depending on the image, one 
    # technique may be more effective than others. 

    # Inputs:
    #   img - RGB or grayscale image data
    #   ksize - Tuple of kernel size
    #   sigma_x - Standard deviation in X direction; if 0 (default), 
    #            calculated from kernel size
    #   sigma_y - Standard deviation in Y direction; if sigmaY is 
    #            None (default), sigmaY is taken to equal sigmaX
                
    					gaussian_img = pcv.gaussian_blur(img=s_thresh, ksize=(5, 5), sigma_x=0, sigma_y=None)
    # Convert RGB to LAB and extract the blue channel ('b')

    # Input:
    #   rgb_img - RGB image data 
    #   channel- Split by 'l' (lightness), 'a' (green-magenta), or 'b' (blue-yellow) channel
    					b = pcv.rgb2gray_lab(rgb_img=img, channel='b')
    					b_thresh = pcv.threshold.binary(gray_img=b, threshold=160, max_value=255, 
                                object_type='light')
                     # Join the threshold saturation and blue-yellow images with a logical or operation 

    # Inputs: 
    #   bin_img1 - Binary image data to be compared to bin_img2
    #   bin_img2 - Binary image data to be compared to bin_img1

    
    					bs = pcv.logical_or(bin_img1=s_mblur, bin_img2=b_thresh)
    					pcv.print_image(bs, "plant/threshold comparison.png")
    					image = Image.open('plant/threshold comparison.png')
    					st.image(image, caption='Threshold Comparision',use_column_width=True)
                    
 # Appy Mask (for VIS images, mask_color='white')

    # Inputs:
    #   img - RGB or grayscale image data 
    #   mask - Binary mask image data 
    #   mask_color - 'white' or 'black' 
    
    					masked = pcv.apply_mask(img=img, mask=bs, mask_color='white')
    					pcv.print_image(masked, "plant/Apply_mask.png")
    					image = Image.open('plant/Apply_mask.png')
    					st.image(image, caption='Applied Mask',use_column_width=True)
                   # Convert RGB to LAB and extract the Green-Magenta and Blue-Yellow channels
    					masked_a = pcv.rgb2gray_lab(rgb_img=masked, channel='a')
    					masked_b = pcv.rgb2gray_lab(rgb_img=masked, channel='b')
                     # Threshold the green-magenta and blue images
    					maskeda_thresh = pcv.threshold.binary(gray_img=masked_a, threshold=115, max_value=255, object_type='dark')
    					maskeda_thresh1 = pcv.threshold.binary(gray_img=masked_a, threshold=135,max_value=255, object_type='light')
    					maskedb_thresh = pcv.threshold.binary(gray_img=masked_b, threshold=128, max_value=255, object_type='light')
    					pcv.print_image( maskeda_thresh, "plant/maskeda_thresh.png")
    					pcv.print_image(maskeda_thresh1, "plant/maskeda_thresh1.png")
    					pcv.print_image(maskedb_thresh, "plant/maskedb_thresh1.png")
  
    					image = Image.open('plant/maskeda_thresh.png')
    					st.image(image, caption='Threshold green-magneta and blue image',use_column_width=True)


   # Join the thresholded saturation and blue-yellow images (OR)
    					ab1 = pcv.logical_or(bin_img1=maskeda_thresh, bin_img2=maskedb_thresh)
    					ab = pcv.logical_or(bin_img1=maskeda_thresh1, bin_img2=ab1)
def segment_on_dt(a, img):

    #logAnd = plantcv.logical_and(a, img)
    #cv2.imshow('logical', logAnd)
    #cv2.waitKey(0)
    gauss = pcv.gaussian_blur(a, (5, 5), 0, 0)
    edges = pcv.canny_edge_detect(a,
                                  mask=None,
                                  sigma=2,
                                  low_thresh=15,
                                  high_thresh=40,
                                  thickness=2,
                                  mask_color=None,
                                  use_quantiles=False)
    cv2.imshow('canny', edges)
    cv2.waitKey(0)
    canny_dilate = cv2.dilate(edges, None, iterations=1)
    cv2.imshow("canny dilate", canny_dilate)
    cv2.waitKey(0)

    dilate = cv2.dilate(img, None, iterations=1)

    border = dilate - cv2.erode(dilate, None, iterations=2)
    cv2.imshow('border', border)
    cv2.waitKey(0)
    border = cv2.bitwise_or(border, canny_dilate, mask=dilate)
    cv2.imshow("border", border)
    cv2.waitKey(0)

    dt = cv2.distanceTransform(img, 1, 5)
    cv2.imshow('dist trans', dt)
    cv2.waitKey(0)
    dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(numpy.uint8)
    cv2.imshow('minmax', dt)
    cv2.waitKey(0)
    _, dt = cv2.threshold(dt, 45, 255, cv2.THRESH_BINARY)
    cv2.imshow('thresh', dt)
    cv2.waitKey(0)

    seg = cv2.subtract(dt, border)
    cv2.imshow('thresh - border', seg)
    cv2.waitKey(0)

    seg1 = cv2.erode(seg, None, iterations=2)
    cv2.imshow('erode', seg1)
    cv2.waitKey(0)

    fill_image = pcv.closing(seg1)
    cv2.imshow('Closing', fill_image)
    cv2.waitKey(0)

    lbl, ncc = label(fill_image)
    lbl = lbl * (255 / (ncc + 1))
    # Completing the markers now.
    lbl[border == 255] = 255

    print(ncc)

    lbl = lbl.astype(numpy.int32)
    #cv2.watershed(a, lbl)

    lbl[lbl == -1] = 0
    lbl = lbl.astype(numpy.uint8)
    return 255 - lbl
def main():

    # Get options
    args = options()
    # plt.rcParams["font.family"] = "Arial"  # All text is Arial

    # pixel_resolution
    cppc.pixelresolution = 0.052  #mm
    # see pixel_resolution.xlsx for calibration curve for pixel to mm translation

    pcv.params.text_size = 12
    pcv.params.text_thickness = 12

    if args.debug:
        pcv.params.debug = args.debug  # set debug mode
        if args.debugdir:
            pcv.params.debug_outdir = args.debugdir  # set debug directory
            os.makedirs(args.debugdir, exist_ok=True)

    args = cppc.roi.copy_metadata(args)

    # read images and create mask
    img, _, fn = pcv.readimage(args.image)
    args.imagename = os.path.splitext(fn)[0]
    # cps=pcv.visualize.colorspaces(img)

    # create mask
    if args.pdfs:  #if not provided in run_workflows.sh then will be False
        print('naive bayes classification')

        # Classify each pixel as plant or background (background and system components)
        img_blur = pcv.gaussian_blur(img, (7, 7))
        masks = pcv.naive_bayes_classifier(rgb_img=img_blur,
                                           pdf_file=args.pdfs)
        mask = masks['Plant']

        # save masks
        colored_img = pcv.visualize.colorize_masks(
            masks=[masks['Plant'], masks['Background'], masks['Blue']],
            colors=['green', 'black', 'blue'])
        # Print out the colorized figure that got created
        imgdir = os.path.join(args.outdir, 'bayesmask_images')
        os.makedirs(imgdir, exist_ok=True)
        pcv.print_image(
            colored_img, os.path.join(imgdir,
                                      args.imagename + '-bayesmask.png'))

    else:
        print('\nthreshold masking')

        # tray mask
        # _, rm, _, _ = pcv.rectangle_mask(img, (425,350), (2100,3050),'white')
        # img_tray = pcv.apply_mask(img, rm, 'black')

        # dark green
        # imgt_h = pcv.rgb2gray_hsv(img,'h')
        mask1, img1 = pcv.threshold.custom_range(img, [15, 0, 0],
                                                 [60, 255, 255], 'hsv')
        mask1 = pcv.fill(mask1, 200)
        mask1 = pcv.closing(mask1, pcv.get_kernel((5, 5), 'rectangle'))

        mask = mask1
        # img1 = pcv.apply_mask(img, mask1, 'black')

        # # remove faint algae
        # img1_a = pcv.rgb2gray_lab(img1,'b')
        # # img1_b = pcv.rgb2gray_lab(img1,'b')
        # th = filters.threshold_otsu(img1_a)
        # algaemask = pcv.threshold.binary(img1_a,th,255,'light')
        # # bmask, _ = pcv.threshold.custom_range(img1,[0,0,100],[120,120,255], 'RGB')
        # img2 = pcv.apply_mask(img1,algaemask,'black')

        # mask = pcv.rgb2gray(img2)
        # mask[mask > 0] = 255
        # pcv.plot_image(mask)

    # find objects based on threshold mask
    c, h = pcv.find_objects(img, mask)
    # setup roi based on pot locations
    rc, rh = pcv.roi.multi(img, coord=[(1250, 1000), (1250, 2300)], radius=300)
    # Turn off debug temporarily if activated, otherwise there will be a lot of plots
    pcv.params.debug = None
    # Loop over each region of interest
    # i=0
    # rc_i = rc[i]
    # rh_i = rh[i]
    final_mask = cppc.roi.iterate_rois(img,
                                       c,
                                       h,
                                       rc,
                                       rh,
                                       args=args,
                                       masked=True,
                                       gi=True,
                                       shape=True,
                                       hist=True,
                                       hue=True)