制作自己的数据集之2 将图片存储为cifar的Python3数据格式 --- png图片存为类cifar10的二进制数据

参考链接:http://blog.****.net/zengxyuyu/article/details/53240463

备注:参考链接用python2.7,有少许错误,本文所用python3.5,已修改可用,小伙伴们注意按需取用哦~


前面用Python3 实现了cifar10数据的可视化,在cifar10里面取出来100张图片转化为png格式,上链接:
http://blog.****.net/f201113137051/article/details/79014627


现在如果我们想用tensorflow训练自己的图片,我们应该怎样把图片转成cifar数据集那种二进制并用字典的数据结构 datadict 存储的数据集呢?我们暂时用上篇博客从cifar数据集生成的图片输出作为这篇博客图片输入,图片数量100,是RGB彩色通道图像。


1.总览

这次用到的Python库或模块有:
(1) pillow:图像处理库,用来读个图像
(2) matplotlib:把从pillow读到的图像转化为数组
(3) numpy:处理一下数组,比如维度,合并数组
(4) pickle:pickle模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

pickle.dump(obj, file, [,protocol])
  注解:将对象obj保存到文件file中去。
pickle.load(file)
  注解:从file中读取一个字符串,并将它重构为原来的python对象。
  

2.步骤:

  (1) 将图片读出来
  (2)将图片转成数组
  (3) 处理一下数组,将所有图片合并为一个数组
  (4)用pickle序列化,存入文本
  

3.代码如下:

# -*- coding:utf-8 -*-
import pickle
from PIL import Image
import numpy as np
import os
import cv2
import matplotlib.image as plimg

class DictSave(object):
    def __init__(self,filenames):
        self.filenames = filenames
        self.arr = []
        self.all_arr = []
        print

    def image_input(self, filenames):
        for filename in filenames:
            self.arr = self.read_file(filename)
            if self.all_arr == []:
                self.all_arr = self.arr
            else:
                self.all_arr = np.concatenate((self.all_arr, self.arr))

    def read_file(self, filename):
        im = Image.open(filename) # 打开一个图像
         # 将图像的RGB分离
         r, g, b = im.split()
        # PILLOW图像转成数组
         r_arr = plimg.pil_to_array(r)
        g_arr = plimg.pil_to_array(g)
        b_arr = plimg.pil_to_array(b)
        # 32*32二位数组转成1024的一维数组
         r_arr1 = r_arr.reshape(1024)
        g_arr1 = g_arr.reshape(1024)
        b_arr1 = b_arr.reshape(1024)
        # 3个一维数组合并成一个一维数组,大小为3072
        arr = np.concatenate((r_arr1, g_arr1, b_arr1))
        return arr

    def pickle_save(self, arr):
        print("正在存储")
        # 构造字典,所有的图像数据都在arr数组里,我这里是个一维数组,目前并没有存label
        contact = {'data': arr}
        f = open('contact', 'wb+')###还有此处用wb+ ,原作者用的 w ,一直报错
        pickle.dump(contact, f) # 把字典存到文本中去
         f.close()
        print("存储完毕")

if __name__ == "__main__":
    # print(os.path.join("D:\\aa","img0"))
    # aa = cv2.imread(os.path.join("D:\\aa","img0")+".png")
    # #aa = cv2.imread("D:/aa/img0.png")
    # cv2.namedWindow("aa",0)
    # cv2.imshow("aa",aa)
    # cv2.waitKey(10000)    
# filenames = [os.path.join("D:\\aa",
# "img%d" % i) for i in range(0, 100)] #100个图像
#### 填坑,此处原作者有误,一直报错找不到img0文件,错误原因----亲,你获取图片路径时忘了.png 啦~~   修改如下:
 
filenames = []    
for i in range(0,100):        
    filename = [os.path.join("
data/cifar10_100/","img%d" % i)+".png"]
    print(filename)        
    filenames = filenames+filename    
    
print(filenames)    
ds = DictSave(filenames)    
ds.image_input(ds.filenames)    
ds.pickle_save(ds.all_arr)    
print("最终数组的大小:"+str(ds.all_arr.shape)) 

制作自己的数据集之2 将图片存储为cifar的Python3数据格式 --- png图片存为类cifar10的二进制数据

此处特别感谢帮我改代码的小熊师弟呀~~~