Example #1
0
  def _patch(self, one, two):
    """Build the full 4 patch of images from sets of 2 images."""
    image = tf.concat([one['image'], two['image']], axis=-3)
    boxes = tf.concat([one['groundtruth_boxes'], two['groundtruth_boxes']],
                      axis=0)
    classes = tf.concat(
        [one['groundtruth_classes'], two['groundtruth_classes']], axis=0)
    is_crowd = tf.concat(
        [one['groundtruth_is_crowd'], two['groundtruth_is_crowd']], axis=0)
    area = tf.concat([one['groundtruth_area'], two['groundtruth_area']], axis=0)

    if self._mosaic_crop_mode is not None:
      image, boxes, classes, is_crowd, area, _ = self._mosaic_crop_image(
          image, boxes, classes, is_crowd, area)

    sample = one
    height, width = preprocessing_ops.get_image_shape(image)
    sample['image'] = tf.cast(image, tf.uint8)
    sample['groundtruth_boxes'] = boxes
    sample['groundtruth_area'] = area
    sample['groundtruth_classes'] = tf.cast(classes,
                                            sample['groundtruth_classes'].dtype)
    sample['groundtruth_is_crowd'] = tf.cast(is_crowd, tf.bool)
    sample['width'] = tf.cast(width, sample['width'].dtype)
    sample['height'] = tf.cast(height, sample['height'].dtype)
    sample['num_detections'] = tf.shape(sample['groundtruth_boxes'])[1]
    sample['is_mosaic'] = tf.cast(1.0, tf.bool)

    del sample['shiftx']
    del sample['shifty']
    del sample['crop_points']
    return sample
Example #2
0
def letterbox(image: tf.Tensor,
              desired_size: List[int],
              letter_box: bool = True) -> Tuple[tf.Tensor, tf.Tensor]:
  """Letter box an image for image serving."""

  with tf.name_scope('letter_box'):
    image_size = tf.cast(preprocessing_ops.get_image_shape(image), tf.float32)

    scaled_size = tf.cast(desired_size, image_size.dtype)
    if letter_box:
      scale = tf.minimum(scaled_size[0] / image_size[0],
                         scaled_size[1] / image_size[1])
      scaled_size = tf.round(image_size * scale)
    else:
      scale = 1.0

    # Computes 2D image_scale.
    image_scale = scaled_size / image_size
    image_offset = tf.cast((desired_size - scaled_size) * 0.5, tf.int32)
    offset = (scaled_size - desired_size) * 0.5
    scaled_image = tf.image.resize(
        image, tf.cast(scaled_size, tf.int32), method='nearest')

    output_image = tf.image.pad_to_bounding_box(scaled_image, image_offset[0],
                                                image_offset[1],
                                                desired_size[0],
                                                desired_size[1])

    image_info = tf.stack([
        image_size,
        tf.cast(desired_size, dtype=tf.float32), image_scale,
        tf.cast(offset, tf.float32)
    ])
    return output_image, image_info
Example #3
0
    def _mosaic_crop_image(self, image, boxes, classes, is_crowd, area):
        """Process a patched image in preperation for final output."""
        if self._mosaic_crop_mode != 'crop':
            shape = tf.cast(preprocessing_ops.get_image_shape(image),
                            tf.float32)
            center = shape * self._mosaic_center

            # shift the center of the image by applying a translation to the whole
            # image
            ch = tf.math.round(
                preprocessing_ops.random_uniform_strong(-center[0],
                                                        center[0],
                                                        seed=self._seed))
            cw = tf.math.round(
                preprocessing_ops.random_uniform_strong(-center[1],
                                                        center[1],
                                                        seed=self._seed))

            # clip the boxes to those with in the image
            image = tfa.image.translate(image, [cw, ch],
                                        fill_value=self._pad_value)
            boxes = box_ops.denormalize_boxes(boxes, shape[:2])
            boxes = boxes + tf.cast([ch, cw, ch, cw], boxes.dtype)
            boxes = box_ops.clip_boxes(boxes, shape[:2])
            inds = box_ops.get_non_empty_box_indices(boxes)

            boxes = box_ops.normalize_boxes(boxes, shape[:2])
            boxes, classes, is_crowd, area = self._select_ind(
                inds,
                boxes,
                classes,  # pylint:disable=unbalanced-tuple-unpacking
                is_crowd,
                area)

        # warp and scale the fully stitched sample
        image, _, affine = preprocessing_ops.affine_warp_image(
            image, [self._output_size[0], self._output_size[1]],
            scale_min=self._aug_scale_min,
            scale_max=self._aug_scale_max,
            translate=self._aug_rand_translate,
            degrees=self._aug_rand_angle,
            perspective=self._aug_rand_perspective,
            random_pad=self._random_pad,
            seed=self._seed)
        height, width = self._output_size[0], self._output_size[1]
        image = tf.image.resize(image, (height, width))

        # clip and clean boxes
        boxes, inds = preprocessing_ops.transform_and_clip_boxes(
            boxes,
            None,
            affine=affine,
            area_thresh=self._area_thresh,
            seed=self._seed)
        classes, is_crowd, area = self._select_ind(inds, classes, is_crowd,
                                                   area)  # pylint:disable=unbalanced-tuple-unpacking
        return image, boxes, classes, is_crowd, area, area
Example #4
0
    def _reorg_boxes(self, boxes, num_detections, image):
        """Scale and Clean boxes prior to Evaluation."""

        # Build a prediciton mask to take only the number of detections
        mask = tf.sequence_mask(num_detections, maxlen=tf.shape(boxes)[1])
        mask = tf.cast(tf.expand_dims(mask, axis=-1), boxes.dtype)

        # Denormalize the boxes by the shape of the image
        inshape = tf.cast(preprocessing_ops.get_image_shape(image),
                          boxes.dtype)
        boxes = box_ops.denormalize_boxes(boxes, inshape)

        # Mask the boxes for usage
        boxes *= mask
        boxes += (mask - 1)
        return boxes
Example #5
0
 def testGetImageShape(self, image_height, image_width):
   image = tf.convert_to_tensor(np.random.rand(image_height, image_width, 3))
   image_shape = preprocessing_ops.get_image_shape(image)
   self.assertAllEqual((image_height, image_width), image_shape)