示例#1
0
def _detect(setting: Dict[Any, Any], image) -> List[Dict[Any, Any]]:
    start = datetime.datetime.now()
    # Generate output tensor targets for filtered bounding boxes.
    # TODO: Wrap these backend operations with Keras layers.
    yolo_outputs = yolo_head(setting['yolo_model'].output, setting['anchors'],
                             len(setting['class_names']))
    input_image_shape = kback.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(yolo_outputs,
                                       input_image_shape,
                                       score_threshold=args.score_threshold,
                                       iou_threshold=args.iou_threshold)
    print('spent time(yolo_eval)', datetime.datetime.now() - start)

    if setting[
            'is_fixed_size']:  # TODO: When resizing we can use minibatch input.
        resized_image = image.resize(
            tuple(reversed(setting['model_image_size'])), Image.BICUBIC)
        image_data = np.array(resized_image, dtype='float32')
    else:
        # Due to skip connection + max pooling in YOLO_v2, inputs must have
        # width and height as multiples of 32.
        new_image_size = (image.width - (image.width % 32),
                          image.height - (image.height % 32))
        resized_image = image.resize(new_image_size, Image.BICUBIC)
        image_data = np.array(resized_image, dtype='float32')
        print(image_data.shape)

    image_data /= 255.
    image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

    print('spent time(before run)', datetime.datetime.now() - start)
    out_boxes, out_scores, out_classes = setting['sess'].run(
        [boxes, scores, classes],
        feed_dict={
            setting['yolo_model'].input: image_data,
            input_image_shape: [image.size[1], image.size[0]],
            kback.learning_phase(): 0
        })
    print('spent time(after run)', datetime.datetime.now() - start)

    detected_items = []
    for i, c in reversed(list(enumerate(out_classes))):
        predicted_class = setting['class_names'][c]
        box = out_boxes[i]
        score = out_scores[i]
        detected_items.append({
            'class': predicted_class,
            'box': box.tolist(),
            'score': score.tolist(),
        })
    print('detected_items', detected_items)
    print('spent time(_detect)', datetime.datetime.now() - start)
    return detected_items
示例#2
0
def YOLO_predict(img, batch_img, sess, model, anchors, n_classes):
    yolo_outputs = yolo_head(model.output, anchors, n_classes)
    input_image_shape = K.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(yolo_outputs, input_image_shape)
    out_boxes, out_scores, out_classes = sess.run(
        [boxes, scores, classes],
        feed_dict={
            model.input: batch_img,
            input_image_shape: [img.shape[0], img.shape[1]],
            K.learning_phase(): 0
        })
    return out_boxes, out_scores, out_classes
示例#3
0
def draw(model_body, class_names, anchors, image_data, image_set='val',
            weights_name='trained_stage_3_best.h5', out_path="output_images", save_all=True):
   
    if image_set == 'train':
        image_data = np.array([np.expand_dims(image, axis=0)
            for image in image_data[:int(len(image_data)*.9)]])
    elif image_set == 'val':
        image_data = np.array([np.expand_dims(image, axis=0)
            for image in image_data[int(len(image_data)*.9):]])
    elif image_set == 'all':
        image_data = np.array([np.expand_dims(image, axis=0)
            for image in image_data])
    else:
        ValueError("draw argument image_set must be 'train', 'val', or 'all'")
    # model.load_weights(weights_name)
    print(image_data.shape)
    model_body.load_weights(weights_name)

    # Create output variables for prediction.
    yolo_outputs = yolo_head(model_body.output, anchors, len(class_names))
    input_image_shape = K.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(
        yolo_outputs, input_image_shape, score_threshold=0.07, iou_threshold=0.0)

    # Run prediction on overfit image.
    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.

    if  not os.path.exists(out_path):
        os.makedirs(out_path)
    for i in range(len(image_data)):
        out_boxes, out_scores, out_classes = sess.run(
            [boxes, scores, classes],
            feed_dict={
                model_body.input: image_data[i],
                input_image_shape: [image_data.shape[2], image_data.shape[3]],
                K.learning_phase(): 0
            })
        print('Found {} boxes for image.'.format(len(out_boxes)))
        print("Boxes:",out_boxes)
        

        # Plot image with predicted boxes.
        image_with_boxes = draw_boxes_(image_data[i][0], out_boxes, out_classes,
                                    class_names, out_scores)
        print("--------------------------------------------")
        # Save the image:
        if save_all or (len(out_boxes) > 0):
             image = PIL.Image.fromarray(image_with_boxes)
             image.save(os.path.join(out_path,str(i)+'.png'))
