[45a3e1]: / darkflow / net / yolo / predict.py

Download this file

132 lines (108 with data), 4.1 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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)