def anchor_refinement(boxes, deltas):
boxes = tf.cast(boxes, tf.float32)
h = boxes[:, 2] - boxes[:, 0]
w = boxes[:, 3] - boxes[:, 1]
center_y = boxes[:, 0] + h / 2
center_x = boxes[:, 1] + w / 2
center_y += deltas[:, 0] * h
center_x += deltas[:, 1] * w
h *= tf.exp(deltas[:, 2])
w *= tf.exp(deltas[:, 3])
y1 = center_y - h / 2
x1 = center_x - w / 2
y2 = center_y + h / 2
x2 = center_x + w / 2
boxes = tf.stack([y1, x1, y2, x2], axis=1)
return boxes
def boxes_clip(boxes, window):
wy1, wx1, wy2, wx2 = tf.split(window, 4)
y1, x1, y2, x2 = tf.split(boxes, 4, axis=1)
y1 = tf.maximum(tf.minimum(y1, wy2), wy1)
x1 = tf.maximum(tf.minimum(x1, wx2), wx1)
y2 = tf.maximum(tf.minimum(y2, wy2), wy1)
x2 = tf.maximum(tf.minimum(x2, wx2), wx1)
cliped = tf.concat([y1, x1, y2, x2], axis=1)
cliped.set_shape((cliped.shape[0], 4))
return cliped
def batch_slice(inputs, graph_fn, batch_size):
if not isinstance(inputs, list):
inputs = [inputs]
output = []
for i in range(batch_size):
inputs_slice = [x[i] for x in inputs]
output_slice = graph_fn(*inputs_slice)
if not isinstance(output_slice, (list, tuple)):
output_slice = [output_slice]
output.append(output_slice)
output = list(zip(*output))
result = [tf.stack(o, axis=0) for o in output]
if len(result)==1:
result = result[0]
return result
import keras.engine as KE
class proposal(KE.Layer):
def __init__(self, proposal_count, nms_thresh, anchors, batch_size, config=None, **kwargs):
super(proposal, self).__init__(**kwargs)
self.proposal_count = proposal_count
self.anchors = anchors
self.nms_thresh = nms_thresh
self.batch_size = batch_size
self.config = config
def call(self, inputs):
probs = inputs[0][:, :, 1]
deltas = inputs[1]
deltas = deltas * np.reshape(self.config.RPN_BBOX_STD_DEV, (1, 1, 4))
prenms_num = min(100, self.anchors.shape[0])
idxs = tf.nn.top_k(probs, prenms_num).indices
probs = batch_slice([probs, idxs], lambda x,y:tf.gather(x, y), self.batch_size)
deltas = batch_slice([deltas, idxs], lambda x,y:tf.gather(x, y), self.batch_size)
anchors = batch_slice([idxs], lambda x:tf.gather(self.anchors,x), self.batch_size)
refined_boxes = batch_slice([anchors, deltas], lambda x,y:anchor_refinement(x,y), self.batch_size)
H,W = self.config.image_size[:2]
windows = np.array([0,0,H,W]).astype(np.float32)
cliped_boxes = batch_slice([refined_boxes], lambda x:boxes_clip(x, windows), self.batch_size)
normalized_boxes = cliped_boxes / np.array([H,W,H,W])
def nms(normalized_boxes, scores):
idxs_ = tf.image.non_max_suppression(normalized_boxes, scores, self.proposal_count, self.nms_thresh)
box = tf.gather(normalized_boxes, idxs_)
pad_num = tf.maximum(self.proposal_count - tf.shape(normalized_boxes)[0],0)
box = tf.pad(box, [(0,pad_num),(0,0)])
return box
proposal_ = batch_slice([normalized_boxes, probs], nms, self.batch_size)
return proposal_
def compute_output_shape(self, input_shape):
return (None, self.proposal_count, 4)
pro
最新推荐文章于 2024-05-19 13:57:09 发布