示例#4
0
    print("classes[2] = " + str(classes[2].eval()))
    print("scores.shape = " + str(scores.eval().shape))
    print("boxes.shape = " + str(boxes.eval().shape))
    print("classes.shape = " + str(classes.eval().shape))

sess = K.get_session()

class_names = read_classes("datasets/coco_classes.txt")
anchors = read_anchors("datasets/yolo_anchors.txt")
image_shape = (720., 1280.)

yolo_model = load_model("datasets/yolo.h5")

yolo_model.summary()

yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))

scores, boxes, classes = yolo_eval(yolo_outputs, image_shape)


def predict(sess, image_file):
    """
    Runs the graph stored in "sess" to predict boxes for "image_file". Prints and plots the preditions.

    Arguments:
    sess -- your tensorflow/Keras session containing the YOLO graph
    image_file -- name of an image stored in the "images" folder.

    Returns:
    out_scores -- tensor of shape (None, ), scores of the predicted boxes
    out_boxes -- tensor of shape (None, 4), coordinates of the predicted boxes
示例#5
0
def _main(args,
          frames_paths,
          crops_bboxes,
          crop_value,
          resize_frames=None,
          verbose=1,
          person_only=True,
          allowed_number_of_boxes=100):
    '''

    :param args: yolo model args like in YAD2K
    :param frames_paths: list of paths to frame images
    :param crops_bboxes: list of lists - crops per frames
    :param verbose:
    :param person_only:
    :return:
    '''

    print("frames_paths", len(frames_paths), frames_paths)
    print("crops_bboxes", len(crops_bboxes), crops_bboxes)

    model_path = os.path.expanduser(args["model_path"])
    print(model_path)
    assert model_path.endswith('.h5'), 'Keras model must be a .h5 file.'
    anchors_path = os.path.expanduser(args["anchors_path"])
    classes_path = os.path.expanduser(args["classes_path"])

    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.

    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]

    with open(anchors_path) as f:
        anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        anchors = np.array(anchors).reshape(-1, 2)

    yolo_model = load_model(model_path)

    # Verify model, anchors, and classes are compatible
    num_classes = len(class_names)
    num_anchors = len(anchors)
    # TODO: Assumes dim ordering is channel last
    # model_output_channels = yolo_model.layers[-1].output_shape[-1]
    # assert model_output_channels == num_anchors * (num_classes + 5), \
    #     'Mismatch between model and given anchor and class sizes. ' \
    #     'Specify matching anchors and classes with --anchors_path and ' \
    #     '--classes_path flags.'
    if verbose > 0:
        print('{} model, anchors, and classes loaded.'.format(model_path))

    # Check if model is fully convolutional, assuming channel last order.
    model_image_size = yolo_model.layers[0].input_shape[1:3]
    is_fixed_size = model_image_size != (None, None)

    # Generate colors for drawing bounding boxes.
    hsv_tuples = [(x / len(class_names), 1., 1.)
                  for x in range(len(class_names))]
    colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    colors = list(
        map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
            colors))
    random.seed(10101)  # Fixed seed for consistent colors across runs.
    random.shuffle(colors)  # Shuffle colors to decorrelate adjacent classes.
    random.seed(None)  # Reset seed to default.

    # Generate output tensor targets for filtered bounding boxes.
    # TODO: Wrap these backend operations with Keras layers.
    ### old
    # yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))###差异
    # input_image_shape = K.placeholder(shape=(2, ))
    ###
    if ("v2" in model_path):
        from YAD2K.yad2k.models.keras_yolo import yolo_eval, yolo_head  ###两个yoloV2
        yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))
    elif ("v3" in model_path):
        from kyolov3.ky.yolo3.model import yolo_head, yolo_eval
        yolo_outputs = yolo_model.output
    else:
        from kyolov3.ky.yolo3.model import yolo_head, yolo_eval
        yolo_outputs = yolo_model.output
    ### 看看会不会错 yolo_model.output == feat == yolo_outputs[l]
    input_image_shape = K.placeholder(shape=(2, ))

    ####### EVALUATION

    boxes, scores, classes = yolo_eval(yolo_outputs,
                                       anchors,
                                       num_classes,
                                       input_image_shape,
                                       score_threshold=args["score_threshold"],
                                       iou_threshold=args["iou_threshold"],
                                       max_boxes=allowed_number_of_boxes)

    pureEval_times = []
    ioPlusEval_times = []
    bboxes = []

    images_processed = 0
    evaluation_time = 0

    ### PROCESS FILES
    for frame_i in range(0, len(frames_paths)):
        start_loop = timer()

        images_processed += 1

        frame_path = frames_paths[frame_i]
        frame = Image.open(frame_path)

        if resize_frames is not None:
            resize_to = resize_frames[frame_i]

            ow, oh = frame.size

            nw = ow * resize_to
            nh = oh * resize_to

            frame = frame.resize((int(nw), int(nh)), Image.ANTIALIAS)

        crops_in_frame = crops_bboxes[frame_i]
        #print("Frame", frame_i, " with ", len(crops_in_frame), " crops.")
        sys.stdout.write("\rFrame " + str(frame_i) + " with " +
                         str(len(crops_in_frame)) + " crops.")
        sys.stdout.flush()

        for crop_i in range(0, len(crops_in_frame)):
            crop = crops_in_frame[crop_i]
            area = crop[1]

            #area = (int(w_crop[0]), int(h_crop[0]), int(w_crop[0] + scale * crop), int(h_crop[0] + scale * crop))
            cropped_img = frame.crop(box=area)
            cropped_img = cropped_img.resize(
                (int(crop_value), int(crop_value)), resample=Image.ANTIALIAS)
            cropped_img.load()
            """
            print("////////////////////////////////////////////////")
            print("area",area)
            print("crop_value",crop_value)
            print("cropped_img", cropped_img.size)
            cropped_img.show()
            print("////////////////////////////////////////////////")
            """

            image = cropped_img
            """
            image_data = np.array(image, dtype='float32')
            """
            if is_fixed_size:  # TODO: When resizing we can use minibatch input.
                resized_image = image.resize(tuple(reversed(model_image_size)),
                                             Image.BICUBIC)
                image_data = np.array(resized_image, dtype='float32')
            else:
                # Due to skip connection + max pooling in YOLO_v2, inputs must have
                # width and height as multiples of 32.
                new_image_size = (image.width - (image.width % 32),
                                  image.height - (image.height % 32))
                resized_image = image.resize(new_image_size, Image.BICUBIC)
                image_data = np.array(resized_image, dtype='float32')
                print(image_data.shape)

            image_data /= 255.
            image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

            if images_processed < 2:
                print("# image size: ", image_data.shape, image.size)

            ################# START #################
            start_eval = timer()
            out_boxes, out_scores, out_classes = sess.run(
                [boxes, scores, classes],
                feed_dict={
                    yolo_model.input: image_data,
                    input_image_shape: [image.size[1], image.size[0]],
                    K.learning_phase(): 0
                })
            end_eval = timer()
            ################# END #################
            evaluation_time = (end_eval - start_eval)
            pureEval_times.append(evaluation_time)
            people = 0
            bboxes_image = []
            #print(num_frames, num_crops)
            for i, c in reversed(list(enumerate(out_classes))):

                predicted_class = class_names[c]

                if predicted_class == 'person':
                    people += 1
                if person_only and (predicted_class != 'person'):
                    continue

                box = out_boxes[i]
                score = out_scores[i]

                #print(predicted_class, box, score)

                bboxes_image.append([predicted_class, box, score, c])

            if verbose > 0:
                num = len(out_boxes)
                if person_only:
                    num = people
                print('Found {} boxes in crop {} of frame {} in {}s'.format(
                    num, crop_i, frame_i, evaluation_time))

            bboxes.append(bboxes_image)

        end_loop = timer()
        loop_time = (end_loop - start_loop)
        ioPlusEval_times.append(loop_time - evaluation_time)

    #sess.close()

    return bboxes
示例#6
0
def run_nn(hWnd):
    global loaded

    model_path = os.path.expanduser('YAD2K/model_data/yolo.h5')
    anchors_path = os.path.expanduser('YAD2K/model_data/yolo_anchors.txt')
    classes_path = os.path.expanduser('YAD2K/model_data/league_classes.txt')

    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.

    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]

    with open(anchors_path) as f:
        anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        anchors = np.array(anchors).reshape(-1, 2)

    yolo_model, _ = create_model(anchors, class_names)
    yolo_model.load_weights('trained_stage_3_best.h5')

    # Verify model, anchors, and classes are compatible
    num_classes = len(class_names)
    num_anchors = len(anchors)
    # TODO: Assumes dim ordering is channel last
    model_output_channels = yolo_model.layers[-1].output_shape[-1]
    assert model_output_channels == num_anchors * (
        num_classes +
        5), 'Mismatch between model and given anchor and class sizes. '
    print('{} model, anchors, and classes loaded.'.format(model_path))

    # Check if model is fully convolutional, assuming channel last order.
    model_image_size = yolo_model.layers[0].input_shape[1:3]
    is_fixed_size = model_image_size != (None, None)

    # Generate colors for drawing bounding boxes.
    hsv_tuples = [(x / len(class_names), 1., 1.)
                  for x in range(len(class_names))]
    colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    colors = list(
        map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
            colors))
    random.seed(10101)  # Fixed seed for consistent colors across runs.
    random.shuffle(colors)  # Shuffle colors to decorrelate adjacent classes.
    random.seed(None)  # Reset seed to default.

    # Generate output tensor targets for filtered bounding boxes.
    # TODO: Wrap these backend operations with Keras layers.
    yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))
    input_image_shape = K.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(yolo_outputs,
                                       input_image_shape,
                                       score_threshold=args.score_threshold,
                                       iou_threshold=args.iou_threshold)

    # Save the output into a compact JSON file.
    outfile = open('output/game_data.json', 'w')
    # This will be appended with an object for every frame.
    data_to_write = []

    loaded = True
    win32gui.RedrawWindow(hWnd, None, None,
                          win32con.RDW_INVALIDATE | win32con.RDW_ERASE)

    with mss.mss() as sct:
        monitor = {'top': 0, 'left': 0, 'width': 1920, 'height': 1080}
        while 'Screen capturing':
            last_time = time.time()

            # Get raw pixels from the screen, save it to a Numpy array
            img = np.array(sct.grab(monitor))
            img = Image.fromarray(img)
            img.load()
            background = Image.new("RGB", img.size, (255, 255, 255))
            background.paste(img, mask=img.split()[3])

            test_yolo(background, is_fixed_size, model_image_size, sess, boxes,
                      scores, classes, yolo_model, input_image_shape,
                      class_names, colors)
            win32gui.RedrawWindow(hWnd, None, None,
                                  win32con.RDW_INVALIDATE | win32con.RDW_ERASE)
            # img = test_yolo(background)
            # basewidth = 700
            # wpercent = (basewidth/float(img.size[0]))
            # hsize = int((float(img.size[1])*float(wpercent)))
            # img = img.resize((basewidth,hsize), Image.ANTIALIAS)
            # img = np.array(img)
            # # Display the picture
            # cv2.imshow('OpenCV/Numpy normal', img)
            # Press "q" to quit
            if cv2.waitKey(25) & 0xFF == ord(';'):
                cv2.destroyAllWindows()
                break

    sess.close()
    return
示例#7
0
def _main(args):
    voc_path = os.path.expanduser(args.data_path)
    classes_path = os.path.expanduser(args.classes_path)
    anchors_path = os.path.expanduser(args.anchors_path)

    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]

    if os.path.isfile(anchors_path):
        with open(anchors_path) as f:
            anchors = f.readline()
            anchors = [float(x) for x in anchors.split(',')]
            anchors = np.array(anchors).reshape(-1, 2)
    else:
        anchors = YOLO_ANCHORS

    voc = h5py.File(voc_path, 'r')
    image = PIL.Image.open(io.BytesIO(voc['train/images'][28]))
    orig_size = np.array([image.width, image.height])
    orig_size = np.expand_dims(orig_size, axis=0)

    # Image preprocessing.
    image = image.resize((416, 416), PIL.Image.BICUBIC)
    image_data = np.array(image, dtype=np.float)
    image_data /= 255.

    # Box preprocessing.
    # Original boxes stored as 1D list of class, x_min, y_min, x_max, y_max.
    boxes = voc['train/boxes'][28]
    boxes = boxes.reshape((-1, 5))
    # Get extents as y_min, x_min, y_max, x_max, class for comparision with
    # model output.
    boxes_extents = boxes[:, [2, 1, 4, 3, 0]]

    # Get box parameters as x_center, y_center, box_width, box_height, class.
    boxes_xy = 0.5 * (boxes[:, 3:5] + boxes[:, 1:3])
    boxes_wh = boxes[:, 3:5] - boxes[:, 1:3]
    boxes_xy = boxes_xy / orig_size
    boxes_wh = boxes_wh / orig_size
    boxes = np.concatenate((boxes_xy, boxes_wh, boxes[:, 0:1]), axis=1)

    # Precompute detectors_mask and matching_true_boxes for training.
    # Detectors mask is 1 for each spatial position in the final conv layer and
    # anchor that should be active for the given boxes and 0 otherwise.
    # Matching true boxes gives the regression targets for the ground truth box
    # that caused a detector to be active or 0 otherwise.
    detectors_mask_shape = (13, 13, 5, 1)
    matching_boxes_shape = (13, 13, 5, 5)
    detectors_mask, matching_true_boxes = preprocess_true_boxes(
        boxes, anchors, [416, 416])

    # Create model input layers.
    image_input = Input(shape=(416, 416, 3))
    boxes_input = Input(shape=(None, 5))
    detectors_mask_input = Input(shape=detectors_mask_shape)
    matching_boxes_input = Input(shape=matching_boxes_shape)

    print('Boxes:')
    print(boxes)
    print('Box corners:')
    print(boxes_extents)
    print('Active detectors:')
    print(np.where(detectors_mask == 1)[:-1])
    print('Matching boxes for active detectors:')
    print(matching_true_boxes[np.where(detectors_mask == 1)[:-1]])

    # Create model body.
    model_body = yolo_body(image_input, len(anchors), len(class_names))
    model_body = Model(image_input, model_body.output)
    # Place model loss on CPU to reduce GPU memory usage.
    with tf.device('/cpu:0'):
        # TODO: Replace Lambda with custom Keras layer for loss.
        model_loss = Lambda(yolo_loss,
                            output_shape=(1, ),
                            name='yolo_loss',
                            arguments={
                                'anchors': anchors,
                                'num_classes': len(class_names)
                            })([
                                model_body.output, boxes_input,
                                detectors_mask_input, matching_boxes_input
                            ])
    model = Model(
        [image_input, boxes_input, detectors_mask_input, matching_boxes_input],
        model_loss)
    model.compile(
        optimizer='adam', loss={
            'yolo_loss': lambda y_true, y_pred: y_pred
        })  # This is a hack to use the custom loss function in the last layer.

    # Add batch dimension for training.
    image_data = np.expand_dims(image_data, axis=0)
    boxes = np.expand_dims(boxes, axis=0)
    detectors_mask = np.expand_dims(detectors_mask, axis=0)
    matching_true_boxes = np.expand_dims(matching_true_boxes, axis=0)

    num_steps = 1000
    # TODO: For full training, put preprocessing inside training loop.
    # for i in range(num_steps):
    #     loss = model.train_on_batch(
    #         [image_data, boxes, detectors_mask, matching_true_boxes],
    #         np.zeros(len(image_data)))
    model.fit([image_data, boxes, detectors_mask, matching_true_boxes],
              np.zeros(len(image_data)),
              batch_size=1,
              epochs=num_steps)
    model.save_weights('overfit_weights.h5')

    # Create output variables for prediction.
    yolo_outputs = yolo_head(model_body.output, anchors, len(class_names))
    input_image_shape = K.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(yolo_outputs,
                                       input_image_shape,
                                       score_threshold=.3,
                                       iou_threshold=.9)

    # Run prediction on overfit image.
    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.
    out_boxes, out_scores, out_classes = sess.run(
        [boxes, scores, classes],
        feed_dict={
            model_body.input: image_data,
            input_image_shape: [image.size[1], image.size[0]],
            K.learning_phase(): 0
        })
    print('Found {} boxes for image.'.format(len(out_boxes)))
    print(out_boxes)

    # Plot image with predicted boxes.
    image_with_boxes = draw_boxes(image_data[0], out_boxes, out_classes,
                                  class_names, out_scores)
    plt.imshow(image_with_boxes, interpolation='nearest')
    plt.show()
示例#8
0
def _main(args):
    model_path = os.path.expanduser(args.model_path)
    assert model_path.endswith('.h5'), 'Keras model must be a .h5 file.'
    anchors_path = os.path.expanduser(args.anchors_path)
    classes_path = os.path.expanduser(args.classes_path)
    test_path = os.path.expanduser(args.test_path)
    output_path = os.path.expanduser(args.output_path)

    if not os.path.exists(output_path):
        print('Creating output path {}'.format(output_path))
        os.mkdir(output_path)

    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.

    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]

    with open(anchors_path) as f:
        anchors = f.readline()
        anchors = [float(x) for x in anchors.split(',')]
        anchors = np.array(anchors).reshape(-1, 2)

    yolo_model = load_model(model_path)

    # Verify model, anchors, and classes are compatible
    num_classes = len(class_names)
    num_anchors = len(anchors)
    # TODO: Assumes dim ordering is channel last
    model_output_channels = yolo_model.layers[-1].output_shape[-1]
    assert model_output_channels == num_anchors * (num_classes + 5), \
        'Mismatch between model and given anchor and class sizes. ' \
        'Specify matching anchors and classes with --anchors_path and ' \
        '--classes_path flags.'
    print('{} model, anchors, and classes loaded.'.format(model_path))

    # Check if model is fully convolutional, assuming channel last order.
    model_image_size = yolo_model.layers[0].input_shape[1:3]
    is_fixed_size = model_image_size != (None, None)

    # Generate colors for drawing bounding boxes.
    hsv_tuples = [(x / len(class_names), 1., 1.)
                  for x in range(len(class_names))]
    colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    colors = list(
        map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
            colors))
    random.seed(10101)  # Fixed seed for consistent colors across runs.
    random.shuffle(colors)  # Shuffle colors to decorrelate adjacent classes.
    random.seed(None)  # Reset seed to default.

    # Generate output tensor targets for filtered bounding boxes.
    # TODO: Wrap these backend operations with Keras layers.
    yolo_outputs = yolo_head(yolo_model.output, anchors, len(class_names))
    input_image_shape = K.placeholder(shape=(2, ))
    boxes, scores, classes = yolo_eval(yolo_outputs,
                                       input_image_shape,
                                       score_threshold=args.score_threshold,
                                       iou_threshold=args.iou_threshold)

    for image_file in os.listdir(test_path):
        try:
            image_type = imghdr.what(os.path.join(test_path, image_file))
            if not image_type:
                continue
        except IsADirectoryError:
            continue

        image = Image.open(os.path.join(test_path, image_file))
        if is_fixed_size:  # TODO: When resizing we can use minibatch input.
            resized_image = image.resize(tuple(reversed(model_image_size)),
                                         Image.BICUBIC)
            image_data = np.array(resized_image, dtype='float32')
        else:
            # Due to skip connection + max pooling in YOLO_v2, inputs must have
            # width and height as multiples of 32.
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            resized_image = image.resize(new_image_size, Image.BICUBIC)
            image_data = np.array(resized_image, dtype='float32')
            print(image_data.shape)

        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

        out_boxes, out_scores, out_classes = sess.run(
            [boxes, scores, classes],
            feed_dict={
                yolo_model.input: image_data,
                input_image_shape: [image.size[1], image.size[0]],
                K.learning_phase(): 0
            })
        print('Found {} boxes for {}'.format(len(out_boxes), image_file))

        font = ImageFont.truetype(
            font=
            'E:\\virtualdestop\AttentionPipeline-master\\video_parser_v1\YAD2K\\font\FiraMono-Medium.otf',
            size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)

            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle([left + i, top + i, right - i, bottom - i],
                               outline=colors[c])
            draw.rectangle(
                [tuple(text_origin),
                 tuple(text_origin + label_size)],
                fill=colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        image.save(os.path.join(output_path, image_file), quality=90)
    sess.close()