Skip to content

Commit

Permalink
move bbox_transform_inv
Browse files Browse the repository at this point in the history
  • Loading branch information
jhung0 committed Aug 24, 2017
1 parent 4ef78c6 commit b648e2b
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 86 deletions.
51 changes: 51 additions & 0 deletions keras_rcnn/backend/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,54 @@ def smooth_l1_loss(y_true, y_pred):
x = keras.backend.switch(p, q, r)

return keras.backend.sum(x)


def bbox_transform_inv(shifted, boxes):
def shape_zero():
x = keras.backend.int_shape(boxes)[-1]

return keras.backend.zeros_like(x, dtype=keras.backend.floatx())

def shape_non_zero():
a = shifted[:, 2] - shifted[:, 0] + 1.0
b = shifted[:, 3] - shifted[:, 1] + 1.0

ctr_x = shifted[:, 0] + 0.5 * a
ctr_y = shifted[:, 1] + 0.5 * b

dx = boxes[:, 0::4]
dy = boxes[:, 1::4]
dw = boxes[:, 2::4]
dh = boxes[:, 3::4]

pred_ctr_x = dx * a[:, keras_rcnn.backend.newaxis] + ctr_x[:, keras_rcnn.backend.newaxis]
pred_ctr_y = dy * b[:, keras_rcnn.backend.newaxis] + ctr_y[:, keras_rcnn.backend.newaxis]

pred_w = keras.backend.exp(dw) * a[:, keras_rcnn.backend.newaxis]
pred_h = keras.backend.exp(dh) * b[:, keras_rcnn.backend.newaxis]


