Switch to side-by-side view

--- a
+++ b/darkflow/net/yolo/predict.py
@@ -0,0 +1,131 @@
+from ...utils.im_transform import imcv2_recolor, imcv2_affine_trans
+from ...utils.box import BoundBox, box_iou, prob_compare
+import numpy as np
+import cv2
+import os
+import json
+from ...cython_utils.cy_yolo_findboxes import yolo_box_constructor
+
+
+def _fix(obj, dims, scale, offs):
+    for i in range(1, 5):
+        dim = dims[(i + 1) % 2]
+        off = offs[(i + 1) % 2]
+        obj[i] = int(obj[i] * scale - off)
+        obj[i] = max(min(obj[i], dim), 0)
+
+
+def resize_input(self, im):
+    h, w, c = self.meta['inp_size']
+    imsz = cv2.resize(im, (w, h))
+    imsz = imsz / 255.
+    imsz = imsz[:, :, ::-1]
+    return imsz
+
+
+def process_box(self, b, h, w, threshold):
+    max_indx = np.argmax(b.probs)
+    max_prob = b.probs[max_indx]
+    label = self.meta['labels'][max_indx]
+    if max_prob > threshold:
+        left = int((b.x - b.w / 2.) * w)
+        right = int((b.x + b.w / 2.) * w)
+        top = int((b.y - b.h / 2.) * h)
+        bot = int((b.y + b.h / 2.) * h)
+        if left < 0:  left = 0
+        if right > w - 1: right = w - 1
+        if top < 0:   top = 0
+        if bot > h - 1:   bot = h - 1
+        mess = '{}'.format(label)
+        return (left, right, top, bot, mess, max_indx, max_prob)
+    return None
+
+
+def findboxes(self, net_out):
+    meta, FLAGS = self.meta, self.FLAGS
+    threshold = FLAGS.threshold
+
+    boxes = []
+    boxes = yolo_box_constructor(meta, net_out, threshold)
+
+    return boxes
+
+
+def preprocess(self, im, allobj=None):
+    """
+    Takes an image, return it as a numpy tensor that is readily
+    to be fed into tfnet. If there is an accompanied annotation (allobj),
+    meaning this preprocessing is serving the train process, then this
+    image will be transformed with random noise to augment training data,
+    using scale, translation, flipping and recolor. The accompanied
+    parsed annotation (allobj) will also be modified accordingly.
+    """
+    if type(im) is not np.ndarray:
+        im = cv2.imread(im)
+
+    if allobj is not None:  # in training mode
+        result = imcv2_affine_trans(im)
+        im, dims, trans_param = result
+        scale, offs, flip = trans_param
+        for obj in allobj:
+            _fix(obj, dims, scale, offs)
+            if not flip: continue
+            obj_1_ = obj[1]
+            obj[1] = dims[0] - obj[3]
+            obj[3] = dims[0] - obj_1_
+        im = imcv2_recolor(im)
+
+    im = self.resize_input(im)
+    if allobj is None: return im
+    return im  # , np.array(im) # for unit testing
+
+
+def postprocess(self, net_out, im, save=True):
+    """
+    Takes net output, draw predictions, save to disk
+    """
+    meta, FLAGS = self.meta, self.FLAGS
+    threshold = FLAGS.threshold
+    colors, labels = meta['colors'], meta['labels']
+
+    boxes = self.findboxes(net_out)
+
+    if type(im) is not np.ndarray:
+        imgcv = cv2.imread(im)
+    else:
+        imgcv = im
+
+    h, w, _ = imgcv.shape
+    resultsForJSON = []
+    for b in boxes:
+        boxResults = self.process_box(b, h, w, threshold)
+        if boxResults is None:
+            continue
+        left, right, top, bot, mess, max_indx, confidence = boxResults
+        thick = int((h + w) // 300)
+        if self.FLAGS.json:
+            resultsForJSON.append(
+                {"label": mess, "confidence": float('%.2f' % confidence), "topleft": {"x": left, "y": top},
+                 "bottomright": {"x": right, "y": bot}})
+            continue
+
+        cv2.rectangle(imgcv,
+                      (left, top), (right, bot),
+                      self.meta['colors'][max_indx], thick)
+        cv2.putText(
+            imgcv, mess, (left, top - 12),
+            0, 1e-3 * h, self.meta['colors'][max_indx],
+               thick // 3)
+
+    if not save: return imgcv
+
+    outfolder = os.path.join(self.FLAGS.imgdir, 'out')
+    img_name = os.path.join(outfolder, os.path.basename(im))
+    if self.FLAGS.json:
+        textJSON = json.dumps(resultsForJSON)
+        textFile = os.path.splitext(img_name)[0] + ".json"
+        with open(textFile, 'w') as f:
+            f.write(textJSON)
+        return
+
+    cv2.imwrite(img_name, imgcv)