在Tensorflow中保存图像文件

use*_*589 11 tensorflow

我刚开始使用Tensorflow,我有一个新手问题.

我知道Tensorflow是关于神经网络的,但我只是从它的机制开始.我试图让它加载,调整大小,翻转和保存两个图像.应该是一个简单的操作,对,它让我从基础开始.

到目前为止,这是我的代码:

import tensorflow as tf
import numpy as np

print("resizing images")

filenames = ['img1.png', 'img2.png' ]
filename_queue = tf.train.string_input_producer(filenames, num_epochs=1)

reader = tf.WholeFileReader()
key,value = reader.read(filename_queue)
images = tf.image.decode_png(value)

resized = tf.image.resize_images(images, 180,180, 1)
resized.set_shape([180,180,3])

flipped_images = tf.image.flip_up_down(resized)

resized_encoded = tf.image.encode_jpeg(flipped_images,name="save_me")

init = tf.initialize_all_variables()
sess = tf.Session()

with sess.as_default():
  tf.train.start_queue_runners()
  sess.run(init)

  f = open("/tmp/foo1.jpeg", "wb+")
  f.write(resized_encoded.eval())
  f.close()

  f = open("/tmp/foo2.jpeg", "wb+")
  f.write(resized_encoded.eval())
  f.close()
Run Code Online (Sandbox Code Playgroud)

它工作正常,调整两个图像的大小并保存它们.但它始终以错误结束:

W tensorflow/core/common_runtime/executor.cc:1076] 0x7f97240e7a40
 Compute status: Out of range: Reached limit of 1
Run Code Online (Sandbox Code Playgroud)

我显然做错了什么.如果我取消num_epochs = 1,则结束时没有错误.

我有几个问题:

我该怎么做呢?

另外,如果我想从filename_queue到结尾保存原始文件名,那么我可以用原始名称保存它们,我该怎么做?我怎么知道需要保存多少文件?假设我正在通过读取目录来创建文件名列表.我尝试了许多不同的东西,但是当我到达终点时,我永远无法知道我是如何知道的.

我似乎很奇怪我正在调用resized_encoded.eval()两次.

谢谢,我确定这是一个非常基本的问题,但我不明白这是如何工作的.

编辑:我创建了一个更简单的行为演示:

import tensorflow as tf
import numpy as np

filenames = ['file1.png', 'file2.png' ]

filename_queue = tf.train.string_input_producer(filenames, 
                        num_epochs=1, name="my_file_q")

reader = tf.WholeFileReader()
key,value = reader.read(filename_queue)
init = tf.initialize_all_variables()

sess = tf.Session()

with sess.as_default():
  print("session started")

  sess.run(init)

  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(coord=coord)

  for i in range (2):
    print(key.eval())

  coord.request_stop()
  coord.join(threads)
Run Code Online (Sandbox Code Playgroud)

这给出了同样的警告.我不明白为什么.

jks*_*hin 8

这个警告是完全正常的.如TensorFlow API中所述

num_epochs:一个整数(可选).如果指定,string_input_producer会在生成OutOfRange错误之前从string_tensor num_epochs次生成每个字符串.如果未指定,string_input_producer可以循环遍历string_tensor中的字符串无限次.

你可能会问,为什么这很重要.在我看来,我已经将您的代码重构为可能更容易理解的内容.让我解释.

import tensorflow as tf
import numpy as np
import os
from PIL import Image

cur_dir = os.getcwd()
print("resizing images")
print("current directory:",cur_dir)

def modify_image(image):
    resized = tf.image.resize_images(image, 180, 180, 1)
    resized.set_shape([180,180,3])
    flipped_images = tf.image.flip_up_down(resized)
    return flipped_images

def read_image(filename_queue):
    reader = tf.WholeFileReader()
    key,value = reader.read(filename_queue)
    image = tf.image.decode_jpeg(value)
    return image

def inputs():
    filenames = ['img1.jpg', 'img2.jpg' ]
    filename_queue = tf.train.string_input_producer(filenames,num_epochs=2)
    read_input = read_image(filename_queue)
    reshaped_image = modify_image(read_input)
    return reshaped_image

with tf.Graph().as_default():
    image = inputs()
    init = tf.initialize_all_variables()
    sess = tf.Session()
    sess.run(init)
    tf.train.start_queue_runners(sess=sess)
    for i in xrange(2):
        img = sess.run(image)
        img = Image.fromarray(img, "RGB")
        img.save(os.path.join(cur_dir,"foo"+str(i)+".jpeg"))
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,如果你明确地输入num_epochs = 2,那么就像API建议的那样,string_input_producer循环遍历string_tensor中的字符串2次.由于string_tensor只有2个文件名,因此队列中填充了4个文件名.如果我将for循环更改为:

for i in xrange(5)
Run Code Online (Sandbox Code Playgroud)

然后这会出错.但是,如果我把它留在4,那就没关系了.再举一个例子.如果我没有放置num_epochs,那么按照建议,它可以循环无限次.把:

for i in xrange(100)
Run Code Online (Sandbox Code Playgroud)

因此不会出错.我希望这回答了你的问题.

编辑:我意识到你有更多的问题.

另外,如果我想从filename_queue到结尾保存原始文件名,那么我可以用原始名称保存它们,我该怎么做?我怎么知道需要保存多少文件?假设我正在通过读取目录来创建文件名列表.我尝试了许多不同的东西,但是当我到达终点时,我永远无法知道我是如何知道的.

如果要保留原始文件名,则方法需要返回文件名.这是下面的代码.

import tensorflow as tf
import numpy as np
import os
from PIL import Image

cur_dir = os.getcwd()
print("resizing images")
print("current directory:",cur_dir)

def modify_image(image):
    resized = tf.image.resize_images(image, 180, 180, 1)
    resized.set_shape([180,180,3])
    flipped_images = tf.image.flip_up_down(resized)
    return flipped_images

def read_image(filename_queue):
    reader = tf.WholeFileReader()
    key,value = reader.read(filename_queue)
    image = tf.image.decode_jpeg(value)
    return key,image

def inputs():
    filenames = ['img1.jpg', 'img2.jpg' ]
    filename_queue = tf.train.string_input_producer(filenames)
    filename,read_input = read_image(filename_queue)
    reshaped_image = modify_image(read_input)
    return filename,reshaped_image

with tf.Graph().as_default():
    image = inputs()
    init = tf.initialize_all_variables()
    sess = tf.Session()
    sess.run(init)
    tf.train.start_queue_runners(sess=sess)
    for i in xrange(10):
        filename,img = sess.run(image)
        print (filename)
        img = Image.fromarray(img, "RGB")
        img.save(os.path.join(cur_dir,"foo"+str(i)+".jpeg"))
Run Code Online (Sandbox Code Playgroud)

要知道需要保存多少文件,您可以按以下方式调用:

os.listdir(os.getcwd())
Run Code Online (Sandbox Code Playgroud)

这将列出目录中的所有文件.检查os.listdir的API以专门过滤JPG,PNG文件类型.一旦你得到这个,你可以调用一个简单的长度操作,并执行:

for i in xrange(len(number_of_elements))
Run Code Online (Sandbox Code Playgroud)