背景
获取到cifar10数据后 希望将数据还原成图片 方便观看并且可进行进一步处理
cifar10数据格式介绍可参看:cifar10 数据格式介绍
本文将介绍1.通过tensorflow解析binary格式数据 2.解析python格式数据
binary格式数据解析
参考:https://blog.youkuaiyun.com/rookie_wei/article/details/80187950
数据是手动下载的 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 数据格式介绍中已经说到了只需要使用
def unpickle(file):
import pickle
with open(file, 'rb') as fo:
dict = pickle.load(fo, encoding='bytes')
return dict
就可以得到一个包含data,labels的字典
根据这个字典我们就可以作分析 并生成图像了 具体步骤如下:
- 首先加载数据 分别获取图像数据 以及标签数据
## 解析图像数据 返回图像数据及图像标签
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
- 检查图像存储路径 生成对应文件夹
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的标签文件夹
- 获取图像数据后遍历每一张图 生成图像
每份数据中包含有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张
参考网址:
- https://blog.youkuaiyun.com/moyu123456789/article/details/83963973
- https://blog.youkuaiyun.com/maweifei/article/details/80720461
- https://blog.youkuaiyun.com/barry_j/article/details/79158292
- https://blog.youkuaiyun.com/zkt286468541/article/details/91878469
- https://blog.youkuaiyun.com/zkt286468541/article/details/91875469