用于 PNG、GIF 等的 Tensorflow Label_Image

Posted

技术标签:

【中文标题】用于 PNG、GIF 等的 Tensorflow Label_Image【英文标题】:Tensorflow Label_Image for PNG, GIF etc 【发布时间】:2017-05-18 12:18:18 【问题描述】:

我正在使用 Tensorflow 进行图像分类。我使用 image_retraining/retrain.py 重新训练具有新类别的初始库,并使用它使用来自https://github.com/llSourcell/tensorflow_image_classifier/blob/master/src/label_image.py 的 label_image.py 对图像进行分类,如下所示:

import tensorflow as tf
import sys

# change this as you see fit
image_path = sys.argv[1]

# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
    in tf.gfile.GFile("/root/tf_files/output_labels.txt")]

# Unpersists graph from file
with tf.gfile.FastGFile("/root/tf_files/output_graph.pb", 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
# Feed the image_data as input to the graph and get first prediction
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')

    #predictions = sess.run(softmax_tensor,'DecodeJpeg/contents:0': image_data)
        predictions = sess.run(softmax_tensor,'DecodePng/contents:0': image_data)

# Sort to show labels of first prediction in order of confidence
    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]

    for node_id in top_k:
        human_string = label_lines[node_id]
        score = predictions[0][node_id]
        print('%s (score = %.5f)' % (human_string, score))

我注意到两个问题。当我用新类别重新训练时,它只训练 JPG 图像。我是机器学习的菜鸟,所以不确定这是否是一种限制,或者是否可以训练其他扩展图像,如 PNG、GIF?

另一个是在对图像进行分类时,输入再次仅适用于 JPG。我试图在上面的 label_image.py 中将 DecodeJpeg 更改为 DecodePng 但无法正常工作。我尝试的另一种方法是将其他格式转换为 JPG,然后再将它们传递给分类,例如:

im = Image.open('/root/Desktop/200_s.gif').convert('RGB')
im.save('/root/Desktop/test.jpg', "JPEG")
image_path1 = '/root/Desktop/test.jpg'

还有其他方法可以做到这一点吗? Tensorflow 是否具有处理除 JPG 以外的其他图像格式的功能?

与@mrry 建议的 JPEG 相比,我通过输入解析图像来尝试以下操作

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

# change this as you see fit
image_path = sys.argv[1]

# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()

image = Image.open(image_path)
image_array = np.array(image)[:,:,0:3]  # Select RGB channels only.

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
    in tf.gfile.GFile("/root/tf_files/output_labels.txt")]

# Unpersists graph from file
with tf.gfile.FastGFile("/root/tf_files/output_graph.pb", 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
# Feed the image_data as input to the graph and get first prediction
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')

        predictions = sess.run(softmax_tensor,'DecodeJpeg:0': image_array)

# Sort to show labels of first prediction in order of confidence
    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]

    for node_id in top_k:
        human_string = label_lines[node_id]
        score = predictions[0][node_id]
        print('%s (score = %.5f)' % (human_string, score))

它适用于 JPEG 图像,但是当我使用 PNG 或 GIF 时它会抛出

        Traceback (most recent call last):   
    File "label_image.py", line 17, in <module>
        image_array = np.array(image)[:,:,0:3]  # Select RGB channels only. 
IndexError: too many indices for array

【问题讨论】:

关于IndexError,错误信息提示image没有三个维度。如果你做print(np.array(image).shape),你会得到什么?你可以试试np.asarray(image) 吗? @mrry 现在可以让它工作了。做了一个 image.convert('RGB') 并随后输入数组。现在可以使用 JPG、PNG 和 GIF。 【参考方案1】:

该模型只能在 JPEG 图像上进行训练(和评估),因为您保存在 /root/tf_files/output_graph.pb 中的 GraphDef 仅包含一个 tf.image.decode_jpeg() 操作,并使用该操作的输出进行预测。使用其他图像格式至少有两种选择:

    输入解析的图像而不是 JPEG 数据。 在当前程序中,您输入一个 JPEG 编码的图像作为张量 "DecodeJpeg/contents:0" 的字符串值。相反,您可以为张量"DecodeJpeg:0"(表示tf.image.decode_jpeg() 操作的输出)输入解码图像数据的 3-D 数组,并且可以使用 NumPy、PIL 或其他一些 Python 库来创建这个数组。

    重新映射tf.import_graph_def() 中的图像输入。 tf.import_graph_def() 函数使您可以通过重新映射单个张量值将两个不同的图形连接在一起。例如,您可以执行以下操作以向现有图形添加新的图像处理操作:

    image_string_input = tf.placeholder(tf.string)
    image_decoded = tf.image.decode_png(image_string_input)
    
    # Unpersists graph from file
    with tf.gfile.FastGFile("/root/tf_files/output_graph.pb", 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        softmax_tensor, = tf.import_graph_def(
            graph_def,
            input_map="DecodeJpeg:0": image_decoded,
            return_operations=["final_result:0"])
    
    with tf.Session() as sess:
        # Feed the image_data as input to the graph and get first prediction
        predictions = sess.run(softmax_tensor, image_string_input: image_data)
        # ...
    

【讨论】:

我尝试了您建议的第一种方法,方法是输入解析后的图像(引用在我的问题中更新)。它适用于 JPEG,但是当我使用 PNG 或 GIF 时,它会抛出“IndexError:数组索引过多”错误。我做错了吗? 您能否在问题中包含来自IndexError 的整个堆栈跟踪? 是的,已将整个堆栈跟踪包含在问题中。【参考方案2】:

你应该看看tf.image 包。它具有很好的解码/编码 JPEG、GIF 和 PNG 的功能。

【讨论】:

【参考方案3】:

按照@mrry 的建议输入解析的图像,将图像数据转换为数组并转换为 RGB,如下代码所述。现在我可以输入 JPG、PNG 和 GIF。

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

# change this as you see fit
image_path = sys.argv[1]

# Read in the image_data
image_data = tf.gfile.FastGFile(image_path, 'rb').read()

image = Image.open(image_path)
image_array = image.convert('RGB')

# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
    in tf.gfile.GFile("/root/tf_files/output_labels.txt")]

# Unpersists graph from file
with tf.gfile.FastGFile("/root/tf_files/output_graph.pb", 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
# Feed the image_data as input to the graph and get first prediction
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')

        predictions = sess.run(softmax_tensor,'DecodeJpeg:0': image_array)

# Sort to show labels of first prediction in order of confidence
    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]

    for node_id in top_k:
        human_string = label_lines[node_id]
        score = predictions[0][node_id]
        print('%s (score = %.5f)' % (human_string, score))

【讨论】:

我有一个问题:与top_k = predictions[0].argsort()[-len(predictions[0]):][::-1] 相关。如何获得最高的预测值? 简短的回答是,label_lines[top_k[0]]。谢谢!

以上是关于用于 PNG、GIF 等的 Tensorflow Label_Image的主要内容,如果未能解决你的问题,请参考以下文章

我的训练数据集中的隐藏文件使 tensorflow 返回“未知的图像文件格式。需要 JPEG、PNG、GIF、BMP 之一。”

gif,png,jpg的区别

phantomjs 输出文件大小:png v gif

PHP 载入图像 imagecreatefrom_gif_jpeg_png 系列函数

将多个png转换为gif作为R中的动画

如何将电影动漫等的“名场面”做成表情包?教你轻松一键制作GIF图