-
-
Save AdamDimech/e54fe95f7face972192fbd76fa83bf9a to your computer and use it in GitHub Desktop.
Problem-solving with a PlantCV update
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import sys, traceback | |
import cv2 | |
import numpy as np | |
import argparse | |
import string | |
import matplotlib as mpl | |
# Import PlantCV | |
from plantcv import plantcv as pcv | |
### Parse command-line arguments | |
def options(): | |
parser = argparse.ArgumentParser(description="Imaging processing with opencv") | |
parser.add_argument("-i", "--image", help="Input image file.", required=True) | |
parser.add_argument("-o", "--outdir", help="Output directory for image files.", required=False) | |
parser.add_argument("-r", "--result", help="result file.", required= False ) | |
parser.add_argument("-w", "--writeimg", help="write out images.", default=False, action="store_true") | |
parser.add_argument("-D", "--debug", help="can be set to 'print' or None (or 'plot' if in jupyter) prints intermediate images.") | |
args = parser.parse_args() | |
return args | |
### Main pipeline | |
def main(): | |
# Get options | |
args = options() | |
pcv.params.debug = args.debug # set debug mode | |
pcv.params.debug_outdir = args.outdir # set output directory | |
# Read image | |
img, path, filename = pcv.readimage(args.image, mode="rgb") | |
# Rotate image | |
img = pcv.rotate(img, -90, False) | |
# Remove obvious area of no interest: | |
maskeda, box1_img, rect_contour1, hierarchy1 = pcv.rectangle_mask(img, (3750,0), (5500,7000), color="white") | |
maskedb, box2_img, rect_contour2, hierarchy2 = pcv.rectangle_mask(img, (0,0), (5500,300), color="white") | |
maskedc, box3_img, rect_contour3, hierarchy3 = pcv.rectangle_mask(img, (0,3200), (5500,3700), color="white") | |
maskedd, box4_img, rect_contour4, hierarchy4 = pcv.rectangle_mask(img, (0,0), (1400,7000), color="white") | |
# combine boxes to filter the edges and car out of the photo | |
bx12_img = pcv.logical_or(box1_img, box2_img) | |
bx123_img = pcv.logical_or(bx12_img, box3_img) | |
bx1234_img = pcv.logical_or(bx123_img, box4_img) | |
# invert this mask and then apply it the masked image. | |
inv_bx1234_img = pcv.invert(bx1234_img) | |
img = pcv.apply_mask(img, inv_bx1234_img, 'white') | |
# Convert RGB to HSV and extract the saturation channel | |
s = pcv.rgb2gray_hsv(img, 'h') | |
# Threshold | |
s_thresh = pcv.threshold.binary(s, 14, 146, 'light') | |
# Median Blur | |
s_mblur = pcv.median_blur(s_thresh, 5) | |
s_cnt = pcv.median_blur(s_thresh, 5) | |
#gaussian_img = pcv.gaussian_blur(img=s_thresh, ksize=(5, 5), sigmax=0, sigmay=None) | |
# Convert RGB to LAB and extract the blue channel ('b') | |
b = pcv.rgb2gray_lab(img, 'b') | |
# Threshold the blue channel image | |
b_thresh = pcv.threshold.binary(b, 120, 255, 'dark') | |
b_cnt = pcv.threshold.binary(b, 120, 255, 'light') | |
# Fill small objects | |
b_fill = pcv.fill(b_thresh, 10) | |
# Remove specs of dirt from the image that will be processed as ROI (4,1 worked well) | |
b_thresh = pcv.dilate(b_thresh,4,1) | |
b_cnt = pcv.erode(b_cnt,4,1) | |
# Join the threshold saturation and blue-yellow images | |
bs = pcv.logical_or(s_mblur, b_cnt) | |
# Appy Mask (for VIS images, mask_color='white') | |
masked = pcv.apply_mask(img, bs, 'white') | |
# Convert RGB to LAB and extract the Green-Magenta and Blue-Yellow channels | |
masked_a = pcv.rgb2gray_lab(masked, 'a') | |
masked_b = pcv.rgb2gray_lab(masked, 'b') | |
# Threshold the green-magenta and blue images | |
maskeda_thresh = pcv.threshold.binary(masked_a, 128, 255, 'light') | |
maskeda_thresh1 = pcv.threshold.binary(masked_a, 135, 255, 'light') | |
maskedb_thresh = pcv.threshold.binary(masked_b, 126, 255, 'dark') | |
# Join the thresholded saturation and blue-yellow images (OR) | |
ab1 = pcv.logical_or(maskeda_thresh, maskedb_thresh) | |
ab = pcv.logical_or(maskeda_thresh1, ab1) | |
xor_img = pcv.logical_xor(maskeda_thresh, maskedb_thresh) | |
# Fill small objects (reduce image noise) | |
ab_fill = pcv.fill(ab, 2) | |
# Apply mask (for VIS images, mask_color=white) | |
masked2 = pcv.apply_mask(masked, ab_fill, 'white') | |
# Identify objects | |
id_objects, obj_hierarchy = pcv.find_objects(masked2, ab_fill) | |
# Define the region of interest (ROI) | |
roi1, roi_hierarchy= pcv.roi.rectangle(x=1450, y=250, h=2950, w=2350, img=masked2) | |
# Decide which objects to keep | |
#roi_objects, hierarchy3, kept_mask, obj_area = pcv.roi_objects(img, 'cutto', roi1, roi_hierarchy, id_objects, obj_hierarchy) | |
roi_objects, hierarchy3, mask, obj_area = pcv.roi_objects(img, roi1, roi_hierarchy, id_objects, obj_hierarchy, roi_type='partial') | |
# Object combine kept objects | |
obj, mask = pcv.object_composition(img, roi_objects, hierarchy3) | |
############### Analysis ################ | |
outfile=False | |
if args.writeimg == True: | |
outfile = args.outdir + "/" + filename | |
# Find shape properties, output shape image (optional) | |
shape_imgs = pcv.analyze_object(img, obj, mask) | |
# Shape properties relative to user boundary line (optional) | |
boundary_img1 = pcv.analyze_bound_horizontal(img, obj, mask, 1680) | |
# Determine color properties: Histograms, Color Slices, output color analyzed histogram (optional) | |
# color_histogram = pcv.analyze_color(img, kept_mask, 'all') | |
# Pseudocolor the grayscale image | |
pseudocolored_img = pcv.visualize.pseudocolor(gray_img=s, obj=None, mask=mask, axes=True, colorbar=True, cmap='jet') | |
# Old | |
#pseudocolored_img = pcv.analyze_color(img, mask, 256, hist_plot_type=None) | |
# Write shape and color data to results file | |
pcv.print_results(filename=args.result) | |
if __name__ == '__main__': | |
main() | |
# End message | |
print("Complete") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Traceback (most recent call last): | |
File "C:/Path/To/plantcv_pipeline.py", line 142, in <module> | |
main() | |
File "C:/Path/To/plantcv_pipeline.py", line 133, in main | |
pseudocolored_img = pcv.visualize.pseudocolor(gray_img=s, obj=None, mask=mask, axes=True, colorbar=True, cmap='jet') | |
AttributeError: module 'plantcv.plantcv' has no attribute 'visualize' | |
Processing results... | |
Traceback (most recent call last): | |
File "C:\Path\To\plantcv_pipeline.py", line 262, in <module> | |
main() | |
File "C:\Path\To\plantcv_pipeline.py", line 247, in main | |
pcvp.process_results(valid_meta=args.valid_meta, job_dir=args.jobdir, json_file=args.json) | |
File "C:\Path\To\plantcv_pipeline.py", line 42, in process_results | |
obs = json.load(results) | |
File "C:\Anaconda\envs\plantcv\lib\json\__init__.py", line 299, in load | |
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) | |
File "C:\Anaconda\envs\plantcv\lib\json\__init__.py", line 354, in loads | |
return _default_decoder.decode(s) | |
File "C:\Anaconda\envs\plantcv\lib\json\decoder.py", line 339, in decode | |
obj, end = self.raw_decode(s, idx=_w(s, 0).end()) | |
File "C:\Anaconda\envs\plantcv\lib\json\decoder.py", line 357, in raw_decode | |
raise JSONDecodeError("Expecting value", s, err.value) from None | |
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment