您的位置:首页 > 其它

【TensorFlow】数据处理(对图像的处理)

2017-12-17 15:19 337 查看
项目已上传至 GitHub —— img-pre

目录结构

images 文件夹下存放将被用于处理的图像,img_all.py 示范了 TensorFlow 中图像处理函数的使用方法,img_pre.py 给出了一个对图像进行预处理的程序示例

img-pre/
images/
1.jpg
img_all.py
img_pre.py


图像处理函数

编码处理

在使用图像之前需要先对图像进行解码,将图像转为像素矩阵,tensorflow.image 提供了图像解码函数,返回的矩阵数据类型是 uint8

decode_jpeg:解码 JPEG 格式图像

decode_and_crop_jpeg:解码并裁剪 JPEG 格式图像

decode_png:解码 PNG 格式图像

decode_gif:解码 GIF 格式图像

decode_bmp:解码 BMP 格式图像

decode_image:自动检测图像格式进行解码,注意 GIF 格式图像返回一个四维矩阵

以下代码示范对 JPEG 格式图像的解码处理

import tensorflow as tf
import matplotlib.pyplot as plt

# 读取图像的原始数据
image_raw_data = tf.gfile.FastGFile('images/1.jpg', 'rb').read()

# 使用pyplot显示图像
def show(img_data):
plt.imshow(img_data.eval())
plt.show()

with tf.Session() as sess:
# 将原始数据解码成多维矩阵
img_data = tf.image.decode_jpeg(image_raw_data)
print(img_data.eval())
show(img_data)

# 将图像的矩阵编码成图像并存入文件
encoded_image = tf.image.encode_jpeg(img_data)
with tf.gfile.GFile('images/output.jpg', 'wb') as f:
f.write(encoded_image.eval())

# 将图像数据的类型转为实数类型,便于对图像进行处理
img_data = tf.image.convert_image_dtype(img_data, dtype=tf.float32)


大小调整

tf.image.resize_images 函数中有四种调整图像的方法,结果会有细微差别

method图像大小调整算法
0双线性插值法(Bilinear interpolation)
1最近邻居法(Nearest neighbor interpolation)
2双三次插值法(Bicubic interpolation)
3面积插值法(Area interpolation)
以下代码都是在图像编码处理代码的基础下运行,省去了加载原始图像,定义会话等过程

# 用resize_images调整图像大小
# 第一个参数为原始图像
# 第二个参数为调整后的图像大小[new_height,new_width],跟旧版本分为两个参数不一样
# method参数给出了调整图像大小的算法
resized = tf.image.resize_images(img_data, [300, 300], method=0)
print(resized.get_shape())  # 图像深度没有显式指定则为问号
show(resized)


还可以通过 resize_image_with_crop_or_pad 函数对图像进行裁剪或填充

# 用resize_image_with_crop_or_pad调整图像大小
# 第一个参数为原始图像
# 第二个和第三个参数是调整后的图像大小,大于原图则填充,小于则裁剪居中部分
croped = tf.image.resize_image_with_crop_or_pad(img_data, 200, 200)
show(croped)
padded = tf.image.resize_image_with_crop_or_pad(img_data, 500, 600)
show(padded)


还支持通过比例裁剪图像

# 用central_crop调整图像大小
# 第一个参数是原始图像
# 第二个参数为调整比例,是(0,1]的实数
central_cropped = tf.image.central_crop(img_data, 0.5)
show(central_cropped)


图像翻转

以下代码示范了将图像进行上下翻转、左右翻转及沿对角线翻转

# 图像翻转
flipped = tf.image.flip_up_down(img_data)  # 上下
show(flipped)
flipped = tf.image.flip_left_right(img_data)  # 左右
show(flipped)
transposed = tf.image.transpose_image(img_data)  # 对角线
show(transposed)


还可以随机翻转图像

# 随机翻转图像
flipped = tf.image.random_flip_up_down(img_data)  # 随机上下
show(flipped)
flipped = tf.image.random_flip_left_right(img_data)  # 随机左右
show(flipped)


色彩调整

图像的色彩调整有四方面

亮度

对比度

饱和度

色相

修改图像的亮度

# 调整图像的亮度
adjusted = tf.image.adjust_brightness(img_data, 0.5)  # 将图像的亮度+0.5
show(adjusted)
adjusted = tf.image.random_brightness(
img_data, max_delta=0.5)  # 在[-0.5,0.5]范围内随机调整图像亮度
show(adjusted)


修改图像的对比度

# 调整图像的对比度
adjusted = tf.image.adjust_contrast(img_data, -5)  # 将图像的对比度-5
show(adjusted)
adjusted = tf.image.adjust_contrast(img_data, 5)  # 将图像的对比度+5
show(adjusted)
adjusted = tf.image.random_contrast(img_data, lower=-5, upper=5)  # 随机调整对比度


修改图像的饱和度

# 调整图像的饱和度
adjusted = tf.image.adjust_saturation(img_data, -5)  # 将饱和度-5
show(adjusted)
adjusted = tf.image.adjust_saturation(img_data, 5)  # 将饱和度+5
show(adjusted)
adjusted = tf.image.random_saturation(image, lower=-5, uppper=5)  # 随机调整饱和度


调整图像的色相

# 调整图像的色相
adjusted = tf.image.adjust_hue(img_data, 0.5)  # 将色相+0.5
show(adjusted)
adjusted = tf.image.random_hue(img_data, max_delta=0.5)  # 随机调整色相
show(adjusted)


处理标注框

以下代码示范了如何在图像中加入标注框

# 用draw_bounding_boxes加入标注框
# 要求图像矩阵类型为实数
# 输入是一个batch的数据,也就是多张图像,所以需要加一维
batched = tf.expand_dims(img_data, 0)
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)
show(result)


还能通过 sample_distorted_bounding_box 函数来随机截取图像

# 用sample_distorted_bounding_box随机截取图像
boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])
begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(
tf.shape(img_data), bounding_boxes=boxes)  # 通过标注框告诉算法有信息量的部分
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)
show(distorted_image)


图像预处理示例

该代码实现自《TensorFlow:实战Google深度学习框架》

img_pre.py 这个示例给出了如何在程序中对图像进行预处理,从而降低不相关因素对训练模型的影响

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.0)
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)
elif color_ordering == 1:
image = tf.image.random_brightness(image, max_delta=32 / 255.0)
image = tf.image.random_hue(image, max_delta=0.2)
image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
elif color_ordering == 2:
# 一共可以有24种排列情况
pass
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.1)
distorted_image = tf.slice(image, bbox_begin, bbox_size)

# 将随机截取的图像调整为输入层的大小
distorted_image = tf.image.resize_images(
distorted_image, size=[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('images/1.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(6):
result = preprocess_for_train(img_data, 300, 300, boxes)
plt.imshow(result.eval())
plt.show()


原书中的函数版本有些落后,有些函数会报错

tf.image.sample_distorted_bounding_box()

# 旧版本

bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox)

# 新版本

bbox_begin,bbox_size,bbox_for_draw=tf.image.sample_distorted_bounding_box(tf.shape(image),bounding_boxes=bbox,min_object_covered=0.1)


如果不显式给 min_object_covered 参数就会报错

ValueError: Tried to convert ‘min_object_covered’ to a tensor and failed. Error: None values not supported.


tf.image.resize_images()

# 旧版本

distorted_image=tf.image.resize_images(distorted_image,height,width,method=method)

# 新版本

distorted_image = tf.image.resize_images(distorted_image, size=[height, width], method=method)


如果不将 size 写为 size=[height,width] 的形式就会报错

TypeError: resize_images() got multiple values for argument ‘method’
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息