2016-01-14 87 views
9

我剛開始使用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() 

它工作正常,調整兩個圖像,並將其保存。但它總是以一個錯誤結束:

W tensorflow/core/common_runtime/executor.cc:1076] 0x7f97240e7a40 
Compute status: Out of range: Reached limit of 1 

我明顯做錯了事。如果我取消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) 

這給出了同樣的警告。我不明白爲什麼。

回答

5

這個警告是完全正常的。如TensorFlow API中所述

num_epochs: An integer (optional). If specified, string_input_producer produces each string from string_tensor num_epochs times before generating an OutOfRange error. If not specified, string_input_producer can cycle through the strings in string_tensor an unlimited number of times.

爲什麼這很重要,你可能會問。在我看來,我已經將你的代碼重構成了可能更容易理解的東西。讓我解釋。

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")) 

在上面的代碼,如果明確提出num_epochs = 2,則作爲API表明,通過string_tensor琴絃2倍string_input_producer週期。由於string_tensor只有2個文件名,隊列中有4個文件名。如果我將for循環更改爲:

for i in xrange(5) 

然後這會出錯。但是,如果我把它放在4,那麼它會沒事的。再舉一個例子。如果我不把num_epochs,那麼如所建議的那樣,它可以循環無限次數。推薦:

for i in xrange(100) 

因此不會出錯。我希望這回答了你的問題。

編輯:我意識到你有更多的問題。

Also, if I want to preserve the original file names all the way from the filename_queue through to the end so I can save them with the original names, how do I do that? And how do I know how many files I need to save? Let's say I'm making the list of file names by reading a directory. I tried many different things but I could never find out how I know when I reach the end.

如果您想保留原始文件名,那麼您的方法需要返回文件名。以下是代碼。

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")) 

要知道你需要多少文件保存,你可以只調用沿着線的東西:

os.listdir(os.getcwd()) 

此列出目錄中的所有文件。檢查os.listdir的API以過濾特定的JPG,PNG文件類型。一旦你得到這個,你可以調用一個簡單的長度操作,並做:

for i in xrange(len(number_of_elements))