def box_iou(self, true_box, pred_box): # based on the type of loss, compute the iou loss for a box # compute_<name> indicated the type of iou to use if self.iou_type == 'giou': _, iou = box_ops.compute_giou(true_box, pred_box) elif self.iou_type == 'ciou': _, iou = box_ops.compute_ciou(true_box, pred_box) else: iou = box_ops.compute_iou(true_box, pred_box) return iou
def box_loss(self, true_box, pred_box, darknet=False): """Call iou function and use it to compute the loss for the box maps.""" if self._loss_type == 'giou': iou, liou = box_ops.compute_giou(true_box, pred_box) elif self._loss_type == 'ciou': iou, liou = box_ops.compute_ciou(true_box, pred_box, darknet=darknet) else: liou = iou = box_ops.compute_iou(true_box, pred_box) loss_box = 1 - liou return iou, liou, loss_box
def test_ious(self, num_boxes): boxes = tf.convert_to_tensor(np.random.rand(num_boxes, 4)) expected_shape = np.array([ num_boxes, ]) expected_iou = np.ones([ num_boxes, ]) iou = box_ops.compute_iou(boxes, boxes) _, giou = box_ops.compute_giou(boxes, boxes) _, ciou = box_ops.compute_ciou(boxes, boxes) _, diou = box_ops.compute_diou(boxes, boxes) self.assertAllEqual(tf.shape(iou).numpy(), expected_shape) self.assertArrayNear(iou, expected_iou, 0.001) self.assertArrayNear(giou, expected_iou, 0.001) self.assertArrayNear(ciou, expected_iou, 0.001) self.assertArrayNear(diou, expected_iou, 0.001)
def aggregated_comparative_iou(boxes1, boxes2=None, iou_type=0): k = tf.shape(boxes1)[-2] boxes1 = tf.expand_dims(boxes1, axis=-2) boxes1 = tf.tile(boxes1, [1, 1, k, 1]) if boxes2 is not None: boxes2 = tf.expand_dims(boxes2, axis=-2) boxes2 = tf.tile(boxes2, [1, 1, k, 1]) boxes2 = tf.transpose(boxes2, perm=(0, 2, 1, 3)) else: boxes2 = tf.transpose(boxes1, perm=(0, 2, 1, 3)) if iou_type == 0: # diou _, iou = box_ops.compute_diou(boxes1, boxes2) elif iou_type == 1: # giou _, iou = box_ops.compute_giou(boxes1, boxes2) else: iou = box_ops.compute_iou(boxes1, boxes2, yxyx=True) return iou
def get_best_anchor(y_true, anchors, width=1, height=1): """Gets the correct anchor that is assoiciated with each box using IOU. Args: y_true: tf.Tensor[] for the list of bounding boxes in the yolo format anchors: list or tensor for the anchor boxes to be used in prediction found via Kmeans width: int for the image width height: int for the image height Returns: tf.Tensor: y_true with the anchor associated with each ground truth box known. """ with tf.name_scope('get_anchor'): width = tf.cast(width, dtype=tf.float32) height = tf.cast(height, dtype=tf.float32) # split the boxes into center and width height anchor_xy = y_true[..., 0:2] # scale thhe boxes anchors = tf.convert_to_tensor(anchors, dtype=tf.float32) anchors_x = anchors[..., 0] / width anchors_y = anchors[..., 1] / height anchors = tf.stack([anchors_x, anchors_y], axis=-1) k = tf.shape(anchors)[0] # build a matrix of anchor boxes of shape [num_anchors, num_boxes, 4] anchors = tf.transpose(anchors, perm=[1, 0]) anchor_xy = tf.tile(tf.expand_dims(anchor_xy, axis=-1), [1, 1, tf.shape(anchors)[-1]]) anchors = tf.tile(tf.expand_dims(anchors, axis=0), [tf.shape(anchor_xy)[0], 1, 1]) # stack the xy so, each anchor is asscoaited once with each center from # the ground truth input anchors = tf.concat([anchor_xy, anchors], axis=1) anchors = tf.transpose(anchors, perm=[2, 0, 1]) # copy the gt n times so that each anchor from above can be compared to # input ground truth to shape: [num_anchors, num_boxes, 4] truth_comp = tf.tile(tf.expand_dims(y_true[..., 0:4], axis=-1), [1, 1, tf.shape(anchors)[0]]) truth_comp = tf.transpose(truth_comp, perm=[2, 0, 1]) # compute intersection over union of the boxes, and take the argmax of # comuted iou for each box. thus each box is associated with the # largest interection over union iou_raw = box_ops.compute_iou(truth_comp, anchors) values, indexes = tf.math.top_k(tf.transpose(iou_raw, perm=[1, 0]), k=tf.cast(k, dtype=tf.int32), sorted=True) ind_mask = tf.cast(values > 0.213, dtype=indexes.dtype) # pad the indexs such that all values less than the thresh are -1 # add one, multiply the mask to zeros all the bad locations # subtract 1 makeing all the bad locations 0. iou_index = tf.concat([ tf.keras.backend.expand_dims(indexes[..., 0], axis=-1), ((indexes[..., 1:] + 1) * ind_mask[..., 1:]) - 1 ], axis=-1) iou_index = iou_index[..., :6] return tf.cast(iou_index, dtype=tf.float32)
def get_best_anchor(y_true, anchors, width=1, height=1): """Gets the correct anchor that is assoiciated with each box using IOU between input anchors and ground truth. Args: y_true: tf.Tensor[] for the list of bounding boxes in the yolo format anchors: list or tensor for the anchor boxes to be used in prediction found via Kmeans size: size of the image that the bounding boxes were selected at 416 is the default for the original YOLO model return: tf.Tensor: y_true with the anchor associated with each ground truth box known """ with tf.name_scope('get_anchor'): width = tf.cast(width, dtype=tf.float32) height = tf.cast(height, dtype=tf.float32) anchor_xy = y_true[..., 0:2] true_wh = y_true[..., 2:4] # scale thhe boxes anchors = tf.convert_to_tensor(anchors, dtype=tf.float32) anchors_x = anchors[..., 0] / width anchors_y = anchors[..., 1] / height anchors = tf.stack([anchors_x, anchors_y], axis=-1) # build a matrix of anchor boxes anchors = tf.transpose(anchors, perm=[1, 0]) anchor_xy = tf.tile(tf.expand_dims(anchor_xy, axis=-1), [1, 1, tf.shape(anchors)[-1]]) anchors = tf.tile(tf.expand_dims(anchors, axis=0), [tf.shape(anchor_xy)[0], 1, 1]) # stack the xy so, each anchor is asscoaited once with each center from # the ground truth input anchors = tf.keras.layers.concatenate([anchor_xy, anchors], axis=1) anchors = tf.transpose(anchors, perm=[2, 0, 1]) # copy the gt n times so that each anchor from above can be compared to # input ground truth truth_comp = tf.tile(tf.expand_dims(y_true[..., 0:4], axis=-1), [1, 1, tf.shape(anchors)[0]]) truth_comp = tf.transpose(truth_comp, perm=[2, 0, 1]) # compute intersection over union of the boxes, and take the argmax of # comuted iou for each box. thus each box is associated with the largest # interection over union iou_raw = box_ops.compute_iou(truth_comp, anchors) gt_mask = tf.cast(iou_raw > 0.213, dtype=iou_raw.dtype) num_k = tf.reduce_max( tf.reduce_sum(tf.transpose(gt_mask, perm=[1, 0]), axis=1)) if num_k <= 0: num_k = 1.0 values, indexes = tf.math.top_k(tf.transpose(iou_raw, perm=[1, 0]), k=tf.cast(num_k, dtype=tf.int32), sorted=True) ind_mask = tf.cast(values > 0.213, dtype=indexes.dtype) iou_index = tf.concat([ tf.expand_dims(indexes[..., 0], axis=-1), ((indexes[..., 1:] + 1) * ind_mask[..., 1:]) - 1 ], axis=-1) stack = tf.zeros( [tf.shape(iou_index)[0], tf.cast(1, dtype=iou_index.dtype)], dtype=iou_index.dtype) - 1 while num_k < 5: iou_index = tf.concat([iou_index, stack], axis=-1) num_k += 1 iou_index = iou_index[..., :5] values = tf.concat([ tf.expand_dims(values[..., 0], axis=-1), ((values[..., 1:]) * tf.cast(ind_mask[..., 1:], dtype=tf.float32)) ], axis=-1) return tf.cast(iou_index, dtype=tf.float32)