def process_pot(self, pot_image):
     device = 0
     # debug=None
     updated_pot_image = self.threshold_green(pot_image)
     # plt.imshow(updated_pot_image)
     # plt.show()
     device, a = pcv.rgb2gray_lab(updated_pot_image, 'a', device)
     device, img_binary = pcv.binary_threshold(a, 127, 255, 'dark', device,
                                               None)
     # plt.imshow(img_binary)
     # plt.show()
     mask = np.copy(img_binary)
     device, fill_image = pcv.fill(img_binary, mask, 50, device)
     device, dilated = pcv.dilate(fill_image, 1, 1, device)
     device, id_objects, obj_hierarchy = pcv.find_objects(
         updated_pot_image, updated_pot_image, device)
     device, roi1, roi_hierarchy = pcv.define_roi(updated_pot_image,
                                                  'rectangle', device, None,
                                                  'default', debug, False)
     device, roi_objects, hierarchy3, kept_mask, obj_area = pcv.roi_objects(
         updated_pot_image, 'partial', roi1, roi_hierarchy, id_objects,
         obj_hierarchy, device, debug)
     device, obj, mask = pcv.object_composition(updated_pot_image,
                                                roi_objects, hierarchy3,
                                                device, debug)
     device, shape_header, shape_data, shape_img = pcv.analyze_object(
         updated_pot_image, "Example1", obj, mask, device, debug, False)
     print(shape_data[1])
Пример #2
0
def main():
    # Get options
    args = options()

    debug = args.debug

    # Read image
    img, path, filename = pcv.readimage(args.image)

    # Pipeline step
    device = 0

    device, corrected_img = pcv.white_balance(device, img, debug,
                                              (500, 1000, 500, 500))
    img = corrected_img

    device, img_gray_sat = pcv.rgb2gray_lab(img, 'a', device, debug)

    device, img_binary = pcv.binary_threshold(img_gray_sat, 120, 255, 'dark',
                                              device, debug)

    mask = np.copy(img_binary)
    device, fill_image = pcv.fill(img_binary, mask, 300, device, debug)

    device, id_objects, obj_hierarchy = pcv.find_objects(
        img, fill_image, device, debug)

    device, roi, roi_hierarchy = pcv.define_roi(img, 'rectangle', device, None,
                                                'default', debug, True, 1800,
                                                1600, -1500, -500)

    device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
        img, 'partial', roi, roi_hierarchy, id_objects, obj_hierarchy, device,
        debug)

    device, obj, mask = pcv.object_composition(img, roi_objects,
                                               roi_obj_hierarchy, device,
                                               debug)

    outfile = os.path.join(args.outdir, filename)

    device, color_header, color_data, color_img = pcv.analyze_color(
        img, img, mask, 256, device, debug, None, 'v', 'img', 300, outfile)

    device, shape_header, shape_data, shape_img = pcv.analyze_object(
        img, "img", obj, mask, device, debug, outfile)

    shapepath = outfile[:-4] + '_shapes.jpg'
    shapepic = cv2.imread(shapepath)
    plantsize = "The plant is " + str(np.sum(mask)) + " pixels large"
    cv2.putText(shapepic, plantsize, (500, 500), cv2.FONT_HERSHEY_SIMPLEX, 5,
                (0, 255, 0), 10)
    pcv.print_image(shapepic, outfile[:-4] + '-out_shapes.jpg')
    def read_dot(self, imageread):

        img1 = imageread
        device, img1gray = pcv.rgb2gray(img1, 0)
        img1hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
        dev, img_binary = pcv.binary_threshold(img1gray, 1, 255, 'light', 0)
        device, id_objects, obj_hierarchy = pcv.find_objects(
            img1, img_binary, 0)

        device, roi, roi_hierarchy = pcv.define_roi(img1,
                                                    shape="rectangle",
                                                    device=device,
                                                    roi_input="default",
                                                    adjust=False,
                                                    x_adj=600,
                                                    y_adj=600,
                                                    w_adj=1200,
                                                    h_adj=1200)
        device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
            img1, "partial", roi, roi_hierarchy, id_objects, obj_hierarchy,
            device)

        device, clusters_i, contours, obj_hierarchy = pcv.cluster_contours(
            device=device,
            img=img1,
            roi_objects=roi_objects,
            roi_obj_hierarchy=roi_obj_hierarchy,
            nrow=1,
            ncol=int(3))
        dotQ = list()
        obj_hierarchy = obj_hierarchy[0]
        for clusters1 in clusters_i:
            for contourtocheck in clusters1:
                if not obj_hierarchy[contourtocheck][2] == -1:
                    if not cv2.contourArea(
                            contours[obj_hierarchy[contourtocheck][2]]) >= 20:
                        obj_hierarchy[contourtocheck][2] = -1
        counter = 0
        for foundcontour in clusters_i:
            hierarchycontours = [obj_hierarchy[j][2] for j in foundcontour]
            if not all([bool(j == -1) for j in hierarchycontours]):
                dotQ.append(True)
            else:
                dotQ.append(False)
        return dotQ
