Skip to content

Instantly share code, notes, and snippets.

@eerwitt
Created February 1, 2016 23:32
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save eerwitt/51aba4bffd9ddd5c581c to your computer and use it in GitHub Desktop.
TensorFlow resize_image_with_crop_or_pad with an input pipeline to avoid issues with the image's shape not being fully defined. The example image is a 2x2 pixel color image used for testing.
Original Image:
[[[255 255 40]
[125 255 67]]
[[ 55 121 231]
[255 40 151]]]
Padded Image:
[[[255 255 40]
[125 255 67]
[ 0 0 0]]
[[ 55 121 231]
[255 40 151]
[ 0 0 0]]
[[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]]
Cropped Image:
[[[255 255 40]]]
import tensorflow as tf
import argparse
import os
def resize_image_with_crop_or_pad(image, target_height, target_width):
image_shape = tf.shape(image)
original_height = image_shape[0]
original_width = image_shape[1]
zero = tf.constant(0)
half = tf.constant(2)
offset_crop_width = tf.python.control_flow_ops.cond(
tf.less(
target_width,
original_width),
lambda: tf.floordiv(tf.sub(original_width, target_width), half),
lambda: zero)
offset_pad_width = tf.python.control_flow_ops.cond(
tf.greater(
target_width,
original_width),
lambda: tf.floordiv(tf.sub(target_width, original_width), half),
lambda: zero)
offset_crop_height = tf.python.control_flow_ops.cond(
tf.less(
target_height,
original_height),
lambda: tf.floordiv(tf.sub(original_height, target_height), half),
lambda: zero)
offset_pad_height = tf.python.control_flow_ops.cond(
tf.greater(
target_height,
original_height),
lambda: tf.floordiv(tf.sub(target_height, original_height), half),
lambda: zero)
cropped = crop_to_bounding_box(
image, offset_crop_height, offset_crop_width,
tf.minimum(target_height, original_height),
tf.minimum(target_width, original_width))
resized = pad_to_bounding_box(cropped, offset_pad_height, offset_pad_width,
target_height, target_width)
return resized
def crop_to_bounding_box(image, offset_height, offset_width, target_height,
target_width):
cropped = tf.slice(
image,
tf.pack([offset_height, offset_width, 0]),
tf.pack([target_height, target_width, -1]))
return cropped
def pad_to_bounding_box(image, offset_height, offset_width, target_height,
target_width):
image_shape = tf.shape(image)
original_height = image_shape[0]
original_width = image_shape[1]
after_padding_width = tf.sub(
tf.sub(target_width, offset_width), original_width)
after_padding_height = tf.sub(
tf.sub(target_height, offset_height), original_height)
paddings = tf.reshape(
tf.pack(
[offset_height, after_padding_height,
offset_width, after_padding_width,
0, 0]), [3, 2])
padded = tf.pad(image, paddings)
return padded
def pad_and_crop_image_dimensions(target_height, target_width, image_dir):
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once(
"{image_dir}/*.jpg".format(image_dir=image_dir)))
image_reader = tf.WholeFileReader()
_, image_file = image_reader.read(filename_queue)
image = tf.image.decode_jpeg(image_file)
resized_padding = resize_image_with_crop_or_pad(image, target_height + 1,
target_width + 1)
resized_cropping = resize_image_with_crop_or_pad(image, target_height - 1,
target_width - 1)
with tf.Session() as sess:
tf.initialize_all_variables().run()
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
result = sess.run([image, resized_padding, resized_cropping])
yield(result[0], result[1], result[2])
coord.request_stop()
coord.join(threads)
if __name__ == "__main__":
def check_if_images_exists(parser, image_dir):
if not os.path.isdir(image_dir):
parser.error(
"The directory {image_dir} does not exist.".format(
image_dir=image_dir))
return image_dir
parser = argparse.ArgumentParser(
description="Pad/Crop JPEG images from a file queue.")
parser.add_argument(
"--image-dir",
default="./images",
type=lambda image_dir: check_if_images_exists(parser, image_dir),
help="Relative directory with image files (extension .jpg required).")
args = parser.parse_args()
padded_and_cropped_dimensions = pad_and_crop_image_dimensions(
2, 2, args.image_dir)
for image, padded_image, cropped_image in padded_and_cropped_dimensions:
print("Original Image:\n{original_image}\n\n".format(
original_image=image))
print("Padded Image:\n{padded_image}\n\n".format(
padded_image=padded_image))
print("Cropped Image:\n{cropped_image}\n\n".format(
cropped_image=cropped_image))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment