TensorFlow 提供了比较丰富的图像处理函数,如翻转,尺寸调整等.
<h2>1. 图像预处理函数</h2>
#! ---- coding: utf-8 ----
import tensorflow as tf
import matplotlib.pyplot as plt
# 读取图像原始数据
image_raw_data = tf.gfile.FastGFile('/path/to/image.jpg', 'rb').read()
def imshow(img)
plt.imshow(img)
plt.show()
# 建立图像处理会话 Session
with tf.Session() as sess:
#-------------------------------------------
# 1. 图像解码
#-------------------------------------------
# 将原始数据解码成三维维矩阵
img_data = tf.image.decode_jpeg(image_raw_data)
print(img_data.eval())
imshow(img_data)
# 将图像的矩阵编码成图像并存入文件
encoded_image = tf.image.encode_jpeg(img_data)
with tf.gfile.GFile('/path/to/image_output.jpg', 'wb') as f:
f.write(encoded_image.eval())
# 将图像数据的类型转为 float32 实数类型,便于图像处理
img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)
#------------------------------------------
# 2. 图像大小调整
#-------------- ----------------------------
# resize_images 函数 - 调整图像大小
# 第一个参数为原始图像
# 第二个参数为调整后的图像大小 [new_height, new_width]
# method 参数指定调整图像大小的算法
# 0 - 双线性插值法(Bilinear interpolation)
# 1 - 最近邻居法(Nearest neighbor interpolation)
# 2 - 双三次插值法(Bicubic interpolation)
# 3 - 面积插值法(Area interpolation)
resized_img = tf.image.resize_images(img_data, [300, 300], method=0)
print(resized_img.get_shape())
imshow(resized_img)
# resize_image_with_crop_or_pad 函数 - 调整图像大小
# 第一个参数为原始图像
# 第二个和第三个参数是调整后的图像大小,大于原图则填充,小于则裁剪居中部分
croped_img = tf.image.resize_image_with_crop_or_pad(img_data, 200, 200)
imshow(croped_img)
padded_img = tf.image.resize_image_with_crop_or_pad(img_data, 500, 600)
imshow(padded_img)
# central_crop 函数 - 调整图像大小
# 第一个参数是原始图像
# 第二个参数为调整比例,是[0,1] 间的实数
central_cropped_img = tf.image.central_crop(img_data, 0.5)
imshow(central_cropped_img)
#------------------------------------------
# 3. 图像翻转
#-------------- ----------------------------
flipped_img = tf.image.flip_up_down(img_data) # 上下翻转
imshow(flipped_img)
flipped_img = tf.image.flip_left_right(img_data) # 左右翻转
imshow(flipped_img)
transposed_im = tf.image.transpose_image(img_data) # 沿对角线翻转
imshow(transposed_img)
# 随机图像翻转
flipped_img = tf.image.random_flip_up_down(img_data) # 随机上下翻转
imshow(flipped_img)
flipped_img = tf.image.random_flip_left_right(img_data) # 随机左右翻转
imshow(flipped_img)
#------------------------------------------
# 4. 图像色彩调整
#-------------- ----------------------------
# 主要调整包括:亮度;对比度;饱和度;色相.
# 图像亮度调整
adjusted_img = tf.image.adjust_brightness(img_data, -0.5) # 图像亮度-0.5
adjusted_img = tf.clip_by_value(adjusted_img, 0.0, 1.0) # 确保像素值截断在 [0.0, 1.0]间.
imshow(adjusted_img)
adjusted_img = tf.image.adjust_brightness(img_data, 0.5) # 图像亮度+0.5
imshow(adjusted_img)
# 随机图像亮度调整
adjusted_img = tf.image.random_brightness(img_data, max_delta=0.5) # 在[-max_delta, max_delta]范围内随机调整图像亮度
imshow(adjusted_img)
# 图像对比度调整
adjusted_img = tf.image.adjust_contrast(img_data, -0.5) # 图像对比度减少到 0.5 倍
imshow(adjusted_img)
adjusted_img = tf.image.adjust_contrast(img_data, 5) # 图像对比度增加 5 倍
imshow(adjusted_img)
adjusted_img = tf.image.random_contrast(img_data, lower=-5, upper=5) # 在 [lower, upper] 范围内随机调整图像对比度
imshow(adjusted_img)
# 图像饱和度调整
adjusted_img = tf.image.adjust_saturation(img_data, -5) # 图像饱和度 -5
imshow(adjusted_img)
adjusted_img = tf.image.adjust_saturation(img_data, 5) # 图像饱和度 +5
imshow(adjusted_img)
adjusted_img = tf.image.random_saturation(image, lower=-5, uppper=5) # 在 [lower, upper] 范围内随机调整图像饱和度
imshow(adjusted_img)
# 图像色相调整
adjusted_img = tf.image.adjust_hue(img_data, 0.5) # 图像色相 +0.5
imshow(adjusted_img)
adjusted_img = tf.image.random_hue(img_data, max_delta=0.5) # 在 [-max_delta, max_delta] 范围内随机调整图像色相, max_delta 取值在 [0, 0.5]
imshow(adjusted_img)
#------------------------------------------
# 5. 图像标准化
#-------------- ----------------------------
# 将图像上的亮度均值变为 0,方差变为 1.
adjusted_img = tf.image.per_image_standardization(img_data)
#------------------------------------------
# 6. 图像标注框处理
#-------------- ----------------------------
# 采用标注框将图像中关注的物体圈出来.
# draw_bounding_boxes 函数 - 图像加入标注框
# 该函数要求图像矩阵中的数字为实数, 处理前需要先转换为实数类型.
# 该函数输入是一个batch的数据,即多张图像组成的四维矩阵
# 因此,需要对解码后的图像矩阵加一维.
# img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)
batched = tf.expand_dims(img_data, 0)
# 图像标注框
# 标注框有 4 个数字:[y_min, x_min, y_max, x_max]. 数字均是图像的相对位置.
# 如:图像尺寸为 180x267, 则 [0.35, 0.47, 0.5, 0.56] 表示从 [63, 125] 到 [90, 150] 的标注框图像.
boxes = tf.constant( [ [ [0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56] ] ] ) # 代表图像的相对位置
result = tf.image.draw_bounding_boxes(batched, boxes)
imshow(result)
# sample_distorted_bounding_box 函数 - 随机截取图像
boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
# min_object_convered=0.4 表示截取图像部分至少包含某个标注框 40% 的内容信息.
begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(tf.shape(img_data),
bounding_boxes=boxes,
min_object_convered=0.4) # 通过标注框告诉算法有信息量的部分
# 随机截取图像的可视化
batched = tf.expand_dims(img_data, 0)
image_with_box = tf.image.draw_bounding_boxes(batched, bbox_for_draw)
distorted_image = tf.slice(img_data, begin, size)
imshow(distorted_image)
<h2>2. 图像预处理样例</h2>
TensorFlow:实战Google深度学习框架(第2版) - 7.2.2 - 图像预处理完整样例
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
def distort_color(image, color_ordering=0):
'''
随机调整图片的色彩,定义两种顺序
'''
if color_ordering == 0:
image = tf.image.random_brightness(image, max_delta=32./255.)
image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
image = tf.image.random_hue(image, max_delta=0.2)
image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
else:
image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
image = tf.image.random_brightness(image, max_delta=32./255.)
image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
image = tf.image.random_hue(image, max_delta=0.2)
return tf.clip_by_value(image, 0.0, 1.0)
def preprocess_for_train(image, height, width, bbox):
'''
图片预处理,
将图片转化成神经网络的输入层数据
'''
# 查看是否存在标注框
if bbox is None:
bbox = tf.constant([0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])
if image.dtype != tf.float32:
image = tf.image.convert_image_dtype(image, dtype=tf.float32)
# 随机的截取图片中一个块
bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(
tf.shape(image), bounding_boxes=bbox, min_object_covered=0.4)
bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(
tf.shape(image), bounding_boxes=bbox, min_object_covered=0.4)
distorted_image = tf.slice(image, bbox_begin, bbox_size)
# 将随机截取的图片调整为神经网络输入层的大小
distorted_image = tf.image.resize_images(distorted_image, [height, width], method=np.random.randint(4))
distorted_image = tf.image.random_flip_left_right(distorted_image)
distorted_image = distort_color(distorted_image, np.random.randint(2))
return distorted_image
# 读取图片
image_raw_data = tf.gfile.FastGFile("datasets/cat.jpg", "rb").read()
with tf.Session() as sess:
img_data = tf.image.decode_jpeg(image_raw_data)
boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
for i in range(9):
result = preprocess_for_train(img_data, 299, 299, boxes)
plt.imshow(result.eval())
plt.show()