Пример #4
0
def plant_cv(img):
    counter = 0
    debug = None

    counter, s = pcv.rgb2gray_hsv(img, 's', counter, debug)
    counter, s_thresh = pcv.binary_threshold(s, 145, 255, 'light', counter,
                                             debug)
    counter, s_mblur = pcv.median_blur(s_thresh, 5, counter, debug)

    # Convert RGB to LAB and extract the Blue channel
    counter, b = pcv.rgb2gray_lab(img, 'b', counter, debug)

    # Threshold the blue image
    counter, b_thresh = pcv.binary_threshold(b, 145, 255, 'light', counter,
                                             debug)
    counter, b_cnt = pcv.binary_threshold(b, 145, 255, 'light', counter, debug)
    # Join the thresholded saturation and blue-yellow images
    counter, bs = pcv.logical_or(s_mblur, b_cnt, counter, debug)
    counter, masked = pcv.apply_mask(img, bs, 'white', counter, debug)

    #----------------------------------------
    # Convert RGB to LAB and extract the Green-Magenta and Blue-Yellow channels
    counter, masked_a = pcv.rgb2gray_lab(masked, 'a', counter, debug)
    counter, masked_b = pcv.rgb2gray_lab(masked, 'b', counter, debug)

    # Threshold the green-magenta and blue images
    counter, maskeda_thresh = pcv.binary_threshold(masked_a, 115, 255, 'dark',
                                                   counter, debug)
    counter, maskeda_thresh1 = pcv.binary_threshold(masked_a, 135, 255,
                                                    'light', counter, debug)
    counter, maskedb_thresh = pcv.binary_threshold(masked_b, 128, 255, 'light',
                                                   counter, debug)

    # Join the thresholded saturation and blue-yellow images (OR)
    counter, ab1 = pcv.logical_or(maskeda_thresh, maskedb_thresh, counter,
                                  debug)
    counter, ab = pcv.logical_or(maskeda_thresh1, ab1, counter, debug)
    counter, ab_cnt = pcv.logical_or(maskeda_thresh1, ab1, counter, debug)

    # Fill small objects
    counter, ab_fill = pcv.fill(ab, ab_cnt, 200, counter, debug)

    # Apply mask (for vis images, mask_color=white)
    counter, masked2 = pcv.apply_mask(masked, ab_fill, 'white', counter, debug)

    zeros = np.zeros(masked2.shape[:2], dtype="uint8")
    merged = cv2.merge([zeros, ab_fill, zeros])

    return merged, masked2
def main():
    # Get options
    args = options()

    debug = args.debug

    # Read image
    img, path, filename = pcv.readimage(args.image)

    # Pipeline step
    device = 0

    device, img1 = pcv.white_balance(device, img, debug,
                                     (100, 100, 1000, 1000))
    img = img1

    #seedmask, path1, filename1 = pcv.readimage(args.mask)
    #device, seedmask = pcv.rgb2gray(seedmask, device, debug)
    #device, inverted = pcv.invert(seedmask, device, debug)
    #device, masked_img = pcv.apply_mask(img, inverted, 'white', device, debug)

    device, img_gray_sat = pcv.rgb2gray_hsv(img1, 's', device, debug)

    device, img_binary = pcv.binary_threshold(img_gray_sat, 70, 255, 'light',
                                              device, debug)

    img_binary1 = np.copy(img_binary)
    device, fill_image = pcv.fill(img_binary1, img_binary, 300, device, debug)

    device, seed_objects, seed_hierarchy = pcv.find_objects(
        img, fill_image, device, debug)

    device, roi1, roi_hierarchy1 = pcv.define_roi(img, 'rectangle', device,
                                                  None, 'default', debug, True,
                                                  1500, 1000, -1000, -500)

    device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
        img, 'partial', roi1, roi_hierarchy1, seed_objects, seed_hierarchy,
        device, debug)

    img_copy = np.copy(img)
    for i in range(0, len(roi_objects)):
        rand_color = pcv.color_palette(1)
        cv2.drawContours(img_copy,
                         roi_objects,
                         i,
                         rand_color[0],
                         -1,
                         lineType=8,
                         hierarchy=roi_obj_hierarchy)

    pcv.print_image(
        img_copy,
        os.path.join(args.outdir, filename[:-4]) + "-seed-confetti.jpg")

    shape_header = []  # Store the table header
    table = []  # Store the PlantCV measurements for each seed in a table
    for i in range(0, len(roi_objects)):
        if roi_obj_hierarchy[0][i][
                3] == -1:  # Only continue if the object is an outermost contour

            # Object combine kept objects
            # Inputs:
            #    contours = object list
            #    device   = device number. Used to count steps in the pipeline
            #    debug    = None, print, or plot. Print = save to file, Plot = print to screen.
            device, obj, mask = pcv.object_composition(
                img, [roi_objects[i]], np.array([[roi_obj_hierarchy[0][i]]]),
                device, None)
            if obj is not None:
                # Measure the area and other shape properties of each seed
                # Inputs:
                #    img             = image object (most likely the original), color(RGB)
                #    imgname         = name of image
                #    obj             = single or grouped contour object
                #    device          = device number. Used to count steps in the pipeline
                #    debug           = None, print, or plot. Print = save to file, Plot = print to screen.
                #    filename        = False or image name. If defined print image
                device, shape_header, shape_data, shape_img = pcv.analyze_object(
                    img, "img", obj, mask, device, None)

                if shape_data is not None:
                    table.append(shape_data[1])

    data_array = np.array(table)
    maxval = np.argmax(data_array)
    maxseed = np.copy(img)
    cv2.drawContours(maxseed, roi_objects, maxval, (0, 255, 0), 10)

    imgtext = "This image has " + str(len(data_array)) + " seeds"
    sizeseed = "The largest seed is in green and is " + str(
        data_array[maxval]) + " pixels"
    cv2.putText(maxseed, imgtext, (500, 300), cv2.FONT_HERSHEY_SIMPLEX, 5,
                (0, 0, 0), 10)
    cv2.putText(maxseed, sizeseed, (500, 600), cv2.FONT_HERSHEY_SIMPLEX, 5,
                (0, 0, 0), 10)
    pcv.print_image(maxseed,
                    os.path.join(args.outdir, filename[:-4]) + "-maxseed.jpg")
