post_process.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import cv2
  2. from keras import backend as K
  3. import tensorflow as tf
  4. def yolo_eval(outputs,
  5. anchors,
  6. num_classes,
  7. max_boxes=20,
  8. score_threshold=.1,
  9. iou_threshold=.1):
  10. """Evaluate YOLO model on given input and return filtered boxes."""
  11. # num_layers = len(anchors) // 3
  12. # yolo_outputs = outputs[:num_layers]
  13. # image_shape = outputs[num_layers]
  14. yolo_outputs = outputs[0]
  15. print("yolo_outputs", yolo_outputs[0])
  16. num_layers = len(yolo_outputs)
  17. image_shape = outputs[1]
  18. print("num_layers", num_layers)
  19. print("image_shape", image_shape)
  20. anchor_mask = [[6, 7, 8], [3, 4, 5], [0, 1, 2]] if num_layers == 3 else [[3, 4, 5], [1, 2, 3]] # default setting
  21. input_shape = K.shape(yolo_outputs[0])[1:3] * 32
  22. boxes = []
  23. box_scores = []
  24. for l in range(num_layers):
  25. _boxes, _box_scores = yolo_boxes_and_scores(yolo_outputs[l],
  26. anchors[anchor_mask[l]],
  27. num_classes, input_shape, image_shape)
  28. boxes.append(_boxes)
  29. box_scores.append(_box_scores)
  30. boxes = K.concatenate(boxes, axis=0)
  31. box_scores = K.concatenate(box_scores, axis=0)
  32. mask = box_scores >= score_threshold
  33. max_boxes_tensor = K.constant(max_boxes, dtype='int32')
  34. boxes_ = []
  35. scores_ = []
  36. classes_ = []
  37. for c in range(num_classes):
  38. # TODO: use keras backend instead of tf.
  39. class_boxes = tf.boolean_mask(boxes, mask[:, c])
  40. class_box_scores = tf.boolean_mask(box_scores[:, c], mask[:, c])
  41. nms_index = tf.image.non_max_suppression(
  42. class_boxes, class_box_scores, max_boxes_tensor, iou_threshold=iou_threshold)
  43. class_boxes = K.gather(class_boxes, nms_index)
  44. class_box_scores = K.gather(class_box_scores, nms_index)
  45. classes = K.ones_like(class_box_scores, 'int32') * c
  46. boxes_.append(class_boxes)
  47. scores_.append(class_box_scores)
  48. classes_.append(classes)
  49. boxes_ = K.concatenate(boxes_, axis=0)
  50. scores_ = K.concatenate(scores_, axis=0)
  51. classes_ = K.concatenate(classes_, axis=0)
  52. return boxes_, scores_, classes_
  53. def yolo_boxes_and_scores(feats, anchors, num_classes, input_shape, image_shape):
  54. """Process Conv layer output"""
  55. box_xy, box_wh, box_confidence, box_class_probs = yolo_head(feats,
  56. anchors, num_classes, input_shape)
  57. boxes = yolo_correct_boxes(box_xy, box_wh, input_shape, image_shape)
  58. boxes = K.reshape(boxes, [-1, 4])
  59. box_scores = box_confidence * box_class_probs
  60. box_scores = K.reshape(box_scores, [-1, num_classes])
  61. return boxes, box_scores
  62. def yolo_head(feats, anchors, num_classes, input_shape, calc_loss=False):
  63. """Convert final layer features to bounding box parameters."""
  64. num_anchors = len(anchors)
  65. # feats = K.constant(feats)
  66. # Reshape to batch, height, width, num_anchors, box_params.
  67. anchors_tensor = K.reshape(K.constant(anchors), [1, 1, 1, num_anchors, 2])
  68. grid_shape = K.shape(feats)[1:3] # height, width
  69. grid_y = K.tile(K.reshape(K.arange(0, stop=grid_shape[0]), [-1, 1, 1, 1]),
  70. [1, grid_shape[1], 1, 1])
  71. grid_x = K.tile(K.reshape(K.arange(0, stop=grid_shape[1]), [1, -1, 1, 1]),
  72. [grid_shape[0], 1, 1, 1])
  73. grid = K.concatenate([grid_x, grid_y])
  74. grid = K.cast(grid, K.dtype(feats))
  75. feats = K.reshape(
  76. feats, [-1, grid_shape[0], grid_shape[1], num_anchors, num_classes + 5])
  77. # Adjust predictions to each spatial grid point and anchor size.
  78. box_xy = (K.sigmoid(feats[..., :2]) + grid) / K.cast(grid_shape[..., ::-1], K.dtype(feats))
  79. box_wh = K.exp(feats[..., 2:4]) * anchors_tensor / K.cast(input_shape[..., ::-1], K.dtype(feats))
  80. box_confidence = K.sigmoid(feats[..., 4:5])
  81. box_class_probs = K.sigmoid(feats[..., 5:])
  82. if calc_loss:
  83. return grid, feats, box_xy, box_wh
  84. return box_xy, box_wh, box_confidence, box_class_probs
  85. def yolo_correct_boxes(box_xy, box_wh, input_shape, image_shape):
  86. """Get corrected boxes"""
  87. box_yx = box_xy[..., ::-1]
  88. box_hw = box_wh[..., ::-1]
  89. input_shape = K.cast(input_shape, K.dtype(box_yx))
  90. image_shape = K.cast(image_shape, K.dtype(box_yx))
  91. new_shape = K.round(image_shape * K.min(input_shape/image_shape))
  92. offset = (input_shape-new_shape)/2./input_shape
  93. scale = input_shape/new_shape
  94. box_yx = (box_yx - offset) * scale
  95. box_hw *= scale
  96. box_mins = box_yx - (box_hw / 2.)
  97. box_maxes = box_yx + (box_hw / 2.)
  98. boxes = K.concatenate([
  99. box_mins[..., 0:1], # y_min
  100. box_mins[..., 1:2], # x_min
  101. box_maxes[..., 0:1], # y_max
  102. box_maxes[..., 1:2] # x_max
  103. ])
  104. # Scale boxes back to original image shape.
  105. boxes *= K.concatenate([image_shape, image_shape])
  106. return boxes
  107. def replace_seal_part(image_np, part_list, boxes):
  108. i = 0
  109. for box in boxes:
  110. x_min, y_min = box[0]
  111. x_max, y_max = box[1]
  112. part = part_list[i]
  113. image_np[y_min:y_max, x_min:x_max, :] = part
  114. i += 1
  115. return image_np
  116. def get_seal_part(image_np, boxes, classes):
  117. part_list = []
  118. for box in boxes:
  119. x_min, y_min = box[0]
  120. x_max, y_max = box[1]
  121. part = image_np[y_min:y_max, x_min:x_max, :]
  122. part_list.append(part)
  123. return part_list