def random_jpeg_quality(image,
                        min_jpeg_quality=0,
                        max_jpeg_quality=100,
                        random_coef=0.0,
                        seed=None,
                        preprocess_vars_cache=None):
  """Randomly encode the image to a random JPEG quality level.

  Args:
    image: rank 3 float32 tensor with shape [height, width, channels] and
      values in the range [0, 255].
    min_jpeg_quality: An int for the lower bound for selecting a random jpeg
      quality level.
    max_jpeg_quality: An int for the upper bound for selecting a random jpeg
      quality level.
    random_coef: a random coefficient that defines the chance of getting the
      original image. If random_coef is 0, we will always get the encoded image,
      and if it is 1.0, we will always get the original image.
    seed: random seed.
    preprocess_vars_cache: PreprocessorCache object that records previously
      performed augmentations. Updated in-place. If this function is called
      multiple times with the same non-null cache, it will perform
      deterministically.

  Returns:
    image: image which is the same shape as input image.
  """
  def _adjust_jpeg_quality():
    """Encodes the image as jpeg with a random quality and then decodes."""
    generator_func = functools.partial(
        tf.random_uniform, [],
        minval=min_jpeg_quality,
        maxval=max_jpeg_quality,
        dtype=tf.int32,
        seed=seed)
    quality = _get_or_create_preprocess_rand_vars(
        generator_func, preprocessor_cache.PreprocessorCache.JPEG_QUALITY,
        preprocess_vars_cache, key='quality')

    # Need to convert to uint8 before calling adjust_jpeg_quality since it
    # assumes that float features are in the range [0, 1], where herein the
    # range is [0, 255].
    image_uint8 = tf.cast(image, tf.uint8)
    adjusted_image = tf.image.adjust_jpeg_quality(image_uint8, quality)
    return tf.cast(adjusted_image, tf.float32)

  with tf.name_scope('RandomJpegQuality', values=[image]):
    generator_func = functools.partial(tf.random_uniform, [], seed=seed)
    do_encoding_random = _get_or_create_preprocess_rand_vars(
        generator_func, preprocessor_cache.PreprocessorCache.JPEG_QUALITY,
        preprocess_vars_cache)
    do_encoding_random = tf.greater_equal(do_encoding_random, random_coef)
    image = tf.cond(do_encoding_random, _adjust_jpeg_quality,
                    lambda: tf.cast(image, tf.float32))

  return image
Randomly encode the image to a random JPEG quality level.

  Args:
    image: rank 3 float32 tensor with shape [height, width, channels] and
      values in the range [0, 255].
    min_jpeg_quality: An int for the lower bound for selecting a random jpeg
      quality level.
    max_jpeg_quality: An int for the upper bound for selecting a random jpeg
      quality level.
    random_coef: a random coefficient that defines the chance of getting the
      original image. If random_coef is 0, we will always get the encoded image,
      and if it is 1.0, we will always get the original image.
    seed: random seed.
    preprocess_vars_cache: PreprocessorCache object that records previously
      performed augmentations. Updated in-place. If this function is called
      multiple times with the same non-null cache, it will perform
      deterministically.

  Returns:
    image: image which is the same shape as input image.
  
inference_api/src/main/object_detection/core/preprocessor.py