Пример #6
0
def report_size_marker_area(img,
                            shape,
                            device,
                            debug,
                            marker='define',
                            x_adj=0,
                            y_adj=0,
                            w_adj=0,
                            h_adj=0,
                            base='white',
                            objcolor='dark',
                            thresh_channel=None,
                            thresh=None,
                            filename=False):
    """Outputs numeric properties for an input object (contour or grouped contours).

    Inputs:
    img             = image object (most likely the original), color(RGB)
    shape           = 'rectangle', 'circle', 'ellipse'
    device          = device number. Used to count steps in the pipeline
    debug           = None, print, or plot. Print = save to file, Plot = print to screen.
    marker          = define or detect, if define it means you set an area, if detect it means you want to
                      detect within an area
    x_adj           = x position of shape, integer
    y_adj           = y position of shape, integer
    w_adj           = width
    h_adj           = height
    plantcv            = background color 'white' is default
    objcolor        = object color is 'dark' or 'light'
    thresh_channel  = 'h', 's','v'
    thresh          = integer value
    filename        = name of file

    Returns:
    device          = device number
    marker_header    = shape data table headers
    marker_data      = shape data table values
    analysis_images = list of output images

    :param img: numpy array
    :param shape: str
    :param device: int
    :param debug: str
    :param marker: str
    :param x_adj:int
    :param y_adj:int
    :param w_adj:int
    :param h_adj:int
    :param h_adj:int
    :param base:str
    :param objcolor: str
    :param thresh_channel:str
    :param thresh:int
    :param filename: str
    :return: device: int
    :return: marker_header: str
    :return: marker_data: int
    :return: analysis_images: list
    """

    device += 1
    ori_img = np.copy(img)
    if len(np.shape(img)) == 3:
        ix, iy, iz = np.shape(img)
    else:
        ix, iy = np.shape(img)

    size = ix, iy
    roi_background = np.zeros(size, dtype=np.uint8)
    roi_size = (ix - 5), (iy - 5)
    roi = np.zeros(roi_size, dtype=np.uint8)
    roi1 = roi + 1
    roi_contour, roi_heirarchy = cv2.findContours(roi1, cv2.RETR_TREE,
                                                  cv2.CHAIN_APPROX_NONE)[-2:]
    cv2.drawContours(roi_background, roi_contour[0], -1, (255, 0, 0), 5)

    if (x_adj > 0 and w_adj > 0) or (y_adj > 0 and h_adj > 0):
        fatal_error(
            'Adjusted ROI position is out of frame, this will cause problems in detecting objects'
        )

    for cnt in roi_contour:
        size1 = ix, iy, 3
        background = np.zeros(size1, dtype=np.uint8)
        if shape == 'rectangle' and (x_adj >= 0 and y_adj >= 0):
            x, y, w, h = cv2.boundingRect(cnt)
            x1 = x + x_adj
            y1 = y + y_adj
            w1 = w + w_adj
            h1 = h + h_adj
            cv2.rectangle(background, (x1, y1), (x + w1, y + h1), (1, 1, 1),
                          -1)
        elif shape == 'circle':
            x, y, w, h = cv2.boundingRect(cnt)
            x1 = x + x_adj
            y1 = y + y_adj
            w1 = w + w_adj
            h1 = h + h_adj
            center = (int((w + x1) / 2), int((h + y1) / 2))
            if h > w:
                radius = int(w1 / 2)
                cv2.circle(background, center, radius, (1, 1, 1), -1)
            else:
                radius = int(h1 / 2)
                cv2.circle(background, center, radius, (1, 1, 1), -1)
        elif shape == 'ellipse':
            x, y, w, h = cv2.boundingRect(cnt)
            x1 = x + x_adj
            y1 = y + y_adj
            w1 = w + w_adj
            h1 = h + h_adj
            center = (int((w + x1) / 2), int((h + y1) / 2))
            if w > h:
                cv2.ellipse(background, center, (int(w1 / 2), int(h1 / 2)), 0,
                            0, 360, (1, 1, 1), -1)
            else:
                cv2.ellipse(background, center, (int(h1 / 2), int(w1 / 2)), 0,
                            0, 360, (1, 1, 1), -1)
        else:
            fatal_error('Shape' + str(shape) +
                        ' is not "rectangle", "circle", or "ellipse"!')

    markerback = cv2.cvtColor(background, cv2.COLOR_RGB2GRAY)
    shape_contour, hierarchy = cv2.findContours(markerback, cv2.RETR_TREE,
                                                cv2.CHAIN_APPROX_NONE)[-2:]
    cv2.drawContours(ori_img, shape_contour, -1, (255, 255, 0), 5)

    if debug is 'print':
        print_image(ori_img, (str(device) + '_marker_roi.png'))
    elif debug is 'plot':
        plot_image(ori_img)

    if marker == 'define':
        m = cv2.moments(markerback, binaryImage=True)
        area = m['m00']
        device, id_objects, obj_hierarchy = find_objects(
            img, markerback, device, debug)
        device, obj, mask = object_composition(img, id_objects, obj_hierarchy,
                                               device, debug)
        center, axes, angle = cv2.fitEllipse(obj)
        major_axis = np.argmax(axes)
        minor_axis = 1 - major_axis
        major_axis_length = axes[major_axis]
        minor_axis_length = axes[minor_axis]
        eccentricity = np.sqrt(1 - (axes[minor_axis] / axes[major_axis])**2)

    elif marker == 'detect':
        if thresh_channel is not None and thresh is not None:
            if base == 'white':
                masked = cv2.multiply(img, background)
                marker1 = markerback * 255
                mask1 = cv2.bitwise_not(marker1)
                markstack = np.dstack((mask1, mask1, mask1))
                added = cv2.add(masked, markstack)
            else:
                added = cv2.multiply(img, background)
            device, maskedhsv = rgb2gray_hsv(added, thresh_channel, device,
                                             debug)
            device, masked2a_thresh = binary_threshold(maskedhsv, thresh, 255,
                                                       objcolor, device, debug)
            device, id_objects, obj_hierarchy = find_objects(
                added, masked2a_thresh, device, debug)
            device, roi1, roi_hierarchy = define_roi(added, shape, device,
                                                     None, 'default', debug,
                                                     True, x_adj, y_adj, w_adj,
                                                     h_adj)
            device, roi_o, hierarchy3, kept_mask, obj_area = roi_objects(
                img, 'partial', roi1, roi_hierarchy, id_objects, obj_hierarchy,
                device, debug)
            device, obj, mask = object_composition(img, roi_o, hierarchy3,
                                                   device, debug)

            cv2.drawContours(ori_img,
                             roi_o,
                             -1, (0, 255, 0),
                             -1,
                             lineType=8,
                             hierarchy=hierarchy3)
            m = cv2.moments(mask, binaryImage=True)
            area = m['m00']

            center, axes, angle = cv2.fitEllipse(obj)
            major_axis = np.argmax(axes)
            minor_axis = 1 - major_axis
            major_axis_length = axes[major_axis]
            minor_axis_length = axes[minor_axis]
            eccentricity = np.sqrt(1 -
                                   (axes[minor_axis] / axes[major_axis])**2)

        else:
            fatal_error(
                'thresh_channel and thresh must be defined in detect mode')
    else:
        fatal_error("marker must be either in 'detect' or 'define' mode")

    analysis_images = []
    if filename:
        out_file = str(filename[0:-4]) + '_sizemarker.jpg'
        print_image(ori_img, out_file)
        analysis_images.append(['IMAGE', 'marker', out_file])
    if debug is 'print':
        print_image(ori_img, (str(device) + '_marker_shape.png'))
    elif debug is 'plot':
        plot_image(ori_img)

    marker_header = ('HEADER_MARKER', 'marker_area',
                     'marker_major_axis_length', 'marker_minor_axis_length',
                     'marker_eccentricity')

    marker_data = ('MARKER_DATA', area, major_axis_length, minor_axis_length,
                   eccentricity)

    return device, marker_header, marker_data, analysis_images
