Python Tensorflow:如何编码和读取bmp图像?

Python Tensorflow:如何编码和读取bmp图像?,python,image,tensorflow,bmp,Python,Image,Tensorflow,Bmp,我正在尝试读取.bmp图像,对这些图像进行一些增强,将它们保存到.tfrecords文件中,然后打开.tfrecords文件并使用这些图像进行图像分类。我知道有一个tf.image.encode_jpeg()和一个tf.image.encode_png()函数,但没有tf.image.encode_bmp()函数。我知道.bmp图像是未压缩的,所以我尝试简单地对图像进行base64编码,np.tostring()和np.tobytes(),但在尝试解码这些格式时,我遇到以下错误: tensorf

我正在尝试读取.bmp图像,对这些图像进行一些增强,将它们保存到.tfrecords文件中,然后打开.tfrecords文件并使用这些图像进行图像分类。我知道有一个tf.image.encode_jpeg()和一个tf.image.encode_png()函数,但没有tf.image.encode_bmp()函数。我知道.bmp图像是未压缩的,所以我尝试简单地对图像进行base64编码,np.tostring()和np.tobytes(),但在尝试解码这些格式时,我遇到以下错误:

tensorflow.python.framework.errors\u impl.InvalidArgumentError:channels属性3与文件中的每像素位不匹配

我的观点是tensorflow在编码为jpeg或png时,对图像的字节编码做了额外的处理;保存有关数组维度等的信息。但是,我对此一无所知,所以任何帮助都将是非常好的

一些代码显示了我试图实现的目标:

with tf.gfile.FastGFile(filename, 'rb') as f:
    image_data = f.read()
    bmp_data = tf.placeholder(dtype=tf.string)
    decode_bmp = tf.image.decode_bmp(self._decode_bmp_data, channels=3)
    augmented_bmp = <do some augmentation on decode_bmp>
    sess = tf.Session()
    np_img = sess.run(augmented_bmp, feed_dict={bmp_data: image_data})
    byte_img = np_img.tostring()

    # Write byte_img to file using tf.train.Example
    writer = tf.python_io.TFRecordWriter(<output_tfrecords_filename>)
    example = tf.train.Example(features=tf.train.Features(feature={
        'encoded_img': tf.train.Feature(bytes_list=tf.train.BytesList(value=[byte_img])}))
    writer.write(example.SerializeToString())

    # Read img from file
    dataset = tf.data.TFRecordDataset(<img_file>)
    dataset = dataset.map(parse_img_fn)
在你的评论中,你肯定是指编码而不是加密

BMP非常简单,由一堆标题和几乎原始的像素数据组成。这就是为什么BMP图像如此之大。我想这也是为什么TensorFlow开发人员没有费心编写一个函数来将数组(表示图像)编码成这种格式的原因。很少有人还在使用它。建议改用PNG,它可以对图像进行无损压缩。或者,如果您可以处理有损压缩,请使用JPG

TensorFlow对图像编码没有任何特殊功能。它只返回以该格式表示图像的字节,类似于matplotlib在执行
save_fig
时所做的操作(除了MPL还将字节写入文件)

假设您生成一个numpy数组,其中顶行为0,底行为255。这是一个数字数组,如果你认为它是一幅图片,它将代表两个水平带,顶部一个黑色,底部一个白色

如果您希望在另一个程序(GIMP)中看到此图片,则需要以标准格式(如PNG)对此信息进行编码。编码意味着添加一些头和元数据,还可以选择压缩数据


现在有点清楚了什么是编码,我建议您使用PNG图像

with tf.gfile.FastGFile('image.png', 'rb') as f:
    # get the bytes representing the image
    # this is a 1D array (string) which includes header and stuff
    raw_png = f.read()

    # decode the raw representation into an array
    # so we have 2D array representing the image (3D if colour) 
    image = tf.image.decode_png(raw_png)

    # augment the image using e.g.
    augmented_img = tf.image.random_brightness(image)

    # convert the array back into a compressed representation
    # by encoding it into png
    # we now end up with a string again
    augmented_png = tf.image.encode_png(augmented_img, compression=9) 

    # Write augmented_png to file using tf.train.Example
    writer = tf.python_io.TFRecordWriter(<output_tfrecords_filename>)
    example = tf.train.Example(features=tf.train.Features(feature={
        'encoded_img': tf.train.Feature(bytes_list=tf.train.BytesList(value=[augmented_png])}))
    writer.write(example.SerializeToString())

    # Read img from file
    dataset = tf.data.TFRecordDataset(<img_file>)
    dataset = dataset.map(parse_img_fn)
将tf.gfile.FastGFile('image.png','rb')作为f:
#获取表示图像的字节
#这是一个1D数组(字符串),其中包括标题和内容
原始png=f.read()
#将原始表示解码为数组
#因此,我们有代表图像的2D数组(3D if颜色)
image=tf.image.decode\u png(原始png)
#使用例如。
增强图像=tf.图像.随机亮度(图像)
#将数组转换回压缩表示形式
#通过将其编码为png
#现在我们又以一个字符串结束
增强png=tf.image.encode\u png(增强img,压缩=9)
#使用tf.train.Example将增强的_png写入文件
writer=tf.python\u io.TFRecordWriter()
示例=tf.train.example(特征=tf.train.features(特征={
'encoded_img':tf.train.Feature(bytes_list=tf.train.BytesList(value=[augmented_png]))
writer.write(示例.SerializeToString())
#从文件中读取img
dataset=tf.data.TFRecordDataset()
dataset=dataset.map(parse\u img\u fn)
这里有几条重要的建议:

  • 不要使用
    numpy.tostring
    。这将返回HUUGE表示,因为每个像素都表示为浮点,并且它们都是串联的。没有压缩,没有任何内容。请尝试检查文件大小:)

  • 不需要通过使用tf.Session返回python。您可以在TF侧执行所有操作。这样您就有了一个输入图,可以将其作为输入管道的一部分重用


tensorflow主软件包中没有encode\u bmp,但是如果您导入tensorflow\u io(也是Google官方支持的软件包),您可以在那里找到encode\u bmp方法

有关文档,请参阅:

问题似乎只是关于编码bmp图像,因为您知道如何读取它们。将其编码为bmp的用例是什么?为什么不使用png呢?很好!我不知道png是一种非破坏性的压缩算法,所以我尝试修复bmp加密。我会用png来代替,谢谢!无论如何,我仍然想知道tensorflow是如何加密图像的,以及是否有可能加密bmp图像。这将是一个很好的机会来学习如何在引擎盖下工作!
with tf.gfile.FastGFile('image.png', 'rb') as f:
    # get the bytes representing the image
    # this is a 1D array (string) which includes header and stuff
    raw_png = f.read()

    # decode the raw representation into an array
    # so we have 2D array representing the image (3D if colour) 
    image = tf.image.decode_png(raw_png)

    # augment the image using e.g.
    augmented_img = tf.image.random_brightness(image)

    # convert the array back into a compressed representation
    # by encoding it into png
    # we now end up with a string again
    augmented_png = tf.image.encode_png(augmented_img, compression=9) 

    # Write augmented_png to file using tf.train.Example
    writer = tf.python_io.TFRecordWriter(<output_tfrecords_filename>)
    example = tf.train.Example(features=tf.train.Features(feature={
        'encoded_img': tf.train.Feature(bytes_list=tf.train.BytesList(value=[augmented_png])}))
    writer.write(example.SerializeToString())

    # Read img from file
    dataset = tf.data.TFRecordDataset(<img_file>)
    dataset = dataset.map(parse_img_fn)