def distorted_bounding_box_crop(image,
labels,
bboxes,
xs, ys,
min_object_covered,
aspect_ratio_range,
area_range,
max_attempts = 200,
scope=None):
"""Generates cropped_image using a one of the bboxes randomly distorted.
See `tf.image.sample_distorted_bounding_box` for more documentation.
Args:
image: 3-D Tensor of image (it will be converted to floats in [0, 1]).
bbox: 2-D float Tensor of bounding boxes arranged [num_boxes, coords]
where each coordinate is [0, 1) and the coordinates are arranged
as [ymin, xmin, ymax, xmax]. If num_boxes is 0 then it would use the whole
image.
min_object_covered: An optional `float`. Defaults to `0.1`. The cropped
area of the image must contain at least this fraction of any bounding box
supplied.
aspect_ratio_range: An optional list of `floats`. The cropped area of the
image must have an aspect ratio = width / height within this range.
area_range: An optional list of `floats`. The cropped area of the image
must contain a fraction of the supplied image within in this range.
max_attempts: An optional `int`. Number of attempts at generating a cropped
region of the image of the specified constraints. After `max_attempts`
failures, return the entire image.
scope: Optional scope for name_scope.
Returns:
A tuple, a 3-D Tensor cropped_image and the distorted bbox
"""
with tf.name_scope(scope, 'distorted_bounding_box_crop', [image, bboxes, xs, ys]):
bbox_begin, bbox_size, distort_bbox = tf.image.sample_distorted_bounding_box(
tf.shape(image),
bounding_boxes=tf.expand_dims(bboxes, 0),
min_object_covered=min_object_covered,
aspect_ratio_range=aspect_ratio_range,
area_range=area_range,
max_attempts=max_attempts,
use_image_if_no_bounding_boxes=True)
distort_bbox = distort_bbox[0, 0]
cropped_image = tf.slice(image, bbox_begin, bbox_size)
cropped_image.set_shape([None, None, 3])
bboxes, xs, ys = tfe.bboxes_resize(distort_bbox, bboxes, xs, ys)
labels, bboxes, xs, ys = tfe.bboxes_filter_overlap(labels, bboxes, xs, ys,
threshold=BBOX_CROP_OVERLAP, assign_negative = False)
return cropped_image, labels, bboxes, xs, ys, distort_bbox
def bboxes_resize(bbox_ref, bboxes, xs, ys, name=None):
"""Resize bounding boxes based on a reference bounding box,
assuming that the latter is [0, 0, 1, 1] after transform. Useful for
updating a collection of boxes after cropping an image.
"""
with tf.name_scope(name, 'bboxes_resize'):
h_ref = bbox_ref[2] - bbox_ref[0]
w_ref = bbox_ref[3] - bbox_ref[1]
v = tf.stack([bbox_ref[0], bbox_ref[1], bbox_ref[0], bbox_ref[1]])
bboxes = bboxes - v
xs = xs - bbox_ref[1]
ys = ys - bbox_ref[0]
s = tf.stack([h_ref, w_ref, h_ref, w_ref])
bboxes = bboxes / s
xs = xs / w_ref;
ys = ys / h_ref;
return bboxes, xs, ys