Exemplo n.º 1
0
def annotate_video(model, class_names, video_path_in, video_path_out):

    tmp_dir = f"tmp_annotate_{np.random.randint(100000, 1000000)}"
    os.mkdir(tmp_dir)

    print("Extracting frames:")
    os.system(f"ffmpeg -i {video_path_in} -vf fps=30 {tmp_dir}/frame_%05d.jpeg -v quiet -stats")

    color_map = visualize.random_colors(len(class_names))

    for p in tqdm(glob.glob(f"{tmp_dir}/frame_*.jpeg"), desc="Annotating frames"):

        image = cv2.imread(p)
        r = model.detect([image])[0]

        #print(f"Annotating {p} with {r['class_ids'].shape} labels")

        if r['class_ids'].shape[0] > 0:
            r_fused = utils.fuse_instances(r)
        else:
            r_fused = r

        img = visualize.render_instances(image, r['rois'], r['masks'], r['class_ids'], class_names, r['scores'], color_map=color_map)
        cv2.imwrite(f"{tmp_dir}/annotated_{Path(p).name}", img)
    
    print("Rendering video:")
    os.system(f"ffmpeg -r 30 -i {tmp_dir}/annotated_frame_%05d.jpeg -c:v libx264 -vf fps=30 -pix_fmt yuv420p {video_path_out} -v quiet -stats")

    shutil.rmtree(tmp_dir, ignore_errors=True)