Пример #7
0
def main():
    # Get options
    args = options()

    debug = args.debug

    # Read image
    img, path, filename = pcv.readimage(args.image)

    # Pipeline step
    device = 0

    device, img1 = pcv.white_balance(device, img, debug, roi=(1000, 1000, 500, 500))

    device, a = pcv.rgb2gray_lab(img1, 'a', device, debug)

    device, img_binary = pcv.binary_threshold(a, 116, 255, 'dark', device, debug)

    mask = np.copy(img_binary)
    device, fill_image = pcv.fill(img_binary, mask, 300, device, debug)

    device, id_objects, obj_hierarchy = pcv.find_objects(img1, fill_image, device, debug)

    device, roi, roi_hierarchy = pcv.define_roi(img1, 'rectangle', device, None, 'default', debug, True,
                                                1800, 1600, -1500, -500)

    device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(img1, 'partial', roi, roi_hierarchy,
                                                                                  id_objects, obj_hierarchy, device,
                                                                                  debug)

    outfile = os.path.join(args.outdir, filename)

    device, color_header, color_data, color_img = pcv.analyze_color(img1, img1, kept_mask, 256, device, debug, None,
                                                                    'v', 'img', 300, outfile)

    device, masked = pcv.apply_mask(img1, kept_mask, 'white', device, debug)
    device, dilated = pcv.dilate(kept_mask, 10, 2, device, debug)
    device, plant_objects, plant_hierarchy = pcv.find_objects(img1, dilated, device, debug)

    img_copy = np.copy(img1)

    color = [(255, 0, 255), (0, 255, 0), (66, 134, 244), (255, 255, 0)]

    for i in range(0, len(plant_objects)):
        if len(plant_objects[i]) < 100:
            pass
        else:
            background = np.zeros((np.shape(img1)), np.uint8)
            cv2.drawContours(background, plant_objects, i, (255, 255, 255), -1, lineType=8, hierarchy=plant_hierarchy)
            device, grayimg = pcv.rgb2gray(background, device, debug)
            device, masked1 = pcv.apply_mask(masked, grayimg, 'white', device, debug)
            device, a1 = pcv.rgb2gray_lab(masked1, 'a', device, debug)
            device, img_binary1 = pcv.binary_threshold(a1, 116, 255, 'dark', device, debug)
            device, single_object, single_hierarchy = pcv.find_objects(masked1, img_binary1, device, debug)
            device, obj, mask = pcv.object_composition(img1, single_object, single_hierarchy, device, debug)
            device, shape_header, shape_data, shape_img = pcv.analyze_object(img, "img", obj, mask, device, debug)
            cv2.drawContours(img_copy, plant_objects, i, color[i], -1, lineType=8, hierarchy=plant_hierarchy)
            plantsize = "Plant matching this color is " + str(shape_data[1]) + " pixels large"
            cv2.putText(img_copy, plantsize, (500, (i + 1) * 300), cv2.FONT_HERSHEY_SIMPLEX, 5, color[i], 10)

    pcv.print_image(img_copy, os.path.join(args.outdir, "arabidopsis-out_shapes.jpg"))
                                          debug="print")  #plantcv model output
