//  [python]
def resize_keeping_aspect_ratio(image, masks, boxes, keypoints, min_dimension, divisor):
    """
    This function resizes and possibly pads with zeros.
    When using a usual FPN, divisor must be equal to 128.

    Arguments:
        image: a float tensor with shape [height, width, 3].
        masks: a float tensor with shape [height / DOWNSAMPLE, width / DOWNSAMPLE, 2].
        boxes: a float tensor with shape [num_persons, 4].
        keypoints: an int tensor with shape [num_persons, 17, 3].
        min_dimension, divisor: integers.
    Returns:
        image: a float tensor with shape [h, w, 3],
            where `min_dimension = min(h, w)`,
            `h` and `w` are divisible by `DIVISOR`.
        masks: a float tensor with shape [h / DOWNSAMPLE, w / DOWNSAMPLE, 2].
        boxes: a float tensor with shape [num_persons, 4].
        keypoints: an int tensor with shape [num_persons, 17, 3].
    """

    assert min_dimension % divisor == 0
    min_dimension = tf.constant(min_dimension, dtype=tf.int32)
    divisor = tf.constant(divisor, dtype=tf.int32)

    shape = tf.shape(image)
    height, width = shape[0], shape[1]

    original_min_dim = tf.minimum(height, width)
    scale_factor = tf.cast(min_dimension / original_min_dim, tf.float32)

    # RESIZE AND PAD IMAGE

    def scale(x):
        unpadded_x = tf.to_int32(tf.round(tf.cast(x, tf.float32) * scale_factor))
        x = tf.to_int32(tf.ceil(unpadded_x / divisor))
        pad = divisor * x - unpadded_x
        return (unpadded_x, pad)

    zero = tf.constant(0, dtype=tf.int32)
    new_height, pad_height, new_width, pad_width = tf.cond(
        tf.greater_equal(height, width),
        lambda: scale(height) + (min_dimension, zero),
        lambda: (min_dimension, zero) + scale(width)
    )

    # final image size
    h = new_height + pad_height
    w = new_width + pad_width

    # resize keeping aspect ratio
    image = tf.image.resize_images(image, [new_height, new_width], method=RESIZE_METHOD)

    # pad image at the bottom or at the right
    image = tf.image.pad_to_bounding_box(image, offset_height=0, offset_width=0, target_height=h, target_width=w)

    # RESIZE AND PAD MASKS

    # new size of masks with padding
    map_height = tf.to_int32(tf.ceil(h / DOWNSAMPLE))
    map_width = tf.to_int32(tf.ceil(w / DOWNSAMPLE))

    # new size of only masks without padding
    map_only_height = tf.to_int32(tf.ceil(new_height / DOWNSAMPLE))
    map_only_width = tf.to_int32(tf.ceil(new_width / DOWNSAMPLE))

    masks = tf.image.resize_images(
        masks, [map_only_height, map_only_width],
        method=tf.image.ResizeMethod.NEAREST_NEIGHBOR
    )

    masks = tf.image.pad_to_bounding_box(
        masks, offset_height=0, offset_width=0,
        target_height=map_height, target_width=map_width
    )

    # TRANSFORM KEYPOINTS

    keypoint_scaler = tf.stack([new_height/height, new_width/width])
    keypoint_scaler = tf.cast(keypoint_scaler, tf.float32)

    points, v = tf.split(keypoints, [2, 1], axis=2)
    points = tf.to_int32(tf.round(tf.cast(points, tf.float32) * keypoint_scaler))
    y, x = tf.split(points, 2, axis=2)
    y = tf.clip_by_value(y, 0, h - 1)
    x = tf.clip_by_value(x, 0, w - 1)
    keypoints = tf.concat([y, x, v], axis=2)

    # TRANSFORM BOXES

    box_scaler = tf.concat(2 * [keypoint_scaler], axis=0)
    boxes *= box_scaler

    return image, masks, boxes, keypoints