Exemplo n.º 2
0
def paint_detections(image, boxes, masks, class_names, class_ids, scores):
    
    font = cv2.FONT_HERSHEY_SIMPLEX
    # Number of instances
    N = boxes.shape[0]

    # Generate random colors
    colors = visualize.random_colors(N)
    
    #copy the image
    masked_image = image.astype(np.uint32).copy()
    
    #paint masks on it
    for i in range(N):
        color = colors[i]
        mask = masks[:, :, i]
        masked_image = visualize.apply_mask(masked_image, mask, color).astype('uint8')

        # paint BB rectangles
        y1, x1, y2, x2 = boxes[i]
        cv2.rectangle(masked_image, (x1,y1), (x2, y2), (0,255,0),2)
        
        class_id = class_ids[i]
        score = scores[i] if scores is not None else None
        label = class_names[class_id]
        x = random.randint(x1, (x1 + x2) // 2)
        caption = "{} {:.3f}".format(label, score) if score else label
        cv2.putText(masked_image, caption,(x1+3, y1+8), font, 0.3,(255,255,255))
    
    return masked_image
Exemplo n.º 3
0
def cv2_display_keypoint(image,
                         boxes,
                         keypoints,
                         masks,
                         class_ids,
                         scores,
                         class_names,
                         skeleton=inference_config.LIMBS):
    # Number of persons
    N = boxes.shape[0]
    if not N:
        print("\n*** No persons to display *** \n")
    else:
        assert N == keypoints.shape[0] and N == class_ids.shape[0] and N==scores.shape[0],\
            "shape must match: boxes,keypoints,class_ids, scores"
    colors = visualize.random_colors(N)
    for i in range(N):
        color = colors[i]
        # Bounding box
        if not np.any(boxes[i]):
            # Skip this instance. Has no bbox. Likely lost in image cropping.
            continue
        y1, x1, y2, x2 = boxes[i]
        cv2.rectangle(image, (x1, y1), (x2, y2), color, thickness=2)
        for Joint in keypoints[i]:
            if (Joint[2] != 0):
                cv2.circle(image, (Joint[0], Joint[1]), 2, color, -1)

        # #draw skeleton connection
        # limb_colors = [[0, 0, 255], [0, 170, 255], [0, 255, 170], [0, 255, 0], [170, 255, 0],
        #                [255, 170, 0], [255, 0, 0], [255, 0, 170], [170, 0, 255], [170, 170, 0], [170, 0, 170]]
        # if (len(skeleton)):
        #     skeleton = np.reshape(skeleton, (-1, 2))
        #     neck = np.array((keypoints[i, 5, :] + keypoints[i, 6, :]) / 2).astype(int)
        #     if (keypoints[i, 5, 2] == 0 or keypoints[i, 6, 2] == 0):
        #         neck = [0, 0, 0]
        #     limb_index = -1
        #     for limb in skeleton:
        #         limb_index += 1
        #         start_index, end_index = limb  # connection joint index from 0 to 16
        #         if (start_index == -1):
        #             Joint_start = neck
        #         else:
        #             Joint_start = keypoints[i][start_index]
        #         if (end_index == -1):
        #             Joint_end = neck
        #         else:
        #             Joint_end = keypoints[i][end_index]
        #         # both are Annotated
        #         # Joint:(x,y,v)
        #         if ((Joint_start[2] != 0) & (Joint_end[2] != 0)):
        #             # print(color)
        #             cv2.line(image, tuple(Joint_start[:2]), tuple(Joint_end[:2]), limb_colors[limb_index],3)
        mask = masks[:, :, i]
        image = visualize.apply_mask(image, mask, color)
        caption = "{} {:.3f}".format(class_names[class_ids[i]], scores[i])
        cv2.putText(image, caption, (x1 + 5, y1 + 16),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, color)
    return image
Exemplo n.º 4
0
def apply_masks(image, masks):
    N = masks.shape[-1]
    colors = visualize.random_colors(N)
    masked_image = image.astype(np.uint32).copy()
    for i in range(N):
        masked_image = visualize.apply_mask(masked_image, masks[:, :, i],
                                            colors[i])
    return masked_image, (masked_image - image).astype(np.uint32)
Exemplo n.º 5
0
 def generate(self):
     color_map = {}
     N = len(self.classes)
     for i, c in enumerate(random_colors(N)):
         color_map[self.classes[i]] = c
     f_name = '%s%s' % (self.class_color_file_name,
                        self.class_color_file_ext)
     with open(f_name, 'w') as f:
         if self.class_color_file_ext == '.yaml':
             logger.info('Generate yaml file.')
             yaml.dump(color_map, f, default_flow_style=False)
             logger.info('YAML %s file is generated.', f_name)
         elif self.class_color_file_ext == '.json':
             logger.info('Generate json file')
             json.dump(color_map, f, sort_keys=True, indent=4)
             logger.info('JSON %s file is generated.', f_name)
Exemplo n.º 6
0
def cv_display_instances(image, boxes, masks, class_ids, class_names,
                    scores=None, title="",
                    figsize=(16, 16)):
  # Number of instances
  N = boxes.shape[0]
  print(N)
  if not N:
      print("\n*** No instances to display *** \n")
  else:
      assert boxes.shape[0] == masks.shape[-1] == class_ids.shape[0]

  # Generate random colors
  colors = visualize.random_colors(N)

  height, width = image.shape[:2]

  masked_image = image.copy()#.astype(np.uint32).copy()
  for i in range(N):
      color = colors[i]

      # Bounding box
      if not np.any(boxes[i]):
          continue
      y1, x1, y2, x2 = boxes[i]
      cv_color = (color[0] * 255, color[1] * 255, color[2] * 255)
      cv2.rectangle(masked_image, (x1, y1), (x2, y2), cv_color , 1)

      # Label
      class_id = class_ids[i]
      score = scores[i] if scores is not None else None
      label = class_names[class_id]
      print(label)
      x = random.randint(x1, (x1 + x2) // 2)
      caption = "{} {:.3f}".format(label, score) if score else label

      font = cv2.FONT_HERSHEY_PLAIN
      cv2.putText(masked_image,caption,(x1, y1),font, 1, cv_color)

      # Mask
      mask = masks[:, :, i]
      masked_image = visualize.apply_mask(masked_image, mask, color)


  masked_image.astype(np.uint8)
  return masked_image
Exemplo n.º 7
0
def main(argv=None):
    ROOT_DIR = os.getcwd()

    with tf.gfile.FastGFile("./pb_out_new.pb", 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        _ = tf.import_graph_def(graph_def, name='')
    print('Graph loaded.')

    with tf.Session() as sess:
        #IMAGE_DIR = os.path.join(ROOT_DIR, 'images') #image of the size defined in the config
        #file_names = next(os.walk(IMAGE_DIR))[2]
        #filename = random.choice(file_names)
        #print('choose image file is', filename)
        image = skimage.io.imread("./151.jpg")
        #       os.system('eog %s &'%(os.path.join(IMAGE_DIR,filename)))
        print(image.shape)
        images = [image]
        print("Processing {} images".format(len(images)))
        print('RGB image loaded and preprocessed.')

        molded_images, image_metas, windows = mold_inputs(images)
        print(molded_images.shape)

        image_shape = molded_images[0].shape
        # Anchors
        anchors = get_anchors(image_shape, inference_config)
        # Duplicate across the batch dimension because Keras requires it
        # TODO: can this be optimized to avoid duplicating the anchors?
        inference_config.BATCH_SIZE = 1
        image_anchors = np.broadcast_to(
            anchors, (inference_config.BATCH_SIZE, ) + anchors.shape)
        print('anchors shape is', image_anchors.shape, image_anchors.dtype)

        img_ph = sess.graph.get_tensor_by_name('input_image:0')
        print(img_ph)
        img_anchors_ph = sess.graph.get_tensor_by_name('input_anchors:0')
        print(img_anchors_ph)
        img_meta_ph = sess.graph.get_tensor_by_name('input_image_meta:0')
        print(img_meta_ph)
        detectionsT = sess.graph.get_tensor_by_name('output_detections:0')
        print('Found ', detectionsT)
        mrcnn_classT = sess.graph.get_tensor_by_name('output_mrcnn_class:0')
        print('Found ', mrcnn_classT)
        mrcnn_bboxT = sess.graph.get_tensor_by_name('output_mrcnn_bbox:0')
        print('Found ', mrcnn_bboxT)
        mrcnn_maskT = sess.graph.get_tensor_by_name('output_mrcnn_mask:0')
        print('Found ', mrcnn_maskT)
        roisT = sess.graph.get_tensor_by_name('output_rois:0')
        print('Found ', roisT)

        np.set_printoptions(suppress=False, precision=4)
        print('Windows', windows.shape, ' ', windows)
        detections = sess.run(detectionsT,
                              feed_dict={
                                  img_ph: molded_images,
                                  img_meta_ph: image_metas,
                                  img_anchors_ph: image_anchors
                              })
        #print('Detections: ',detections[0].shape, detections[0])
        mrcnn_class = sess.run(mrcnn_classT,
                               feed_dict={
                                   img_ph: molded_images,
                                   img_meta_ph: image_metas,
                                   img_anchors_ph: image_anchors
                               })
        #print('Classes: ',mrcnn_class[0].shape, mrcnn_class[0])
        mrcnn_bbox = sess.run(mrcnn_bboxT,
                              feed_dict={
                                  img_ph: molded_images,
                                  img_meta_ph: image_metas,
                                  img_anchors_ph: image_anchors
                              })
        #print('BBoxes: ',mrcnn_bbox[0].shape, mrcnn_bbox[0])
        mrcnn_mask = sess.run(mrcnn_maskT,
                              feed_dict={
                                  img_ph: molded_images,
                                  img_meta_ph: image_metas,
                                  img_anchors_ph: image_anchors
                              })
        #print('Masks: ',mrcnn_mask[0].shape )#, outputs1[0])
        rois = sess.run(roisT,
                        feed_dict={
                            img_ph: molded_images,
                            img_meta_ph: image_metas,
                            img_anchors_ph: image_anchors
                        })
        #print('Rois: ',rois[0].shape, rois[0])

        results = []
        for i, image in enumerate(images):
            final_rois, final_class_ids, final_scores, final_masks =\
                unmold_detections(detections[i], mrcnn_mask[i],
                                  image.shape, molded_images[i].shape,
                                  windows[i])
            results.append({
                "rois": final_rois,
                "class_ids": final_class_ids,
                "scores": final_scores,
                "masks": final_masks,
            })

        r = results[0]
        print(results)
        #print('result is', r)
        class_names = [
            'BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
            'train', 'truck', 'boat', 'traffic light', 'fire hydrant',
            'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog',
            'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe',
            'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
            'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat',
            'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
            'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
            'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot',
            'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
            'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop',
            'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven',
            'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase',
            'scissors', 'teddy bear', 'hair drier', 'toothbrush'
        ]
        #visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'], class_names, r['scores'])#, ax=get_ax())
    print('Done')

    print("mask shape", r['masks'].shape)
    #image = cv2.imread(testImage)
    N = r['rois'].shape[0]  #find out how many different instances are there
    try:  #if no mask simply return image frame
        mask = r['masks'][:, :, 0]
        color = visualize.random_colors(N)  #generates random instance colors
        color = color[0]
        image = visualize.apply_mask(image, mask, color)
    except Exception as e:
        print(e)
    cv2.imshow('test', image)
    cv2.waitKey(0)
    return 0
Exemplo n.º 8
0
for l in range(num_levels):
    num_cells = BACKBONE_SHAPES[l][0] * BACKBONE_SHAPES[l][1]
    anchors_per_level.append(anchors_per_cell * num_cells //
                             config.RPN_ANCHOR_STRIDE**2)
    print("Anchors in Level {}: {}".format(l, anchors_per_level[l]))

## Visualize anchors of one cell at the center of the feature map of a specific level

# Load and draw random image
image, image_meta, _, _, _ = modellib.load_image_gt(dataset, config, image_id)
fig, ax = plt.subplots(1, figsize=(10, 10))
ax.imshow(image)
levels = len(BACKBONE_SHAPES)

for level in range(levels):
    colors = visualize.random_colors(levels)
    # Compute the index of the anchors at the center of the image
    level_start = sum(
        anchors_per_level[:level])  # sum of anchors of previous levels
    level_anchors = anchors[level_start:level_start + anchors_per_level[level]]
    print("Level {}. Anchors: {:6}  Feature map Shape: {}".format(
        level, level_anchors.shape[0], BACKBONE_SHAPES[level]))
    center_cell = BACKBONE_SHAPES[level] // 2
    center_cell_index = (center_cell[0] * BACKBONE_SHAPES[level][1] +
                         center_cell[1])
    level_center = center_cell_index * anchors_per_cell
    center_anchor = anchors_per_cell * (
        (center_cell[0] * BACKBONE_SHAPES[level][1] / config.RPN_ANCHOR_STRIDE**2) \
        + center_cell[1] / config.RPN_ANCHOR_STRIDE)
    level_center = int(center_anchor)
Exemplo n.º 9
0
#im=visualize.display_instances(image, r['rois'], r['masks'], r['class_ids'],
#class_names, r['scores'])
#skimage.io.imsave('/home/ltp/图片/smplayer_screenshots/crop/I2/'+v,im)
# Load a random image from the images folderim,ax =plt.subplots(1,figsize = (16,16))
IMAGE_DIR = train_dir  #'./images/'
file_names = '3870_426771.jpg'  #next(os.walk(IMAGE_DIR))[2]
random.seed(120)
image = skimage.io.imread(IMAGE_DIR + file_names)

# Run detection
results = model.detect([image], verbose=0)
#results = model.detect_filter([image],f['label'][...].transpose(), verbose=0)
# Visualize results
r = results[0]
color = visualize.random_colors(N=config.NUM_CLASSES)
im = visualize.apply_mask(image,
                          r['masks'],
                          color=color,
                          class_ids=[v for v in range(1, config.NUM_CLASSES)])
att_prob = model.run_graph([image],
                           model.get_layers_by_name(['mask_att_prob']))
att_prob = scipy.ndimage.zoom(att_prob['mask_att_prob'][0], zoom=[8, 8, 1])
molded_images, image_metas, windows = model.mold_inputs([image])
a_prob, _ = model.unmold_detections(att_prob, att_prob[..., 0], image.shape,
                                    windows[0])
print(a_prob.sum(2))
for v in range(3):
    plt.subplot(1, 3, v + 1)
    skimage.io.imshow(50 * (att_prob[..., v] - 0.33), cmap='rainbow')
plt.show()
Exemplo n.º 10
0
def display_keypoints(image,
                      boxes,
                      keypoints,
                      class_ids,
                      class_names,
                      skeleton=[],
                      scores=None,
                      title="",
                      figsize=(16, 16),
                      ax=None):
    """
    boxes: [num_persons, (y1, x1, y2, x2)] in image coordinates.
    keypoints: [num_persons, num_keypoint, 3]
    class_ids: [num_persons]
    class_names: list of class names of the dataset
    scores: (optional) confidence scores for each box
    figsize: (optional) the size of the image.
    """
    # Number of persons
    N = boxes.shape[0]
    keypoints = np.array(keypoints).astype(int)
    print("keypoint_shape:", np.shape(keypoints))
    if not N:
        print("\n*** No persons to display *** \n")
    else:
        assert boxes.shape[0] == keypoints.shape[0] == class_ids.shape[0]

    if not ax:
        _, ax = plt.subplots(1, figsize=figsize)

    # Generate random colors
    colors = visualize.random_colors(N)

    # Show area outside image boundaries.
    height, width = image.shape[:2]
    ax.set_ylim(height + 10, -10)
    ax.set_xlim(-10, width + 10)
    ax.axis('off')
    ax.set_title(title)
    skeleton_image = image.astype(np.float32).copy()
    for i in range(N):
        color = colors[i]

        # Bounding box
        if not np.any(boxes[i]):
            # Skip this instance. Has no bbox. Likely lost in image cropping.
            continue
        y1, x1, y2, x2 = boxes[i]
        p = patches.Rectangle((x1, y1),
                              x2 - x1,
                              y2 - y1,
                              linewidth=2,
                              alpha=0.7,
                              linestyle="dashed",
                              edgecolor=color,
                              facecolor='none')
        ax.add_patch(p)

        # Label
        class_id = class_ids[i]
        score = scores[i] if scores is not None else None
        label = class_names[class_id]
        # x = random.randint(x1, (x1 + x2) // 2)
        caption = "{} {:.3f}".format(label, score) if score else label
        ax.text(x1,
                y1 + 8,
                caption,
                color='w',
                size=11,
                backgroundcolor="none")
        # Keypoints: num_person, num_keypoint, 3
        for Joint in keypoints[i]:
            if (Joint[2] != 0):
                circle = patches.Circle((Joint[0], Joint[1]),
                                        radius=1,
                                        edgecolor=color,
                                        facecolor='none')
                ax.add_patch(circle)

        # Skeleton: 11*2
        limb_colors = [[0, 0, 255], [0, 170, 255], [0, 255, 170], [0, 255, 0],
                       [170, 255, 0], [255, 170, 0], [255, 0, 0],
                       [255, 0, 170], [170, 0, 255], [170, 170, 0],
                       [170, 0, 170]]
        if (len(skeleton)):
            skeleton = np.reshape(skeleton, (-1, 2))
            neck = np.array(
                (keypoints[i, 5, :] + keypoints[i, 6, :]) / 2).astype(int)
            if (keypoints[i, 5, 2] == 0 or keypoints[i, 6, 2] == 0):
                neck = [0, 0, 0]
            limb_index = -1
            for limb in skeleton:
                limb_index += 1
                start_index, end_index = limb  # connection joint index from 0 to 16
                if (start_index == -1):
                    Joint_start = neck
                else:
                    Joint_start = keypoints[i][start_index]
                if (end_index == -1):
                    Joint_end = neck
                else:
                    Joint_end = keypoints[i][end_index]
                # both are Annotated
                # Joint:(x,y,v)
                if ((Joint_start[2] != 0) & (Joint_end[2] != 0)):
                    # print(color)
                    cv2.line(skeleton_image, tuple(Joint_start[:2]),
                             tuple(Joint_end[:2]), limb_colors[limb_index], 5)
    ax.imshow(skeleton_image.astype(np.uint8))
    plt.show()
Exemplo n.º 11
0
def cv2_display_keypoint(image, boxes, masks, class_ids, scores, class_names):
    # Number of lips
    N = boxes.shape[0]
    print("number of lips " + str(N))

    if (N < 2):
        return image, "minimum not found"

    if not N:
        print("\n*** No lips to display *** \n")
    else:
        assert N == class_ids.shape[0] and N==scores.shape[0],\
            "shape must match: boxes,keypoints,class_ids, scores"
    colors = visualize.random_colors(N)

    class1 = True
    class2 = True

    keypoints = []
    classes = []

    for i in range(N):
        if class_ids[i] == 1:
            classes.append(i)
            break

    for i in range(N):
        if class_ids[i] == 2:
            classes.append(i)
            break

    for k in range(len(classes)):
        i = classes[k]
        color = colors[i]
        # Bounding box
        if not np.any(boxes[i]):
            # Skip this instance. Has no bbox. Likely lost in image cropping.
            continue
        y1, x1, y2, x2 = boxes[i]
        # cv2.rectangle(image, (x1, y1), (x2, y2), color, thickness=2)

        mask = masks[:, :, i]

        if scores[i] >= 0.9:

            column_first_non_zero = first_nonzero(mask, axis=0, invalid_val=-1)
            column_last_non_zero = last_nonzero(mask, axis=0, invalid_val=-1)
            row_first_non_zero = first_nonzero(mask, axis=1, invalid_val=-1)
            row_last_non_zero = last_nonzero(mask, axis=1, invalid_val=-1)

            if (lip_orientation(column_first_non_zero, row_first_non_zero)
                    in "horizontal"):

                #for class 1
                if class_ids[i] == 1 and class1:
                    class1 = False
                    indexes_column_last_positive = np.where(
                        column_last_non_zero > -1)[0]
                    indexes_column_first_positive = np.where(
                        column_first_non_zero > -1)[0]

                    xf = indexes_column_last_positive[0]
                    xl = indexes_column_last_positive[
                        len(indexes_column_last_positive) - 1]
                    yf = column_last_non_zero[xf]
                    yl = column_last_non_zero[xl]

                    if (yf < yl):
                        #first corner up
                        xf = indexes_column_first_positive[0]
                        yf = column_first_non_zero[xf]
                    elif (yf > yl):
                        #last corner up
                        xl = indexes_column_first_positive[
                            len(indexes_column_first_positive) - 1]
                        yl = column_first_non_zero[xl]

                    cv2.circle(image, (xf, yf), 2, color, -1)
                    cv2.circle(image, (xl, yl), 2, color, -1)

                    keypoints.append([xf, yf])
                    keypoints.append([xl, yl])

                    #mid points of 2 corners
                    x_mid_line = int(round((xf + xl) / 2))
                    y_mid_line = int(round((yf + yl) / 2))

                    #spliting columns from mid point
                    index_largest_last = np.argmax(column_last_non_zero)
                    yl = column_last_non_zero[index_largest_last]
                    max_replaced_neg = np.where(column_first_non_zero == -1,
                                                yl, column_first_non_zero)
                    column_first_half = max_replaced_neg[:x_mid_line]
                    column_last_half = max_replaced_neg[x_mid_line:]

                    #upper part upper lip

                    #upper lip upper left high point
                    temp = column_first_half[::-1]
                    upper_lip_left_high_x = len(temp) - np.argmin(temp) - 1
                    upper_lip_left_high_y = column_first_half[
                        upper_lip_left_high_x]
                    cv2.circle(image,
                               (upper_lip_left_high_x, upper_lip_left_high_y),
                               2, color, -1)
                    keypoints.append(
                        [upper_lip_left_high_x, upper_lip_left_high_y])

                    #center of left corner and left high point
                    center_left_corner_high_x = int(
                        round((xf + upper_lip_left_high_x) / 2))
                    center_left_corner_high_y = column_first_non_zero[
                        center_left_corner_high_x]
                    cv2.circle(
                        image,
                        (center_left_corner_high_x, center_left_corner_high_y),
                        2, color, -1)
                    keypoints.append(
                        [center_left_corner_high_x, center_left_corner_high_y])

                    # upper lip upper right high point
                    upper_lip_right_high_x = np.argmin(column_last_half)
                    upper_lip_right_high_y = column_last_half[
                        upper_lip_right_high_x]
                    cv2.circle(
                        image,
                        (len(column_first_half) + upper_lip_right_high_x,
                         upper_lip_right_high_y), 2, color, -1)
                    keypoints.append([
                        len(column_first_half) + upper_lip_right_high_x,
                        upper_lip_right_high_y
                    ])

                    # center of right corner and right high point
                    center_right_corner_high_x = int(
                        round((xl + len(column_first_half) +
                               upper_lip_right_high_x) / 2))
                    center_right_corner_high_y = column_first_non_zero[
                        center_right_corner_high_x]
                    cv2.circle(image, (center_right_corner_high_x,
                                       center_right_corner_high_y), 2, color,
                               -1)
                    keypoints.append([
                        center_right_corner_high_x, center_right_corner_high_y
                    ])

                    #actual mid point of upper upper lip
                    mid_point_x = int(
                        round((upper_lip_left_high_x + len(column_first_half) +
                               upper_lip_right_high_x) / 2))
                    mid_point_y = column_first_non_zero[mid_point_x]
                    cv2.circle(image, (mid_point_x, mid_point_y), 2, color, -1)
                    keypoints.append([mid_point_x, mid_point_y])

                    #lower part of upper lip

                    # angle of lip with x-axis
                    angle = math.atan((yl - yf) / (xl - xf))

                    #mid point lower upper lip
                    length = column_last_non_zero[mid_point_x] - mid_point_y
                    x_mid_point_low = int(
                        round(mid_point_x + math.sin(angle) * length))
                    y_mid_point_low = int(
                        round(mid_point_y + math.cos(angle) * length))
                    cv2.circle(image, (x_mid_point_low, y_mid_point_low), 2,
                               color, -1)
                    keypoints.append([x_mid_point_low, y_mid_point_low])

                    # upper lip lower left high point
                    length = column_last_non_zero[
                        upper_lip_left_high_x] - upper_lip_left_high_y
                    upper_lip_left_lower_x = int(
                        round(upper_lip_left_high_x +
                              math.sin(angle) * length))
                    upper_lip_left_lower_y = int(
                        round(upper_lip_left_high_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (upper_lip_left_lower_x, upper_lip_left_lower_y), 2,
                        color, -1)
                    keypoints.append(
                        [upper_lip_left_lower_x, upper_lip_left_lower_y])

                    # upper lip lower right high point
                    length = column_last_non_zero[
                        len(column_first_half) +
                        upper_lip_right_high_x] - upper_lip_right_high_y
                    upper_lip_right_lower_x = int(
                        round(
                            len(column_first_half) + upper_lip_right_high_x +
                            math.sin(angle) * length))
                    upper_lip_right_lower_y = int(
                        round(upper_lip_right_high_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (upper_lip_right_lower_x, upper_lip_right_lower_y), 2,
                        color, -1)
                    keypoints.append(
                        [upper_lip_right_lower_x, upper_lip_right_lower_y])

                    # upper lip lower center of right corner and right high point
                    length = column_last_non_zero[
                        center_right_corner_high_x] - center_right_corner_high_y
                    upper_lip_right_corner_lower_x = int(
                        round(center_right_corner_high_x +
                              math.sin(angle) * length))
                    upper_lip_right__corner_lower_y = int(
                        round(center_right_corner_high_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (upper_lip_right_corner_lower_x,
                                       upper_lip_right__corner_lower_y), 2,
                               color, -1)
                    keypoints.append([
                        upper_lip_right_corner_lower_x,
                        upper_lip_right__corner_lower_y
                    ])

                    # lower center of left corner and left high point
                    length = column_last_non_zero[
                        center_left_corner_high_x] - center_left_corner_high_y
                    upper_lip_left_corner_lower_x = int(
                        round(center_left_corner_high_x +
                              math.sin(angle) * length))
                    upper_lip_left_corner_lower_y = int(
                        round(center_left_corner_high_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (upper_lip_left_corner_lower_x,
                                       upper_lip_left_corner_lower_y), 2,
                               color, -1)
                    keypoints.append([
                        upper_lip_left_corner_lower_x,
                        upper_lip_left_corner_lower_y
                    ])

                if class_ids[i] == 2 and class2 and not class1:
                    class2 = False
                    #lower lip upper part

                    # mid point upper lower lip
                    length = column_first_non_zero[mid_point_x] - mid_point_y
                    x_mid_point_up_lower = int(
                        round(mid_point_x + math.sin(angle) * length))
                    y_mid_point_up_lower = int(
                        round(mid_point_y + math.cos(angle) * length))
                    cv2.circle(image,
                               (x_mid_point_up_lower, y_mid_point_up_lower), 2,
                               color, -1)
                    keypoints.append(
                        [x_mid_point_up_lower, y_mid_point_up_lower])

                    # lower lip upper left high point
                    length = column_first_non_zero[
                        upper_lip_left_high_x] - upper_lip_left_high_y
                    lower_lip_left_upper_x = int(
                        round(upper_lip_left_high_x +
                              math.sin(angle) * length))
                    lower_lip_left_upper_y = int(
                        round(upper_lip_left_high_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (lower_lip_left_upper_x, lower_lip_left_upper_y), 2,
                        color, -1)
                    keypoints.append(
                        [lower_lip_left_upper_x, lower_lip_left_upper_y])

                    # lower lip upper right high point
                    length = column_first_non_zero[
                        len(column_first_half) +
                        upper_lip_right_high_x] - upper_lip_right_high_y
                    lower_lip_right_upper_x = int(
                        round(
                            len(column_first_half) + upper_lip_right_high_x +
                            math.sin(angle) * length))
                    lower_lip_right_upper_y = int(
                        round(upper_lip_right_high_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (lower_lip_right_upper_x, lower_lip_right_upper_y), 2,
                        color, -1)
                    keypoints.append(
                        [lower_lip_right_upper_x, lower_lip_right_upper_y])

                    # lower lip upper center of right corner and right high point
                    length = column_first_non_zero[
                        center_right_corner_high_x] - center_right_corner_high_y
                    lower_lip_right_corner_upper_x = int(
                        round(center_right_corner_high_x +
                              math.sin(angle) * length))
                    lower_lip_right_corner_upper_y = int(
                        round(center_right_corner_high_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (lower_lip_right_corner_upper_x,
                                       lower_lip_right_corner_upper_y), 2,
                               color, -1)
                    keypoints.append([
                        lower_lip_right_corner_upper_x,
                        lower_lip_right_corner_upper_y
                    ])

                    # lower center of left corner and left high point
                    length = column_first_non_zero[
                        center_left_corner_high_x] - center_left_corner_high_y
                    lower_lip_left_corner_upper_x = int(
                        round(center_left_corner_high_x +
                              math.sin(angle) * length))
                    lower_lip_left_corner_upper_y = int(
                        round(center_left_corner_high_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (lower_lip_left_corner_upper_x,
                                       lower_lip_left_corner_upper_y), 2,
                               color, -1)
                    keypoints.append([
                        lower_lip_left_corner_upper_x,
                        lower_lip_left_corner_upper_y
                    ])

                    #lower lip lower part
                    # mid point lower lower lip
                    length = column_last_non_zero[
                        x_mid_point_up_lower] - y_mid_point_up_lower
                    x_mid_point_low_lower = int(
                        round(x_mid_point_up_lower + math.sin(angle) * length))
                    y_mid_point_low_lower = int(
                        round(y_mid_point_up_lower + math.cos(angle) * length))
                    cv2.circle(image,
                               (x_mid_point_low_lower, y_mid_point_low_lower),
                               2, color, -1)
                    keypoints.append(
                        [x_mid_point_low_lower, y_mid_point_low_lower])

                    # lower lip lower left high point
                    length = column_last_non_zero[
                        lower_lip_left_upper_x] - lower_lip_left_upper_y
                    lower_lip_left_lower_x = int(
                        round(lower_lip_left_upper_x +
                              math.sin(angle) * length))
                    lower_lip_left_lower_y = int(
                        round(lower_lip_left_upper_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (lower_lip_left_lower_x, lower_lip_left_lower_y), 2,
                        color, -1)
                    keypoints.append(
                        [lower_lip_left_lower_x, lower_lip_left_lower_y])

                    # lower lip lower right high point
                    length = column_last_non_zero[
                        lower_lip_right_upper_x] - lower_lip_right_upper_y
                    lower_lip_right_lower_x = int(
                        round(lower_lip_right_upper_x +
                              math.sin(angle) * length))
                    lower_lip_right_lower_y = int(
                        round(lower_lip_right_upper_y +
                              math.cos(angle) * length))
                    cv2.circle(
                        image,
                        (lower_lip_right_lower_x, lower_lip_right_lower_y), 2,
                        color, -1)
                    keypoints.append(
                        [lower_lip_right_lower_x, lower_lip_right_lower_y])

                    # lower lip lower center of right corner and right high point
                    length = column_last_non_zero[
                        lower_lip_right_corner_upper_x] - lower_lip_right_corner_upper_y
                    lower_lip_right_corner_lower_x = int(
                        round(lower_lip_right_corner_upper_x +
                              math.sin(angle) * length))
                    lower_lip_right_corner_lower_y = int(
                        round(lower_lip_right_corner_upper_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (lower_lip_right_corner_lower_x,
                                       lower_lip_right_corner_lower_y), 2,
                               color, -1)
                    keypoints.append([
                        lower_lip_right_corner_lower_x,
                        lower_lip_right_corner_lower_y
                    ])

                    # lower center of left corner and left high point
                    length = column_last_non_zero[
                        lower_lip_left_corner_upper_x] - lower_lip_left_corner_upper_y
                    lower_lip_left_corner_lower_x = int(
                        round(lower_lip_left_corner_upper_x +
                              math.sin(angle) * length))
                    lower_lip_left_corner_lower_y = int(
                        round(lower_lip_left_corner_upper_y +
                              math.cos(angle) * length))
                    cv2.circle(image, (lower_lip_left_corner_lower_x,
                                       lower_lip_left_corner_lower_y), 2,
                               color, -1)
                    keypoints.append([
                        lower_lip_left_corner_lower_x,
                        lower_lip_left_corner_lower_y
                    ])

            image = visualize.apply_mask(image, mask, color)
            # caption = "{} {:.3f}".format(class_names[class_ids[i]], scores[i])
            # cv2.putText(image, caption, (x1 + 5, y1 + 16), cv2.FONT_HERSHEY_SIMPLEX,
            #             0.5, color)

    s = ""
    if (len(keypoints) > 1 and len(keypoints[0]) > 1):
        distance = math.sqrt(((keypoints[0][0] - keypoints[1][0])**2) +
                             ((keypoints[0][1] - keypoints[1][1])**2))
    else:
        distance = 0
    p = 0
    while (p < len(keypoints)):
        q = p + 1
        while (q < len(keypoints)):
            hor = math.sqrt(((keypoints[p][0] - keypoints[q][0])**2) +
                            ((keypoints[p][1] - keypoints[q][1])**2))
            if hor != 0:
                s = s + str(format(distance / hor, '.3f')) + ", "
            q += 1
        p += 1
    return image, s
Exemplo n.º 12
0
def detectVideoOffline(model, video_path):
    """ Detects instances in video, produces vector plots and saves to file
    
    Notes
    -----
    - Saves to local directory:
            Video with colour effect applied
            Images of vector plots
        
    - Requires matlab.engine to interface with camera model script for
      pixelToVector calculations.
    
    Parameters
    ----------
    model :  Tensorflow model
        Mask-RCNN model in inference mode.
        Generated in runNetwork().
        
    video_path : file/path/to/video
        Path to video upon which to do detection.
        User-defined.
    
    Returns
    -------
    None
    
    """
    angle1 = -125
    angle2 = -70
    class_names = ['BG', 'Duckie']

    # Open 3d plot with origin at [0,0,0]
    fig = plt.figure(figsize=(7, 7 / 3))
    ax2 = fig.add_subplot(121, projection='3d')
    ax2.cla()
    ax2.set_xlim(-1, 1)
    ax2.set_ylim(-1, 1)
    ax2.set_zlim(0, 1)
    ax2.set_title('Optimised pixelToVector function')
    ax2.set_xlabel("x", fontsize=16)
    ax2.set_ylabel("y", fontsize=16)
    ax2.set_zlabel("z", fontsize=16)
    ax2.view_init(elev=angle1, azim=angle2)

    #    ax2 = fig.add_subplot(122, projection='3d')
    #    ax2.cla()
    #    ax2.set_xlim(-1, 1)
    #    ax2.set_ylim(-1, 1)
    #    ax2.set_zlim(0, 1)
    #    ax2.set_title('Non-optimised pixelToVector function')
    #    ax2.set_xlabel("x", fontsize=16)
    #    ax2.set_ylabel("y", fontsize=16)
    #    ax2.set_zlabel("z", fontsize=16)
    #    ax2.view_init(elev=angle1, azim=angle2)
    #    plt.tight_layout()
    plt.show()

    # Generate filenames and create directories
    file_name_orig = "offline_rec_{:%Y%m%dT%H%M%S}".format(
        datetime.datetime.now())
    rootDir = ROOT_DIR + r'/Recordings/' + file_name_orig + r'/'
    rootDir_orig = rootDir + r'orig/'
    rootDir_vec = rootDir + r'vec/'
    rootDir_col = rootDir + r'col/'
    os.mkdir(rootDir)
    os.mkdir(rootDir_orig)
    os.mkdir(rootDir_vec)
    os.mkdir(rootDir_col)

    lines = []
    lines2 = []
    frameCount = -1
    origin = [0, 0, 0]
    height = 200
    angularWidth = 0
    distance = 0
    dpi = 72
    imageSize = (32, 32)
    imDuckie = image.imread(r'PlotImages\duckie.png')
    imCamera = image.imread(r'PlotImages\wheatley.png')
    imDuckie = OffsetImage(imDuckie, zoom=0.25)
    imCamera = OffsetImage(imCamera, zoom=0.1)
    capture = cv2.VideoCapture(video_path)

    while True:
        frameCount += 1
        print("Frame #", frameCount)

        ret, frame = capture.read()

        # Detect objects
        results = model.detect([frame], verbose=0)
        r = results[0]

        # Get points of interest
        tL, bL, tR, bT, centre = getPoints(r['rois'])

        if (r['rois'].shape[0] > 0):
            # Clear previous lines and reset format
            ax2.cla()
            ax2.set_xlim(-1, 1)
            ax2.set_ylim(-1, 1)
            ax2.set_zlim(0, 1)
            ax2.set_title('Non-optimised pixelToVector function')
            ax2.set_xlabel("x", fontsize=16)
            ax2.set_ylabel("y", fontsize=16)
            ax2.set_zlabel("z", fontsize=16)
            #ax2.view_init(elev=angle1, azim=angle2)

            angularWidth = []
            distance = []

            # Plot vector from origin to centre of each object
            for i in range(r['rois'].shape[0]):

                # Do pixeltovector function using upper left and bottom left
                u_uLeft = float(tL[i][0])
                v_uLeft = float(tL[i][1])
                u_bLeft = float(bL[i][0])
                v_bLeft = float(bL[i][1])

                l_Vec = eng.pixeltovector(float(u_uLeft), float(v_uLeft))
                r_Vec = eng.pixeltovector(float(u_bLeft), float(v_bLeft))

                l_Vec = [l_Vec[0][3], l_Vec[0][4], l_Vec[0][5]]
                r_Vec = [r_Vec[0][3], r_Vec[0][4], r_Vec[0][5]]

                # Using diameter, not radius
                angularWidth.append(vectorAngle(l_Vec, r_Vec))

                # Estimating distance
                # (probably doing this wrong, too sleepy to think)
                distance.append(height / np.tan(angularWidth[i]))

                # Do pixeltovector function using centre points
                # Run from MATLAB
                u_centre = float(centre[i][0])
                v_centre = float(centre[i][1])
                res = eng.pixeltovector(float(u_centre), float(v_centre))
                noptVect = [res[0][0], res[0][1], res[0][2]]
                optVect = [res[0][3], res[0][4], res[0][5]]

                # Plot optimised vector
                #                duckieVector = optVect
                #                xs = asarray([origin[0], duckieVector[0]])
                #                ys = asarray([origin[1], duckieVector[1]])
                #                zs = asarray([origin[2], duckieVector[2]])
                #                colors = random_colors(r['rois'].shape[0])
                #                lines.append(ax.plot(xs, ys, zs, color=colors[i],
                #                                     mfc="None", mec="None",
                #                                     markersize=imageSize[0]*(dpi/96)))
                #
                #                xOrigin, yOrigin, _ = proj3d.proj_transform(0,0,0,
                #                                                            ax.get_proj())
                #
                #                xDuck, yDuck, _ = proj3d.proj_transform(duckieVector[0],
                #                                                        duckieVector[1],
                #                                                        duckieVector[2],
                #                                                        ax.get_proj())
                #                ab1 = AnnotationBbox(imDuckie, [xDuck,yDuck])
                #                ab2 = AnnotationBbox(imCamera, [xOrigin,yOrigin])
                #                ax.add_artist(ab1)
                #                ax.add_artist(ab2)

                # Plot non-optimised vector
                duckieVector = noptVect
                xs = asarray([origin[0], duckieVector[0]])
                ys = asarray([origin[1], duckieVector[1]])
                zs = asarray([origin[2], duckieVector[2]])
                plt.tight_layout()
                colors = random_colors(r['rois'].shape[0])
                lines2.append(
                    ax2.plot(xs,
                             ys,
                             zs,
                             color=colors[i],
                             mfc="None",
                             mec="None",
                             markersize=imageSize[0] * (dpi / 96)))

                xOrigin, yOrigin, _ = proj3d.proj_transform(
                    0, 0, 0, ax2.get_proj())

                xDuck, yDuck, _ = proj3d.proj_transform(
                    duckieVector[0], duckieVector[1], duckieVector[2],
                    ax2.get_proj())
                ab1 = AnnotationBbox(imDuckie, [xDuck, yDuck])
                ab2 = AnnotationBbox(imCamera, [xOrigin, yOrigin])
                ax2.add_artist(ab1)
                ax2.add_artist(ab2)
                plt.tight_layout()
                plt.pause(0.1)

        frame = displayDetections(frame, r['rois'], r['masks'], r['class_ids'],
                                  class_names, r['scores'], angularWidth,
                                  distance)

        # Save 3D vector plots
        imagePath = rootDir_vec + file_name_orig + 'vector_' + "{:03d}".format(
            frameCount) + '.png'
        fig.savefig(imagePath)

        # Write the annotated image to a file
        imagePath = rootDir_col + file_name_orig + 'img_' + "{:03d}".format(
            frameCount) + '.png'
        cv2.imwrite(imagePath, frame)

        cv2.imshow('frame', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    capture.release()
    cv2.destroyAllWindows()
Exemplo n.º 13
0
    def __init__(self):
        """Initialize a MaskRCNNNode

        Parameters
        ----------

        Returns
        ----------
        - <obj>: MaskRCNNNode
            A Mask RCNN instantiation.

        """
        self._cv_bridge = CvBridge()
        self._class_names = rospy.get_param('~class_names', CLASS_NAMES)
        self._class_colors = visualize.random_colors(len(CLASS_NAMES))
        self._visualization = rospy.get_param('~visualization', True)

        #
        # network configuration
        #
        config = InferenceConfig()
        config.display()

        #
        # model in inference mode
        #
        self._model = modellib.MaskRCNN(mode="inference",
                                        model_dir="",
                                        config=config)

        #
        # mutual exclusive lock for handling image messages.
        #
        self._last_msg = None
        self._msg_lock = threading.Lock()

        #
        # publisher
        #
        self._detection_pub = rospy.Publisher('~detection',
                                              mask_rcnn_ros.msg.Detection,
                                              queue_size=1)
        self._vis_pub = rospy.Publisher('~visualization',
                                        sensor_msgs.msg.Image,
                                        queue_size=1)

        self._publish_rate = rospy.get_param('~publish_rate', 100)

        #
        # tensorflow graph
        #
        self._graph = tf.get_default_graph()

        #
        # Load weights trained on MS-COCO, download COCO trained weights from
        # releases if needed
        #
        model_path = rospy.get_param('~model_path', COCO_MODEL_PATH)
        if model_path == COCO_MODEL_PATH and not os.path.exists(
                COCO_MODEL_PATH):
            utils.download_trained_weights(COCO_MODEL_PATH)

        self._model.load_weights(model_path, by_name=True)
Exemplo n.º 14
0
    def get_all_mask_class_and_draw_minrect(self, r, image):
        num = r['masks'].shape[2]
        object = []

        _, ax = plt.subplots(1, figsize=(16, 16))
        shape = image.shape
        ax.set_ylim(shape[0] + 10, -10)
        ax.set_xlim(-10, shape[1] + 10)
        ax.axis('off')
        ax.set_title("hhhh")

        for i in range(num):  # create mask class for every instance
            obj = Mask(i, r['class_ids'][i],
                       self.dataset_val.class_names[r['class_ids'][i]],
                       r['masks'][:, :, i], r['rois'][i], r['scores'][i])
            obj.get_min_rect()
            object.append(obj)
            # cv2.drawContours(image, [object[i].min_box], 0, (0, 0, 255), 3)
            print(object[i].class_name)

        for i in range(num):
            # if (object[i].class_name is "lemon") | (object[i].class_name is "grape")| (object[i].class_name is "fig"):
            shoe = object[i]
            center_x = shoe.min_rect[0][0]
            center_y = shoe.min_rect[0][1]
            width = shoe.min_rect[1][0]
            height = shoe.min_rect[1][1]
            theta = shoe.min_rect[2]
            PI = math.pi
            the = (theta / 180) * PI
            # print("object", i,":width height theta:", width, height, theta)

            if theta == 0:
                y = center_y - 3 * height / 4
                x = center_x
                point = (x, y)
                w_h = (width / 2, width / 4)
            elif width > height:
                x = center_x + (5 * width * math.cos(the)) / 8
                y = center_y + (5 * width * math.sin(the)) / 8
                # x = center_x - (2 * width * math.cos(the)) / 4
                # y = center_y - (2 * width * math.sin(the)) / 4
                point = (x, y)
                w_h = (height / 4, height / 2)
            else:
                x = center_x + (5 * height * math.sin(the)) / 8
                y = center_y - (5 * height * math.cos(the)) / 8
                # x = center_x - (2 * height * math.sin(the)) / 4
                # y = center_y + (2 * height * math.cos(the)) / 4
                point = (x, y)
                w_h = (width / 2, width / 4)
            # print("object", i, "center center_cut:", shoe.min_rect[0], center_x, center_y, x, y)

            rect = (point, w_h, theta)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            cv2.drawContours(image, [box], 0, (255, 0, 0), 2)

        colors = random_colors(num)
        masked_image = image.astype(np.uint32).copy()
        captions = [
            "lemon 0.988", "lemon 1.000", "lemon 0.995", "lemon 0.984",
            "lemon 0.992"
        ]
        for i in range(num):
            # if (object[i].class_name is "lemon") | (object[i].class_name is "grape") | (object[i].class_name is "fig"):
            shoe = object[i]
            box = shoe.min_box
            width = shoe.min_rect[1][0]
            height = shoe.min_rect[1][1]
            theta = shoe.min_rect[2]
            score = shoe.scores
            label = shoe.class_name
            mask = shoe.mask

            p = patches.Rectangle(
                box[1],
                width,
                height,
                angle=theta,
                linewidth=2,  # add rectangle dash
                alpha=0.7,
                linestyle="dashed",
                edgecolor="blue",
                facecolor='none')
            ax.add_patch(p)
            caption = "{} {:.3f}".format(
                label, score) if score else label  # add label
            # caption = captions[i]
            print(type(caption), caption)
            ax.text(box[0][0],
                    box[0][1],
                    caption,
                    color='w',
                    size=8,
                    backgroundcolor="blue")

            masked_image = apply_mask(masked_image, mask, colors[i])

        ax.imshow(masked_image.astype(np.uint8))
        plt.show()
Exemplo n.º 15
0
def detectVideo(model, video_path=None, live=True):
    """ Detects instances in video, produces vector plots and saves to file
    
    Notes
    -----
    - Saves to local directory:
            Video with colour effect applied
            Images of vector plots
        
    - Requires matlab.engine to interface with camera model script for
      pixelToVector calculations.
    
    Parameters
    ----------
    model :  Tensorflow model
        Mask-RCNN model in inference mode.
        Generated in runNetwork().
        
    video_path : file/path/to/video
        Path to video upon which to do detection.
        User-defined.
    
    Returns
    -------
    None
    
    """

    # Video capture - live
    if live is True:
        print("Using webcam!")
        capture = cv2.VideoCapture(0)
        fps = 1

    # Video capture - video path
    else:
        capture = cv2.VideoCapture(video_path)
        fps = capture.get(cv2.CAP_PROP_FPS)

    # Get width and height
    width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # Open 3d plot with origin at [0,0,0]
    fig = plt.figure(figsize=(15, 15 / 3))
    ax = fig.add_subplot(121, projection='3d')
    ax.cla()
    ax.set_xlim(-1, 1)
    ax.set_ylim(-1, 1)
    ax.set_zlim(0, 1)
    ax.set_title('Optimised pixelToVector function')
    ax.set_xlabel("x", fontsize=16)
    ax.set_ylabel("y", fontsize=16)
    ax.set_zlabel("z", fontsize=16)
    ax.view_init(elev=45, azim=45)

    ax2 = fig.add_subplot(122, projection='3d')
    ax2.cla()
    ax2.set_xlim(-1, 1)
    ax2.set_ylim(-1, 1)
    ax2.set_zlim(0, 1)
    ax2.set_title('Non-optimised pixelToVector function')
    ax2.set_xlabel("x", fontsize=16)
    ax2.set_ylabel("y", fontsize=16)
    ax2.set_zlabel("z", fontsize=16)
    ax2.view_init(elev=45, azim=45)
    plt.tight_layout()
    plt.show()

    # Generate filenames and create directories
    file_name_orig = "colourised_{:%Y%m%dT%H%M%S}".format(
        datetime.datetime.now())
    rootDir = r'C:/Users/Chloe/Desktop/MCHA3900/Machine Vision/' + file_name_orig + r'/'
    rootDir_orig = rootDir + r'orig/'
    rootDir_vec = rootDir + r'vec/'
    rootDir_col = rootDir + r'col/'
    os.mkdir(rootDir)
    os.mkdir(rootDir_orig)
    os.mkdir(rootDir_vec)
    os.mkdir(rootDir_col)

    # Define codec and create video writer
    file_name = file_name_orig + ".avi"
    vwriter = cv2.VideoWriter(rootDir + file_name,
                              cv2.VideoWriter_fourcc(*'MJPG'), fps,
                              (width, height))

    lines = []
    lines2 = []
    frameCount = -1
    origin = [0, 0, 0]
    validFlag = True
    height = 200
    angularWidth = 0
    distance = 0

    while validFlag:
        # Increment frame counter
        frameCount += 1
        print("Frame #", frameCount)

        # Read next image
        validFlag, image = capture.read()

        if validFlag:

            # OpenCV returns images as BGR, convert to RGB
            image = image[..., ::-1]

            # Detect objects
            r = model.detect([image], verbose=0)[0]

            # Get points of interest
            tL, bL, tR, bT, centre = getPoints(r['rois'])

            # Do plots if any objects have been detected
            if (r['rois'].shape[0] > 0):

                # Clear previous lines and reset format
                ax.cla()
                ax.set_xlim(-1, 1)
                ax.set_ylim(-1, 1)
                ax.set_zlim(0, 1)
                ax.set_title('Optimised pixelToVector function')
                ax.set_xlabel("x", fontsize=16)
                ax.set_ylabel("y", fontsize=16)
                ax.set_zlabel("z", fontsize=16)
                ax.view_init(elev=45, azim=45)

                ax2.cla()
                ax2.set_xlim(-1, 1)
                ax2.set_ylim(-1, 1)
                ax2.set_zlim(0, 1)
                ax2.set_title('Non-optimised pixelToVector function')
                ax2.set_xlabel("x", fontsize=16)
                ax2.set_ylabel("y", fontsize=16)
                ax2.set_zlabel("z", fontsize=16)
                ax2.view_init(elev=45, azim=45)

                angularWidth = []
                distance = []

                # Plot vector from origin to centre of each object
                for i in range(r['rois'].shape[0]):

                    #duckieDistance = pixel2mm*(rad[i])/duckieRadius
                    #duckieLocation = [centre[i][1], centre[i][0], 1]
                    #duckieVector = duckieLocation

                    # Do pixeltovector function using upper left and bottom left
                    u_uLeft = float(tL[i][0])
                    v_uLeft = float(tL[i][1])
                    u_bLeft = float(bL[i][0])
                    v_bLeft = float(bL[i][1])

                    l_Vec = eng.pixeltovector(float(u_uLeft), float(v_uLeft))
                    r_Vec = eng.pixeltovector(float(u_bLeft), float(v_bLeft))

                    l_Vec = [l_Vec[0][3], l_Vec[0][4], l_Vec[0][5]]
                    r_Vec = [r_Vec[0][3], r_Vec[0][4], r_Vec[0][5]]

                    # Diameter, not radius
                    angularWidth.append(vectorAngle(l_Vec, r_Vec))

                    # Estimating distance
                    # (probably doing this wrong, too sleepy to think)
                    distance.append(height / np.tan(angularWidth[i]))

                    # Do pixeltovector function using cansentre points
                    # Run from MATLAB
                    u_centre = float(centre[i][0])
                    v_centre = float(centre[i][1])
                    res = eng.pixeltovector(float(u_centre), float(v_centre))
                    noptVect = [res[0][0], res[0][1], res[0][2]]
                    optVect = [res[0][3], res[0][4], res[0][5]]

                    # Plot optimised vector
                    duckieVector = optVect
                    xs = asarray([origin[0], abs(duckieVector[0])])
                    ys = asarray([origin[1], abs(duckieVector[1])])
                    zs = asarray([origin[2], duckieVector[2]])
                    colors = random_colors(r['rois'].shape[0])
                    lines.append(
                        ax.plot(xs,
                                ys,
                                zs,
                                color=colors[i],
                                marker=r'$\bigotimes$',
                                markersize=22))

                    # Plot non-optimised vector
                    duckieVector = noptVect
                    xs = asarray([origin[0], abs(duckieVector[0])])
                    ys = asarray([origin[1], abs(duckieVector[1])])
                    zs = asarray([origin[2], duckieVector[2]])
                    plt.tight_layout()
                    colors = random_colors(r['rois'].shape[0])
                    lines2.append(
                        ax2.plot(xs,
                                 ys,
                                 zs,
                                 color=colors[i],
                                 marker=r'$\bigotimes$',
                                 markersize=22))
                    plt.tight_layout()
                    plt.pause(0.1)

            # Colourise detected regions
            # detectFlag, image = colourRegion(image, r['masks'])
            image = display_cv_instances(image, r['rois'], r['masks'],
                                         r['class_ids'], ['BG', 'duckie'],
                                         r['scores'], angularWidth, distance)

            # RGB -> BGR to save image to video
            image = image[..., ::-1]

            # Write the annotated image to a file
            imagePath = rootDir_col + file_name_orig + 'img_' + "{:03d}".format(
                frameCount) + '.png'
            #cv2.imwrite(imagePath,image)

            # Add annotated image to video writer
            if live is False:
                vwriter.write(image)

            # Save 3D vector plots
            imagePath = rootDir_vec + file_name_orig + 'vector_' + "{:03d}".format(
                frameCount) + '.png'
            fig.savefig(imagePath)

        # Show webcam, press x to exit
        cv2.imshow('image', image.astype(np.int32))
        if cv2.waitKey(1) & 0xFF == ord('x'):
            break

    # Release video writer
    capture.release()
    vwriter.release()
    cv2.destroyAllWindows()