mask_image_plant, path, filename = pcv.readimage(
    '1_naive_bayes_Plant_mask.jpg')

############################################
######    Perform Calculations    ##########
############################################

# combine leaf and labels
mask_image_label, path, filename = pcv.readimage(
    '1_naive_bayes_labels_mask.jpg')
mask_image = mask_image_plant + mask_image_label
device, mask_image = pcv.rgb2gray_lab(mask_image, 'l', device)

#clean the mask up
device, img_binary = pcv.binary_threshold(mask_image, 50, 255, 'light', device)
pcv.print_image(img_binary, 'img_binary.tif')
device, blur_img = pcv.erode(
    img_binary, 3, 1, device, debug='print'
)  # Erode to remove soil and Dilate so that you don't lose leaves (just in case)

mask = np.copy(blur_img)
device, fill_image = pcv.fill(blur_img, mask, 100, device)
pcv.print_image(fill_image, 'fill_image.tif')
device, binary_image = pcv.median_blur(fill_image, 1, device)
pcv.print_image(binary_image, 'binary_image.tif')
device, masked_image = device, dilate_image = pcv.dilate(
    fill_image, 3, 3, device)

############################################
###########    Create Output   #############
def analyze_NIR_intensity(img, rgbimg, mask, bins, device, histplot=False, debug=None, filename=False):
    """This function calculates the intensity of each pixel associated with the plant and writes the values out to
       a file. It can also print out a histogram plot of pixel intensity and a pseudocolor image of the plant.

    Inputs:
    img          = input image original NIR image
    rgbimg      = RGB NIR image
    mask         = mask made from selected contours
    bins         = number of classes to divide spectrum into
    device       = device number. Used to count steps in the pipeline
    histplot     = if True plots histogram of intensity values
    debug        = None, print, or plot. Print = save to file, Plot = print to screen.
    filename     = False or image name. If defined print image

    Returns:
    device       = device number
    hist_header  = NIR histogram data table headers
    hist_data    = NIR histogram data table values
    analysis_img = output image

    :param img: numpy array
    :param rgbimg: numpy array
    :param mask: numpy array
    :param bins: int
    :param device: int
    :param histplot: bool
    :param debug: str
    :param filename: str
    :return device: int
    :return hist_header: list
    :return hist_data: list
    :return analysis_img: str
    """

    device += 1

    # apply plant shaped mask to image
    device, mask1 = binary_threshold(mask, 0, 255, 'light', device, None)
    mask1 = (mask1 / 255)
    masked = np.multiply(img, mask1)

    # calculate histogram
    if img.dtype == 'uint16':
        maxval = 65536
    else:
        maxval = 256

    hist_nir, hist_bins = np.histogram(masked, bins, (1, maxval), False, None, None)

    hist_bins1 = hist_bins[:-1]
    hist_bins2 = [l for l in hist_bins1]

    hist_nir1 = [l for l in hist_nir]

    # make hist percentage for plotting
    pixels = cv2.countNonZero(mask1)
    hist_percent = (hist_nir / float(pixels)) * 100

    # report histogram data
    hist_header = [
        'HEADER_HISTOGRAM',
        'bin-number',
        'bin-values',
        'nir'
    ]

    hist_data = [
        'HISTOGRAM_DATA',
        bins,
        hist_bins2,
        hist_nir1
    ]

    analysis_img = []

    # make mask to select the background
    mask_inv = cv2.bitwise_not(mask)
    img_back = cv2.bitwise_and(rgbimg, rgbimg, mask=mask_inv)
    img_back1 = cv2.applyColorMap(img_back, colormap=1)

    # mask the background and color the plant with color scheme 'jet'
    cplant = cv2.applyColorMap(rgbimg, colormap=2)
    device, masked1 = apply_mask(cplant, mask, 'black', device, debug=None)
    cplant_back = cv2.add(masked1, img_back1)

    if filename:
        path = os.path.dirname(filename)
        fig_name = 'NIR_pseudocolor_colorbar.svg'
        if not os.path.isfile(path + '/' + fig_name):
            plot_colorbar(path, fig_name, bins)

        fig_name_pseudo = (str(filename[0:-4]) + '_nir_pseudo_col.jpg')
        print_image(cplant_back, fig_name_pseudo)
        analysis_img.append(['IMAGE', 'pseudo', fig_name_pseudo])

    if debug is not None:
        if debug == "print":
            print_image(masked1, (str(device) + "_nir_pseudo_plant.jpg"))
            print_image(cplant_back, (str(device) + "_nir_pseudo_plant_back.jpg"))
        if debug == "plot":
            plot_image(masked1)
            plot_image(cplant_back)


    if histplot is True:
        import matplotlib
        matplotlib.use('Agg', warn=False)
        from matplotlib import pyplot as plt

        # plot hist percent
        plt.plot(hist_percent, color='green', label='Signal Intensity')
        plt.xlim([0, (bins - 1)])
        plt.xlabel(('Grayscale pixel intensity (0-' + str(bins) + ")"))
        plt.ylabel('Proportion of pixels (%)')

        if filename:
            fig_name_hist = (str(filename[0:-4]) + '_nir_hist.svg')
            plt.savefig(fig_name_hist)
            analysis_img.append(['IMAGE', 'hist', fig_name_hist])
        if debug == "print":
            plt.savefig((str(device) + "_nir_histogram.png"))
        if debug == "plot":
            plt.figure()
        plt.clf()



    return device, hist_header, hist_data, analysis_img
    def read_image_obsolete(self, imagearray):
        """***Do Not Use***Translate the picture of the dots into a tray number assignment."""
        ###Preprocessing & Object Finding Steps

        device, img1gray = pcv.rgb2gray(imagearray, 0)
        device, img_binary = pcv.binary_threshold(img1gray, 1, 255, "light", 0)
        device, id_objects, obj_hierarchy = pcv.find_objects(
            imagearray, img_binary, 0)
        device, roi, roi_hierarchy = pcv.define_roi(imagearray,
                                                    shape="rectangle",
                                                    device=device,
                                                    roi_input="default",
                                                    adjust=False,
                                                    x_adj=600,
                                                    y_adj=600,
                                                    w_adj=1200,
                                                    h_adj=1200)
        device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
            imagearray, "partial", roi, roi_hierarchy, id_objects,
            obj_hierarchy, device)
        device, clusters_i, contours, obj_hierarchy = pcv.cluster_contours(
            device=device,
            img=imagearray,
            roi_objects=roi_objects,
            roi_obj_hierarchy=roi_obj_hierarchy,
            nrow=1,
            ncol=int(3))
        out = "/Users/gghosal/Desktop/gaurav/res"
        device, output_path = pcv.cluster_contour_splitimg(
            device=device,
            img=imagearray,
            grouped_contour_indexes=clusters_i,
            contours=contours,
            hierarchy=obj_hierarchy,
            outdir=out)
        obj_hierarchy = obj_hierarchy[0]
        centroids = list()
        totalcontours = list()
        #print(len(contours))
        for clusters1 in clusters_i:
            totalcontour = contours[clusters1[0]]
            for j in clusters1[1:]:
                totalcontour = np.concatenate((contours[j], totalcontour),
                                              axis=0)
            totalcontours.append(totalcontour)
            mmt = cv2.moments(totalcontour)
            ycoords = int(mmt['m10'] / mmt['m00'])
            xcoords = int(mmt['m01'] / mmt['m00'])
            #cv2.circle(img1, (ycoords, xcoords), 3, (255, 0, 0), 3)

            centroids.append(tuple([ycoords, xcoords]))
        count11 = 0
        for clusters1 in clusters_i:
            for contourtocheck in clusters1:
                if not obj_hierarchy[contourtocheck][2] == -1:
                    if not cv2.contourArea(
                            clusters_i[obj_hierarchy[contourtocheck][2]]) >= 5:
                        obj_hierarchy[contourtocheck][2] = -1
        dotlist = list()
        for foundcontour in clusters_i:
            hierarchycontours = [obj_hierarchy[j][2] for j in foundcontour]
            if not all([bool(j == -1) for j in hierarchycontours]):
                dotlist.append(True)
            else:
                dotlist.append(False)
        colors = self.read_colors(out)
        for pnr in range(3):
            dot_characteristics.append(tuple((colors[pnr], dotlist[pnr])))
        try:
            return self.translator[self.translate(dot_characteristics)]
        except:
            return "Error"
    def read_image2(self, imageread):
        """This is the current implementation for finding and reading the dot codes. """
        os.chdir('/Users/gghosal/Desktop/gaurav/res/')
        self.centers = list()
        for i in self.listdir_nohidden('/Users/gghosal/Desktop/gaurav/res/'):
            os.remove(i)
        #color_recognition_dict={'red':0, "lightblue":98, "darkblue":120, "pink":175, "purple":140}
        img1 = imageread
        device, img1gray = pcv.rgb2gray(img1, 0)
        img1hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
        dev, img_binary = pcv.binary_threshold(img1gray, 1, 255, 'light', 0)
        device, id_objects, obj_hierarchy = pcv.find_objects(
            img1, img_binary, 0)

        device, roi, roi_hierarchy = pcv.define_roi(img1,
                                                    shape="rectangle",
                                                    device=device,
                                                    roi_input="default",
                                                    adjust=False,
                                                    x_adj=600,
                                                    y_adj=600,
                                                    w_adj=1200,
                                                    h_adj=1200)
        device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
            img1, "partial", roi, roi_hierarchy, id_objects, obj_hierarchy,
            device)

        device, clusters_i, contours, obj_hierarchy = pcv.cluster_contours(
            device=device,
            img=img1,
            roi_objects=roi_objects,
            roi_obj_hierarchy=roi_obj_hierarchy,
            nrow=1,
            ncol=int(3))

        out = "/Users/gghosal/Desktop/gaurav/res"
        device, output_path = pcv.cluster_contour_splitimg(
            device=device,
            img=img1,
            grouped_contour_indexes=clusters_i,
            contours=contours,
            hierarchy=obj_hierarchy,
            outdir=out)

        obj_hierarchy = obj_hierarchy[0]
        dotQ = list()
        centroids = list()
        totalcontours = list()
        for clusters1 in clusters_i:
            totalcontour = contours[clusters1[0]]
            for j in clusters1[1:]:
                totalcontour = np.concatenate((contours[j], totalcontour),
                                              axis=0)
            totalcontours.append(totalcontour)
            mmt = cv2.moments(totalcontour)
            ycoords = int(mmt['m10'] / mmt['m00'])
            xcoords = int(mmt['m01'] / mmt['m00'])

            self.centers.append(tuple([ycoords, xcoords]))
            centroids.append(tuple([xcoords, ycoords]))
        count11 = 0

        dot_cleaned = apply_brightness_contrast(imageread,
                                                brightness=0,
                                                contrast=49)

        dot_cleaned_grey = cv2.cvtColor(dot_cleaned, cv2.COLOR_RGB2HSV)
        dot_cleaned_thresh = cv2.inRange(dot_cleaned_grey,
                                         np.array([0, 0, 150]),
                                         np.array([255, 255, 255]))
        dot_cleaned = cv2.bitwise_and(dot_cleaned,
                                      dot_cleaned,
                                      mask=dot_cleaned_thresh)
        dot_kernel = np.ones((7, 7), np.uint8)

        dotQ = self.read_dot3(dot_cleaned)

        os.chdir(out)
        colors = list()
        dot_characteristics = list()
        for i in self.listdir_nohidden(out):
            #print(i)
            if self.masked(i):
                mask = cv2.imread(i, 0)
                unmasked = cv2.imread(i[0:-5])
                width = mask.shape[0]
                length = mask.shape[1]
                color_averagelist = list()
                masked_img1hsv = cv2.bitwise_and(img1hsv, img1hsv, mask=mask)
                color_averagelist = cv2.split(masked_img1hsv)[0]
                color_averagelist = np.reshape(color_averagelist,
                                               (color_averagelist.shape[0] *
                                                color_averagelist.shape[1], ))
                color_averagelist = color_averagelist[np.flatnonzero(
                    color_averagelist)]

                color_avg = statistics.mode(color_averagelist)
                resultsdict = dict()
                for color in self.colordefinitions:
                    resultsdict[color] = abs(self.colordefinitions[color] -
                                             color_avg)
                color = min(resultsdict, key=lambda x: resultsdict[x])
                colors.append(color)

        for pnr in range(3):
            dot_characteristics.append(tuple((colors[pnr], dotQ[pnr])))

        try:

            return self.translator.get(self.translate(dot_characteristics),
                                       self.translate(dot_characteristics))
        except Exception as e:

            pass