indices = keras.backend.tile(keras.backend.arange(0, keras.backend.shape(boxes)[0]), [4])
indices = keras.backend.reshape(indices, (-1, 1))
indices = keras.backend.tile(indices, [1, keras.backend.shape(boxes)[-1] // 4])
indices = keras.backend.reshape(indices, (-1, 1))
indices_coords = keras.backend.tile(keras.backend.arange(0, keras.backend.shape(boxes)[1], step = 4), [keras.backend.shape(boxes)[0]])
indices_coords = keras.backend.concatenate([indices_coords, indices_coords + 1, indices_coords + 2, indices_coords + 3], 0)
indices = keras.backend.concatenate([indices, keras.backend.expand_dims(indices_coords)], axis=1)


updates = keras.backend.concatenate([keras.backend.reshape(pred_ctr_x - 0.5 * pred_w, (-1,)),
keras.backend.reshape(pred_ctr_y - 0.5 * pred_h, (-1,)),
keras.backend.reshape(pred_ctr_x + 0.5 * pred_w, (-1,)),
keras.backend.reshape(pred_ctr_y + 0.5 * pred_h, (-1,))], axis=0)
pred_boxes = keras_rcnn.backend.scatter_add_tensor(keras.backend.zeros_like(boxes), indices, updates)
return pred_boxes


zero_boxes = keras.backend.equal(keras.backend.shape(boxes)[0], 0)

pred_boxes = keras.backend.switch(zero_boxes, shape_zero, shape_non_zero)

return pred_boxes


51 changes: 1 addition & 50 deletions keras_rcnn/layers/object_detection/_object_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def call(self, inputs, **kwargs):
deltas = keras.backend.reshape(deltas, (-1, 4))
scores = keras.backend.reshape(scores, (-1, 1))

deltas = bbox_transform_inv(anchors, deltas)
deltas = keras_rcnn.backend.bbox_transform_inv(anchors, deltas)

# 2. clip predicted boxes to image
proposals = keras_rcnn.backend.clip(deltas, image_shape)
Expand Down Expand Up @@ -98,55 +98,6 @@ def compute_output_shape(self, input_shape):
return None, self.maximum_proposals, 4


def bbox_transform_inv(shifted, boxes):
def shape_zero():
x = keras.backend.int_shape(boxes)[-1]

return keras.backend.zeros_like(x, dtype=keras.backend.floatx())

def shape_non_zero():
a = shifted[:, 2] - shifted[:, 0] + 1.0
b = shifted[:, 3] - shifted[:, 1] + 1.0

ctr_x = shifted[:, 0] + 0.5 * a
ctr_y = shifted[:, 1] + 0.5 * b

dx = boxes[:, 0::4]
dy = boxes[:, 1::4]
dw = boxes[:, 2::4]
dh = boxes[:, 3::4]

pred_ctr_x = dx * a[:, keras_rcnn.backend.newaxis] + ctr_x[:, keras_rcnn.backend.newaxis]
pred_ctr_y = dy * b[:, keras_rcnn.backend.newaxis] + ctr_y[:, keras_rcnn.backend.newaxis]

pred_w = keras.backend.exp(dw) * a[:, keras_rcnn.backend.newaxis]
pred_h = keras.backend.exp(dh) * b[:, keras_rcnn.backend.newaxis]


indices = keras.backend.tile(keras.backend.arange(0, keras.backend.shape(boxes)[0]), [4])
indices = keras.backend.reshape(indices, (-1, 1))
indices = keras.backend.tile(indices, [1, keras.backend.shape(boxes)[-1] // 4])
indices = keras.backend.reshape(indices, (-1, 1))
indices_coords = keras.backend.tile(keras.backend.arange(0, keras.backend.shape(boxes)[1], step = 4), [keras.backend.shape(boxes)[0]])
indices_coords = keras.backend.concatenate([indices_coords, indices_coords + 1, indices_coords + 2, indices_coords + 3], 0)
indices = keras.backend.concatenate([indices, keras.backend.expand_dims(indices_coords)], axis=1)


updates = keras.backend.concatenate([keras.backend.reshape(pred_ctr_x - 0.5 * pred_w, (-1,)),
keras.backend.reshape(pred_ctr_y - 0.5 * pred_h, (-1,)),
keras.backend.reshape(pred_ctr_x + 0.5 * pred_w, (-1,)),
keras.backend.reshape(pred_ctr_y + 0.5 * pred_h, (-1,))], axis=0)
pred_boxes = keras_rcnn.backend.scatter_add_tensor(keras.backend.zeros_like(boxes), indices, updates)
return pred_boxes


zero_boxes = keras.backend.equal(keras.backend.shape(boxes)[0], 0)

pred_boxes = keras.backend.switch(zero_boxes, shape_zero, shape_non_zero)

return pred_boxes


def filter_boxes(proposals, minimum):
"""
Filters proposed RoIs so that all have width and height at least as big as minimum
Expand Down
37 changes: 37 additions & 0 deletions tests/backend/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,40 @@ def test_shift():
assert keras.backend.int_shape(y) == (1764, 4)

assert y.dtype == keras.backend.floatx()


def test_bbox_transform_inv():
anchors = 9
features = (14, 14)
shifted = keras_rcnn.backend.shift(features, 16)
deltas = numpy.zeros((features[0] * features[1] * anchors, 4))
deltas = keras.backend.variable(deltas)
pred_boxes = keras_rcnn.backend.bbox_transform_inv(shifted, deltas)
assert keras.backend.eval(pred_boxes).shape == (1764, 4)

shifted = numpy.zeros((5, 4))
deltas = numpy.reshape(numpy.arange(12*5), (5, -1))
deltas = keras.backend.variable(deltas)
pred_boxes = keras_rcnn.backend.bbox_transform_inv(shifted, deltas)
expected = numpy.array(
[[ -3.19452805e+00, -8.54276846e+00, 4.19452805e+00,
1.15427685e+01, -1.97214397e+02, -5.42816579e+02,
2.06214397e+02, 5.53816579e+02, -1.10047329e+04,
-2.99275709e+04, 1.10217329e+04, 2.99465709e+04],
[ -6.01289642e+05, -1.63449519e+06, 6.01314642e+05,
1.63452219e+06, -3.28299681e+07, -8.92411330e+07,
3.28300011e+07, 8.92411680e+07, -1.79245640e+09,
-4.87240170e+09, 1.79245644e+09, 4.87240174e+09],
[ -9.78648047e+10, -2.66024120e+11, 9.78648047e+10,
2.66024120e+11, -5.34323729e+12, -1.45244248e+13,
5.34323729e+12, 1.45244248e+13, -2.91730871e+14,
-7.93006726e+14, 2.91730871e+14, 7.93006726e+14],
[ -1.59279659e+16, -4.32967002e+16, 1.59279659e+16,
4.32967002e+16, -8.69637471e+17, -2.36391973e+18,
8.69637471e+17, 2.36391973e+18, -4.74805971e+19,
-1.29065644e+20, 4.74805971e+19, 1.29065644e+20],
[ -2.59235276e+21, -7.04674541e+21, 2.59235276e+21,
7.04674541e+21, -1.41537665e+23, -3.84739263e+23,
1.41537665e+23, 3.84739263e+23, -7.72769468e+24,
-2.10060520e+25, 7.72769468e+24, 2.10060520e+25]], dtype=numpy.float32)
numpy.testing.assert_array_almost_equal(keras.backend.eval(pred_boxes)[0], expected[0], 0, verbose=True)
36 changes: 0 additions & 36 deletions tests/layers/object_detection/test_object_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,42 +20,6 @@ def test_call(self):
object_proposal.call([metadata, deltas, scores])


def test_bbox_transform_inv():
anchors = 9
features = (14, 14)
shifted = keras_rcnn.backend.shift(features, 16)
deltas = numpy.zeros((features[0] * features[1] * anchors, 4))
deltas = keras.backend.variable(deltas)
pred_boxes = keras_rcnn.layers.object_detection._object_proposal.bbox_transform_inv(shifted, deltas)
assert keras.backend.eval(pred_boxes).shape == (1764, 4)

shifted = numpy.zeros((5, 4))
deltas = numpy.reshape(numpy.arange(12*5), (5, -1))
deltas = keras.backend.variable(deltas)
pred_boxes = keras_rcnn.layers.object_detection._object_proposal.bbox_transform_inv(shifted, deltas)
expected = numpy.array(
[[ -3.19452805e+00, -8.54276846e+00, 4.19452805e+00,
1.15427685e+01, -1.97214397e+02, -5.42816579e+02,
2.06214397e+02, 5.53816579e+02, -1.10047329e+04,
-2.99275709e+04, 1.10217329e+04, 2.99465709e+04],
[ -6.01289642e+05, -1.63449519e+06, 6.01314642e+05,
1.63452219e+06, -3.28299681e+07, -8.92411330e+07,
3.28300011e+07, 8.92411680e+07, -1.79245640e+09,
-4.87240170e+09, 1.79245644e+09, 4.87240174e+09],
[ -9.78648047e+10, -2.66024120e+11, 9.78648047e+10,
2.66024120e+11, -5.34323729e+12, -1.45244248e+13,
5.34323729e+12, 1.45244248e+13, -2.91730871e+14,
-7.93006726e+14, 2.91730871e+14, 7.93006726e+14],
[ -1.59279659e+16, -4.32967002e+16, 1.59279659e+16,
4.32967002e+16, -8.69637471e+17, -2.36391973e+18,
8.69637471e+17, 2.36391973e+18, -4.74805971e+19,
-1.29065644e+20, 4.74805971e+19, 1.29065644e+20],
[ -2.59235276e+21, -7.04674541e+21, 2.59235276e+21,
7.04674541e+21, -1.41537665e+23, -3.84739263e+23,
1.41537665e+23, 3.84739263e+23, -7.72769468e+24,
-2.10060520e+25, 7.72769468e+24, 2.10060520e+25]], dtype=numpy.float32)
numpy.testing.assert_array_almost_equal(keras.backend.eval(pred_boxes)[0], expected[0], 0, verbose=True)

def test_filter_boxes():
proposals = numpy.array(
[[0, 2, 3, 10],
Expand Down

0 comments on commit b648e2b

Please sign in to comment.