def getProcessedBoxes(self, net_out): """ Takes net output, draw net_out, save to disk """ # meta meta = self.meta H, W, _ = meta['out_size'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] threshold = self.FLAGS.threshold max_iou = self.FLAGS.slice_max_iou net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] #print(bx.x, bx.y, bx.w, bx.h, bx.c) bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H classes = net_out[row, col, b, 5:] bx.probs = _softmax(classes) * bx.c bx.probs *= bx.probs > threshold boxes.append(bx) for c in range(C): for i in range(len(boxes)): max_indx = np.argmax(boxes[i].probs) boxes[i].class_num = max_indx # boxes = sorted(boxes, key = prob_compare) # for i in range(len(boxes)): # boxi = boxes[i] # if boxi.probs[c] == 0: continue # for j in range(i + 1, len(boxes)): # boxj = boxes[j] # if box_iou(boxi, boxj) >= max_iou: # boxes[j].probs[c] = 0. return boxes
def findboxes(self, net_out): meta, FLAGS = self.meta, self.FLAGS threshold, sqrt = FLAGS.threshold, meta['sqrt'] + 1 C, B, S = meta['classes'], meta['num'], meta['side'] boxes = [] SS = S * S # number of grid cells prob_size = SS * C # class probabilities conf_size = SS * B # confidences for each grid cell # net_out = net_out[0] probs = net_out[0:prob_size] confs = net_out[prob_size:(prob_size + conf_size)] cords = net_out[(prob_size + conf_size):] probs = probs.reshape([SS, C]) confs = confs.reshape([SS, B]) cords = cords.reshape([SS, B, 4]) for grid in range(SS): for b in range(B): bx = BoundBox(C) bx.c = confs[grid, b] bx.x = (cords[grid, b, 0] + grid % S) / S bx.y = (cords[grid, b, 1] + grid // S) / S bx.w = cords[grid, b, 2]**sqrt bx.h = cords[grid, b, 3]**sqrt p = probs[grid, :] * bx.c p *= (p > threshold) bx.probs = p boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key=prob_compare, reverse=True) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. return boxes
def findboxes(self, net_out): # meta meta = self.meta H, W, _ = meta['out_size'] threshold = meta['thresh'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H classes = net_out[row, col, b, 5:] bx.probs = _softmax(classes) * bx.c bx.probs *= bx.probs > threshold boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key=prob_compare, reverse=True) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. return boxes
def postprocess(self, net_out, im, save=True): """ Takes net output, draw net_out, save to disk """ # meta meta = self.meta H, W, _ = meta['out_size'] threshold = meta['thresh'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H p = net_out[row, col, b, 5:] * bx.c mi = np.argmax(p) if p[mi] < 1.5: continue bx.ind = mi bx.pi = p[mi] boxes.append(bx) # non max suppress boxes boxes = sorted(boxes, cmp=prob_compare2) for i in range(len(boxes)): boxi = boxes[i] if boxi.pi == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] areaj = boxj.w * boxj.h if box_intersection(boxi, boxj) / areaj >= .4: boxes[j].pi = 0. colors = meta['colors'] labels = meta['labels'] if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape for b in boxes: if b.pi > 0.: label = labels[b.ind] 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 thick = int((h + w) / 300) cv2.rectangle(imgcv, (left, top), (right, bot), colors[b.ind], thick) mess = '{}'.format(label) cv2.putText(imgcv, mess, (left, top - 12), 0, 1e-3 * h, colors[b.ind], thick / 5) if not save: return imgcv outfolder = os.path.join(self.FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) cv2.imwrite(img_name, imgcv)
def postprocess(self, net_out, im, save = True): """ Takes net output, draw net_out, save to disk """ # meta meta = self.meta H, W, _ = meta['out_size'] threshold = meta['thresh'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H classes = net_out[row, col, b, 5:] bx.probs = _softmax(classes) * bx.c bx.probs *= bx.probs > threshold boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key = prob_compare, reverse = True) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. colors = meta['colors'] labels = meta['labels'] if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape textBuff = "[" for b in boxes: max_indx = np.argmax(b.probs) max_prob = b.probs[max_indx] label = 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 thick = int((h+w)/300) mess = '{}'.format(label) if self.FLAGS.json: line = ('{"label":"%s",' '"topleft":{"x":%d,"y":%d},' '"bottomright":{"x":%d,"y":%d}},\n') % \ (mess, left, top, right, bot) textBuff += line continue cv2.rectangle(imgcv, (left, top), (right, bot), colors[max_indx], thick) cv2.putText(imgcv, mess, (left, top - 12), 0, 1e-3 * h, colors[max_indx],thick//3) # Removing trailing comma+newline adding json list terminator. textBuff = textBuff[:-2] + "]" outfolder = os.path.join(self.FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) if self.FLAGS.json: textFile = os.path.splitext(img_name)[0] + ".json" with open(textFile, 'w') as f: f.write(textBuff) return if not save: return imgcv cv2.imwrite(img_name, imgcv)
def postprocess(self, net_out, im, save=True): """ Takes net output, draw predictions, save to disk """ meta, FLAGS = self.meta, self.FLAGS threshold, sqrt = FLAGS.threshold, meta['sqrt'] + 1 C, B, S = meta['classes'], meta['num'], meta['side'] colors, labels = meta['colors'], meta['labels'] boxes = [] SS = S * S # number of grid cells prob_size = SS * C # class probabilities conf_size = SS * B # confidences for each grid cell #net_out = net_out[0] probs = net_out[0:prob_size] confs = net_out[prob_size:(prob_size + conf_size)] cords = net_out[(prob_size + conf_size):] probs = probs.reshape([SS, C]) confs = confs.reshape([SS, B]) cords = cords.reshape([SS, B, 4]) for grid in range(SS): for b in range(B): bx = BoundBox(C) bx.c = confs[grid, b] bx.x = (cords[grid, b, 0] + grid % S) / S bx.y = (cords[grid, b, 1] + grid // S) / S bx.w = cords[grid, b, 2]**sqrt bx.h = cords[grid, b, 3]**sqrt p = probs[grid, :] * bx.c p *= (p > threshold) bx.probs = p boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key=prob_compare, reverse=True) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape textBuff = "[" for b in boxes: 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 thick = int((h + w) // 300) mess = '{}'.format(label) if self.FLAGS.json: line = ('{"label":"%s",' '"topleft":{"x":%d,"y":%d},' '"bottomright":{"x":%d,"y":%d}},\n') % \ (mess, left, top, right, bot) textBuff += line 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) # Removing trailing comma+newline adding json list terminator. textBuff = textBuff[:-2] + "]" if self.FLAGS.json: textFile = os.path.splitext(img_name)[0] + ".json" with open(textFile, 'w') as f: f.write(textBuff) return if not save: return imgcv outfolder = os.path.join(self.FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) cv2.imwrite(img_name, imgcv)
def postprocess(self, net_out, im, save=True): """ Takes net output, draw net_out, save to disk """ # meta meta = self.meta H, W, _ = meta['out_size'] threshold = meta['thresh'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H classes = net_out[row, col, b, 5:] bx.probs = _softmax(classes) * bx.c bx.probs *= bx.probs > threshold boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key=prob_compare) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. colors = meta['colors'] labels = meta['labels'] if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape for b in boxes: max_indx = np.argmax(b.probs) max_prob = b.probs[max_indx] label = 'object' * int(C < 2) label += labels[max_indx] * int(C > 1) 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 thick = int((h + w) / 300) cv2.rectangle(imgcv, (left, top), (right, bot), colors[max_indx], thick) mess = '{}'.format(label) cv2.putText(imgcv, mess, (left, top - 12), 0, 1e-3 * h, colors[max_indx], thick // 3) if not save: return imgcv outfolder = os.path.join(self.FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) cv2.imwrite(img_name, imgcv) # def _postprocess(self, net_out, im, save = True): # """ # Takes net output, draw net_out, save to disk # """ # # meta # meta = self.meta # H, W, _ = meta['out_size'] # threshold = meta['thresh'] # C, B = meta['classes'], meta['num'] # anchors = meta['anchors'] # net_out = net_out.reshape([H, W, B, -1]) # boxes = list() # for row in range(H): # for col in range(W): # for b in range(B): # bx = BoundBox(C) # bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] # bx.c = expit(bx.c) # bx.x = (col + expit(bx.x)) / W # bx.y = (row + expit(bx.y)) / H # bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W # bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H # p = net_out[row, col, b, 5:] * bx.c # mi = np.argmax(p) # if p[mi] < threshold*2: continue # bx.ind = mi; bx.pi = p[mi] # boxes.append(bx) # # non max suppress boxes # boxes = sorted(boxes, cmp = prob_compare2) # for i in range(len(boxes)): # boxi = boxes[i] # if boxi.pi == 0: continue # for j in range(i + 1, len(boxes)): # boxj = boxes[j] # areaj = boxj.w * boxj.h # if box_intersection(boxi, boxj)/areaj >= .4: # boxes[j].pi = 0. # colors = meta['colors'] # labels = meta['labels'] # if type(im) is not np.ndarray: # imgcv = cv2.imread(im) # else: imgcv = im # h, w, _ = imgcv.shape # for b in boxes: # if b.pi > 0.: # label = labels[b.ind] # 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 # thick = int((h+w)/300) # cv2.rectangle(imgcv, # (left, top), (right, bot), # colors[b.ind], thick) # mess = '{}'.format(label) # cv2.putText(imgcv, mess, (left, top - 12), # 0, 1e-3 * h, colors[b.ind], thick // 3) # if not save: return imgcv # outfolder = os.path.join(self.FLAGS.test, 'out') # img_name = os.path.join(outfolder, im.split('/')[-1]) # cv2.imwrite(img_name, imgcv)
def postprocess(predictions, img_path, FLAGS, meta): """ Takes net output, draw predictions, save to results/ prediction is a numpy tensor - net's output img_path is the path to testing folder FLAGS contains threshold for predictions meta supplies labels and colors for drawing """ # meta threshold = FLAGS.threshold C, B, S = meta['classes'], meta['num'], meta['side'] colors, labels = meta['colors'], meta['labels'] boxes = [] SS = S * S # number of grid cells prob_size = SS * C # class probabilities conf_size = SS * B # confidences for each grid cell probs = predictions[0:prob_size] confs = predictions[prob_size:(prob_size + conf_size)] cords = predictions[(prob_size + conf_size):] probs = probs.reshape([SS, C]) confs = confs.reshape([SS, B]) cords = cords.reshape([SS, B, 4]) for grid in range(SS): for b in range(B): new_box = BoundBox(C) new_box.c = confs[grid, b] new_box.x = (cords[grid, b, 0] + grid % S) / S new_box.y = (cords[grid, b, 1] + grid // S) / S new_box.w = cords[grid, b, 2]**2 new_box.h = cords[grid, b, 3]**2 new_box.id = '{}-{}'.format(grid, b) for c in range(C): new_box.probs[c] = new_box.c * probs[grid, c] boxes.append(new_box) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, cmp=prob_compare) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] boxij = box_intersection(boxi, boxj) boxja = boxj.w * boxj.h apart = boxij / boxja if apart >= .5: if boxi.probs[c] > boxj.probs[c]: boxes[j].probs[c] = 0. else: boxes[i].probs[c] = 0. imgcv = cv2.imread(img_path) h, w, _ = imgcv.shape for b in boxes: max_indx = np.argmax(b.probs) max_prob = b.probs[max_indx] label = 'object' * int(C < 2) label += labels[max_indx] * int(C > 1) 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 thick = int((h + w) / 300) cv2.rectangle(imgcv, (left, top), (right, bot), colors[max_indx], thick) mess = '{}:{:.3f}'.format(label, max_prob) cv2.putText(imgcv, mess, (left, top - 12), 0, 1e-3 * h, colors[max_indx], thick / 5) outfolder = os.path.join(FLAGS.test, 'out') img_name = os.path.join(outfolder, img_path.split('/')[-1]) cv2.imwrite(img_name, imgcv)
def eval_list(boxes, self): actuals = udacity_voc_csv(self.FLAGS.valAnn, self.meta['labels']) names = list() for box in actuals: names.append(box[0]) imgName = list(OrderedDict.fromkeys(names)) conf_thresh = 0.25 nms_thresh = 0.4 iou_thresh = 0.5 min_box_scale = 8. / 448 total = 0.0 proposals = 0.0 correct = 0.0 lineId = 0 avg_iou = 0.0 groundBox = BoundBox(20) prdiction = BoundBox(20) for names in imgName: for boxgt in actuals: if (names[1:] == boxgt[0][1:]): total = total + 1 best_iou = 0 for box in boxes: if (box[0] == boxgt[0][1:] and box[1][2][0][0] == boxgt[1][2][0][0]): proposals = proposals + 1 box_gt = boxgt[1][2][0][1:5] boxp = box[1][2][0][1:5] groundBox.x = (box_gt[2] + box_gt[0]) / 2 groundBox.y = (box_gt[1] + box_gt[3]) / 2 groundBox.w = (box_gt[2] - box_gt[0]) groundBox.h = (box_gt[3] - box_gt[1]) prdiction.x = (boxp[2] + boxp[0]) / 2 prdiction.y = (boxp[1] + boxp[3]) / 2 prdiction.w = (boxp[2] - boxp[0]) prdiction.h = (boxp[3] - boxp[1]) iou = box_iou(groundBox, prdiction) best_iou = max(iou, best_iou) if best_iou > iou_thresh: avg_iou += best_iou correct = correct + 1 if (proposals == 0): precision = 0 else: precision = 1.0 * correct / proposals recall = 1.0 * correct / total if (correct == 0): fscore = 0 IOU = 0 else: fscore = 2.0 * precision * recall / (precision + recall) IOU = avg_iou / correct proposals = 0 total = 0 print( "Image no:", names[1:], "IOU: %f, Recal: %f, Precision: %f, Fscore: %f" % (IOU, recall, precision, fscore))
def postprocess(self, net_out, im, save=True): """ Takes net output, draw predictions, save to disk """ meta, FLAGS = self.meta, self.FLAGS threshold, sqrt = FLAGS.threshold, meta['sqrt'] + 1 C, B, S = meta['classes'], meta['num'], meta['side'] colors, labels = meta['colors'], meta['labels'] boxes = [] SS = S * S # number of grid cells prob_size = SS * C # class probabilities conf_size = SS * B # confidences for each grid cell #net_out = net_out[0] probs = net_out[0:prob_size] confs = net_out[prob_size:(prob_size + conf_size)] cords = net_out[(prob_size + conf_size):] probs = probs.reshape([SS, C]) confs = confs.reshape([SS, B]) cords = cords.reshape([SS, B, 4]) for grid in range(SS): for b in range(B): bx = BoundBox(C) bx.c = confs[grid, b] bx.x = (cords[grid, b, 0] + grid % S) / S bx.y = (cords[grid, b, 1] + grid // S) / S bx.w = cords[grid, b, 2]**sqrt bx.h = cords[grid, b, 3]**sqrt p = probs[grid, :] * bx.c p *= (p > threshold) bx.probs = p boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key=prob_compare) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape for b in boxes: max_indx = np.argmax(b.probs) max_prob = b.probs[max_indx] label = self.meta['labels'][max_indx] if max_prob > _thresh.get(label, 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 thick = int((h + w) // 150) cv2.rectangle(imgcv, (left, top), (right, bot), self.meta['colors'][max_indx], thick) mess = '{}'.format(label) 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(FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) cv2.imwrite(img_name, imgcv)
def postprocess(self, net_out, im, save = True, check= False): """ Takes net output, draw net_out, save to disk """ # meta meta = self.meta H, W, _ = meta['out_size'] threshold = meta['thresh'] C, B = meta['classes'], meta['num'] anchors = meta['anchors'] net_out = net_out.reshape([H, W, B, -1]) boxes = list() for row in range(H): for col in range(W): for b in range(B): bx = BoundBox(C) bx.x, bx.y, bx.w, bx.h, bx.c = net_out[row, col, b, :5] bx.c = expit(bx.c) bx.x = (col + expit(bx.x)) / W bx.y = (row + expit(bx.y)) / H bx.w = math.exp(bx.w) * anchors[2 * b + 0] / W bx.h = math.exp(bx.h) * anchors[2 * b + 1] / H classes = net_out[row, col, b, 5:] bx.probs = _softmax(classes) * bx.c bx.probs *= bx.probs > threshold boxes.append(bx) # non max suppress boxes for c in range(C): for i in range(len(boxes)): boxes[i].class_num = c boxes = sorted(boxes, key = prob_compare) for i in range(len(boxes)): boxi = boxes[i] if boxi.probs[c] == 0: continue for j in range(i + 1, len(boxes)): boxj = boxes[j] if box_iou(boxi, boxj) >= .4: boxes[j].probs[c] = 0. colors = meta['colors'] labels = meta['labels'] if type(im) is not np.ndarray: imgcv = cv2.imread(im) else: imgcv = im h, w, _ = imgcv.shape resultsForJSON = [] for b in boxes: max_indx = np.argmax(b.probs) max_prob = b.probs[max_indx] label = 'object' * int(C < 2) label += labels[max_indx] * int(C>1) 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 thick = int((h+w)/300) mess = '{}'.format(label) #print(("label", mess, "confidence", max_prob, "topleft ","x ", left, "y ", top, "bottomright", " x", right, "y", bot)) if self.FLAGS.json: resultsForJSON.append({"label": mess, "confidence": float('%.2f' % max_prob), "topleft": {"x": left, "y": top}, "bottomright": {"x": right, "y": bot}}) continue cv2.rectangle(imgcv, (left, top), (right, bot), colors[max_indx], thick) cv2.putText(imgcv, mess, (left, top - 12), 0, 1e-3 * h, colors[max_indx],thick//3) outfolder = os.path.join(self.FLAGS.test, 'out') img_name = os.path.join(outfolder, im.split('/')[-1]) if(check==False): 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 if not save: return imgcv cv2.imwrite(img_name, imgcv)