Пример #12
0
def main():
    # Get options
    args = options()

    # Read image
    img, path, filename = pcv.readimage(args.image)

    debug = args.debug

    # Pipeline step
    device = 0

    # Step 1: Check if this is a night image, for some of these datasets images were captured
    # at night, even if nothing is visible. To make sure that images are not taken at
    # night we check that the image isn't mostly dark (0=black, 255=white).
    # if it is a night image it throws a fatal error and stops the pipeline.

    if np.average(img) < 50:
        pcv.fatal_error("Night Image")
    else:
        pass

    # Step 2: Normalize the white color so you can later
    # compare color between images.
    # Inputs:
    # device = device number. Used to count steps in the workflow
    # img = image object, RGB colorspace
    # debug = None, print, or plot. Print = save to file, Plot = print to screen.
    # roi = region for white reference, if none uses the whole image,
    # otherwise (x position, y position, box width, box height)

    #white balance image based on white toughspot
    device, img1 = pcv.white_balance(device, img, debug, roi=white_balance_roi)
    # img1 = img

    # Step 3: Rotate the image

    # device, rotate_img = pcv.rotate(img1, -1, device, debug)

    #Step 4: Shift image. This step is important for clustering later on.
    # For this image it also allows you to push the green raspberry pi camera
    # out of the image. This step might not be necessary for all images.
    # The resulting image is the same size as the original.
    # Input:
    # img = image object
    # device = device number. Used to count steps in the workflow
    # number = integer, number of pixels to move image
    # side = direction to move from "top", "bottom", "right","left"
    # debug = None, print, or plot. Print = save to file, Plot = print to screen.

    # device, shift1 = pcv.shift_img(img1, device, 300, 'top', debug)
    # img1 = shift1

    # STEP 5: Convert image from RGB colorspace to LAB colorspace
    # Keep only the green-magenta channel (grayscale)
    # Inputs:
    #    img     = image object, RGB colorspace
    #    channel = color subchannel (l = lightness, a = green-magenta , b = blue-yellow)
    #    device  = device number. Used to count steps in the workflow
    #    debug   = None, print, or plot. Print = save to file, Plot = print to screen.
    device, a = pcv.rgb2gray_lab(img1, 'a', device, debug)

    # STEP 6: Set a binary threshold on the Saturation channel image
    # Inputs:
    #    img         = img object, grayscale
    #    threshold   = threshold value (0-255)
    #    maxValue    = value to apply above threshold (usually 255 = white)
    #    object_type = light or dark
    #                  - If object is light then standard thresholding is done
    #                  - If object is dark then inverse thresholding is done
    #    device      = device number. Used to count steps in the pipeline
    #    debug       = None, print, or plot. Print = save to file, Plot = print to screen.
    device, img_binary = pcv.binary_threshold(a, darkness_threshold, 255,
                                              'dark', device, debug)
    #                                            ^
    #                                            |
    #                                           adjust this value

    # STEP 7: Fill in small objects (speckles)
    # Inputs:
    #    img    = image object, grayscale. img will be returned after filling
    #    mask   = image object, grayscale. This image will be used to identify contours
    #    size   = minimum object area size in pixels (integer)
    #    device = device number. Used to count steps in the pipeline
    #    debug  = None, print, or plot. Print = save to file, Plot = print to screen.
    mask = np.copy(img_binary)
    device, fill_image = pcv.fill(img_binary, mask, minimum_object_area_pixels,
                                  device, debug)
    #                                               ^
    #                                               |
    #                                               adjust this value

    # STEP 8: Dilate so that you don't lose leaves (just in case)
    # Inputs:
    #    img     = input image
    #    kernel  = integer
    #    i       = interations, i.e. number of consecutive filtering passes
    #    device  = device number. Used to count steps in the pipeline
    #    debug   = None, print, or plot. Print = save to file, Plot = print to screen.

    device, dilated = pcv.dilate(fill_image, 1, 1, device, debug)

    # STEP 9: Find objects (contours: black-white boundaries)
    # Inputs:
    #    img       = image that the objects will be overlayed
    #    mask      = what is used for object detection
    #    device    = device number.  Used to count steps in the pipeline
    #    debug     = None, print, or plot. Print = save to file, Plot = print to screen.
    device, id_objects, obj_hierarchy = pcv.find_objects(
        img1, dilated, device, debug)

    # STEP 10: Define region of interest (ROI)
    # Inputs:
    #    img       = img to overlay roi
    #    roi       = default (None) or user input ROI image, object area should be white and background should be black,
    #                has not been optimized for more than one ROI
    #    roi_input = type of file roi_base is, either 'binary', 'rgb', or 'default' (no ROI inputted)
    #    shape     = desired shape of final roi, either 'rectangle' or 'circle', if  user inputs rectangular roi but chooses
    #                'circle' for shape then a circle is fitted around rectangular roi (and vice versa)
    #    device    = device number.  Used to count steps in the pipeline
    #    debug     = None, print, or plot. Print = save to file, Plot = print to screen.
    #    adjust    = either 'True' or 'False', if 'True' allows user to adjust ROI
    #    x_adj     = adjust center along x axis
    #    y_adj     = adjust center along y axis
    #    w_adj     = adjust width
    #    h_adj     = adjust height
    # x=0, y=560, h=4040-560, w=3456
    roi_contour, roi_hierarchy = pcv.roi.rectangle(**total_region_of_interest,
                                                   img=img1)
    # device, roi, roi_hierarchy = pcv.define_roi(img1, 'rectangle', device, None, 'default', debug, False,
    #                                             0, 0, 0, 0)
    #                                            ^                ^
    #                                            |________________|
    #                                            adjust these four values

    # STEP 11: Keep objects that overlap with the ROI
    # Inputs:
    #    img            = img to display kept objects
    #    roi_type       = 'cutto' or 'partial' (for partially inside)
    #    roi_contour    = contour of roi, output from "View and Ajust ROI" function
    #    roi_hierarchy  = contour of roi, output from "View and Ajust ROI" function
    #    object_contour = contours of objects, output from "Identifying Objects" fuction
    #    obj_hierarchy  = hierarchy of objects, output from "Identifying Objects" fuction
    #    device         = device number.  Used to count steps in the pipeline
    #    debug          = None, print, or plot. Print = save to file, Plot = print to screen.
    device, roi_objects, roi_obj_hierarchy, kept_mask, obj_area = pcv.roi_objects(
        img1, 'partial', roi_contour, roi_hierarchy, id_objects, obj_hierarchy,
        device, debug)

    # print(obj_area)

    #Step 12: This function take a image with multiple contours and
    # clusters them based on user input of rows and columns

    #Inputs:
    #    img - An RGB image array
    #    roi_objects - object contours in an image that are needed to be clustered.
    #    nrow - number of rows to cluster (this should be the approximate  number of desired rows in the entire image (even if there isn't a literal row of plants)
    #    ncol - number of columns to cluster (this should be the approximate number of desired columns in the entire image (even if there isn't a literal row of plants)
    #    file -  output of filename from read_image function
    #    filenames - input txt file with list of filenames in order from top to bottom left to right
    #    debug - print debugging images

    device, clusters_i, contours = pcv.cluster_contours(
        device, img1, roi_objects, expected_number_of_rows,
        expected_number_of_columns, debug)

    # print(contours)

    #Step 13:This function takes clustered contours and splits them into multiple images,
    #also does a check to make sure that the number of inputted filenames matches the number
    #of clustered contours. If no filenames are given then the objects are just numbered

    #Inputs:
    #    img - ideally a masked RGB image.
    #    grouped_contour_indexes - output of cluster_contours, indexes of clusters of contours
    #    contours - contours to cluster, output of cluster_contours
    #    filenames - input txt file with list of filenames in order from top to bottom left to right (likely list of genotypes)
    #    debug - print debugging images

    out = args.outdir
    names = args.names
    device, output_path = pcv.cluster_contour_splitimg(device,
                                                       img1,
                                                       clusters_i,
                                                       contours,
                                                       out,
                                                       file=filename,
                                                       filenames=names,
                                                       debug=debug)