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
|
import numpy as np
''' 该文件中的函数都是与anchors的变换相关,包括正向变换,反向变换。 '''
def bbox_transform(ex_rois, gt_rois): ''' 计算两个N * 4的矩阵之间的相关回归矩阵。 本质上是在求解每一个anchor相对于它的对应gt box的(dx, dy, dw, dh)的四个回归值,返回结果的shape为[N, 4]。 :param ex_rois: shape为[N, 4]的数组,一般传入的anchors的信息。 :param gt_rois: shape为[N, 4]的数组,一般传入的gt boxes(ground truth boxes)的信息。每一个gt roi都与一个ex roi相对应。 :return: 本质上是在求解每一个anchor相对于它的对应gt box的(dx, dy, dw, dh)的四个回归值,返回结果的shape为[N, 4]。 '''
ex_widths = ex_rois[:, 2] - ex_rois[:, 0] + 1.0 ex_heights = ex_rois[:, 3] - ex_rois[:, 1] + 1.0 ex_ctr_x = ex_rois[:, 0] + 0.5 * ex_widths ex_ctr_y = ex_rois[:, 1] + 0.5 * ex_heights
gt_widths = gt_rois[:, 2] - gt_rois[:, 0] + 1.0 gt_heights = gt_rois[:, 3] - gt_rois[:, 1] + 1.0 gt_ctr_x = gt_rois[:, 0] + 0.5 * gt_widths gt_ctr_y = gt_rois[:, 1] + 0.5 * gt_heights
targets_dx = (gt_ctr_x - ex_ctr_x) / ex_widths targets_dy = (gt_ctr_y - ex_ctr_y) / ex_heights targets_dw = np.log(gt_widths / ex_widths) targets_dh = np.log(gt_heights / ex_heights)
targets = np.vstack( (targets_dx, targets_dy, targets_dw, targets_dh)).transpose()
return targets
def bbox_transform_inv(boxes, deltas): ''' 将boxes使用rpn网络产生的deltas进行变换处理,求出变换后的boxes,即预测的proposals。 此处boxes一般表示原始anchors,即未经任何处理仅仅是经过平移之后产生测anchors。 :param boxes: 一般表示原始anchors,即未经任何处理仅仅是经过平移之后产生测anchors,shape为[N, 4],N表示anchors的数目。 :param deltas: RPN网络产生的数据,shape为[N, (1 + classes) * 4],classes表示类别数目,1 表示背景,N表示anchors的数目。 :return: 预测的变换之后的proposals(或者叫anchors) ''' if boxes.shape[0] == 0: return np.zeros((0, deltas.shape[1]), dtype=deltas.dtype)
boxes = boxes.astype(deltas.dtype, copy=False)
widths = boxes[:, 2] - boxes[:, 0] + 1.0 heights = boxes[:, 3] - boxes[:, 1] + 1.0 ctr_x = boxes[:, 0] + 0.5 * widths ctr_y = boxes[:, 1] + 0.5 * heights
dx = deltas[:, 0::4] dy = deltas[:, 1::4] dw = deltas[:, 2::4] dh = deltas[:, 3::4]
pred_ctr_x = dx * widths[:, np.newaxis] + ctr_x[:, np.newaxis] pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis] pred_w = np.exp(dw) * widths[:, np.newaxis] pred_h = np.exp(dh) * heights[:, np.newaxis]
pred_boxes = np.zeros(deltas.shape, dtype=deltas.dtype)
pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * pred_w pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * pred_h pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * pred_w pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * pred_h
return pred_boxes
def clip_boxes(boxes, im_shape): """ Clip boxes to image boundaries. 将boxes的边框进行裁剪,使得每一条边框都在图片大小的范围之内。 :param boxes: 等待裁剪的boxes,一般是一系列的anchors。 :param im_shape: 图片的大小形状 :return: 裁减之后的boxes,每一条边都在图片大小的范围内 """
boxes[:, 0::4] = np.maximum(np.minimum(boxes[:, 0::4], im_shape[1] - 1), 0) boxes[:, 1::4] = np.maximum(np.minimum(boxes[:, 1::4], im_shape[0] - 1), 0) boxes[:, 2::4] = np.maximum(np.minimum(boxes[:, 2::4], im_shape[1] - 1), 0) boxes[:, 3::4] = np.maximum(np.minimum(boxes[:, 3::4], im_shape[0] - 1), 0) return boxes
|