背景

获取到cifar10数据后 希望将数据还原成图片 方便观看并且可进行进一步处理 cifar10数据格式介绍可参看:cifar10 数据格式介绍 本文将介绍1.通过tensorflow解析binary格式数据 2.解析python格式数据


目录

  • 背景
  • binary格式数据解析
  • python 格式数据解析

binary格式数据解析

参考:

数据是手动下载的 gitlab上下载的cifar10文件中已经没有了maybe_download_and_extract() 下载地址可以参见【cifar10 数据格式介绍】速度还是挺快的

具体的解释 在参考链接中有详细说明 不再解释了 要注意的是使用这种方法 需要下载的是binary格式的数据 千万不要下载错了~~~

import os
import tensorflow as tf
from scipy import misc as sm

    
def check_cifar10_data_files(filenames):
    for file in filenames:
        if os.path.exists(file) == False:
            print("not found cifar10 data",file)
            return False
    return True

def get_record(queue):
    print("get record")
    #计算样本大小
    label_bytes = 1
    width = 32
    height = 32
    depth = 3
    #图像大小3*32*32=3072
    image_bytes = width*height*depth
    
    #一张图像数据总量 1+3072=3073
    record_bytes = label_bytes + image_bytes
    
    #根据样本大小读取数据
    reader = tf.FixedLengthRecordReader(record_bytes)
    key,value = reader.read(queue)
    
    record_bytes = tf.decode_raw(value, tf.uint8)
    
    #第一个字节为标签
    label_data = tf.cast(tf.strided_slice(record_bytes,[0],[label_bytes]), tf.int32)
    
    depth_major = tf.reshape(tf.strided_slice(record_bytes,[label_bytes],[label_bytes+image_bytes]),[3,32,32])
    image_data = tf.transpose(depth_major,[1,2,0])
    return label_data,image_data

def get_image(dpath):
    filenames = [os.path.join(dpath,"data_batch_%d.bin"% i) for i in range(2,3)]
    print(filenames)
    if check_cifar10_data_files(filenames) == False:
        print("err")
        return
    queue = tf.train.string_input_producer(filenames,shuffle=False)
    return get_record(queue)

if __name__=='__main__':
    img_save_path = './cifar10_image/'
    if os.path.exists(img_save_path) == False:
        os.mkdir(img_save_path)
        
    key,value = get_image('./cifar10_bdata/')
    
    
    with tf.Session() as sess:
        #init
        sess.run(tf.global_variables_initializer())
        coord = tf.train.Coordinator()
        
        threads = tf.train.start_queue_runners(sess=sess,coord=coord)
        
        for i in range(50):
            label,data = sess.run([key,value])
            print(label)
            sm.toimage(data).save(img_save_path+'%d_%d.jpg'%(label,i))
        coord.request_stop()
        coord.join()

生成图像的效果:

根据图片生成关键词 PYTHON python根据数据生成图像_cifar10

python 格式数据解析

解析python格式的数据要简单很多 这里我们将解析所有的数据 并且根据标签存储 在cifar10 数据格式介绍中已经说到了只需要使用

def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict

就可以得到一个包含data,labels的字典

根据这个字典我们就可以作分析 并生成图像了 具体步骤如下:

  1. 首先加载数据 分别获取图像数据 以及标签数据
## 解析图像数据 返回图像数据及图像标签
def load_cifar_batch(filename):
    import pickle
    with open(filename,'rb') as fo:
        dic = pickle.load(fo,encoding='latin1')
        X = dic['data']
        Y = dic['labels']
        X = X.reshape(10000,3,32,32)
        Y = np.array(Y)
        return X,Y
  1. 检查图像存储路径 生成对应文件夹
def checkimgpath(path):
    pathlist = [path+"%d/"%i for i in range(10)]
    for p in pathlist:
        if os.path.exists(p)==False:
            os.mkdir(p)

其实可以读取batches.meta文件获取具体类别的名称 这里略过了 只生成了0-9的标签文件夹

  1. 获取图像数据后遍历每一张图 生成图像 每份数据中包含有10000份图像数据
for i in range(10000):
	#获取第i张图像
    imgs = imgX[i]
            
    #三个通道分别代表了R G B
    img0 = imgs[0]
    img1 = imgs[1]
    img2 = imgs[2]
    r = Image.fromarray(img0)
    g = Image.fromarray(img1)
    b = Image.fromarray(img2)
            
    #获取第i张图像的标签
    label = imgY[i]
            
    #合并三通道生成RGB图像
    img = Image.merge("RGB",(r,g,b))
            
   #记录这一类别的图像数目
   num = imgfile[label]
   imgfile[label]+=1
   name = "img"+str(num)+".jpg"
            
   #将图像保存至相应类别的文件夹
   img.save(imgpath+"%d/%s"%(label,name))

完整代码如下:

import numpy as np
import os
from PIL import Image
    
## 解析图像数据 返回图像数据及图像标签
def load_cifar_batch(filename):
    import pickle
    with open(filename,'rb') as fo:
        dic = pickle.load(fo,encoding='latin1')
        X = dic['data']
        Y = dic['labels']
        X = X.reshape(10000,3,32,32)
        Y = np.array(Y)
        return X,Y

imgfile = {i:0 for i in range(10)}
def checkimgpath(path):
    pathlist = [path+"%d/"%i for i in range(10)]
    for p in pathlist:
        if os.path.exists(p)==False:
            os.mkdir(p)
            
if __name__ == "__main__":
    # 图像保存路径
    imgpath = './cifar10_images_py/'
    # 生成图像分类文件夹 (可以读取batches.meta文件获取具体类别的名称 这里略过了)
    checkimgpath(imgpath)
    datapath = './cifar10_data/'
    filelist = [(datapath+'data_batch_%d'%i) for i in range(1,6)]
    print (filelist)
    
    for file in filelist:
        imgX,imgY = load_cifar_batch(file)
        
        for i in range(10000):
            #获取第i张图像
            imgs = imgX[i]
            
            #三个通道分别代表了R G B
            img0 = imgs[0]
            img1 = imgs[1]
            img2 = imgs[2]
            r = Image.fromarray(img0)
            g = Image.fromarray(img1)
            b = Image.fromarray(img2)
            
            #获取第i张图像的标签
            label = imgY[i]
            
            #合并三通道生成RGB图像
            img = Image.merge("RGB",(r,g,b))
            
            #记录这一类别的图像数目
            num = imgfile[label]
            imgfile[label]+=1
            name = "img"+str(num)+".jpg"
            
            #将图像保存至相应类别的文件夹
            img.save(imgpath+"%d/%s"%(label,name))

解析结果如下:

共有十种分类 每种图片5000张

根据图片生成关键词 PYTHON python根据数据生成图像_cifar10_02

根据图片生成关键词 PYTHON python根据数据生成图像_根据图片生成关键词 PYTHON_03

根据图片生成关键词 PYTHON python根据数据生成图像_cifar10_04