一、需求
论文《EyeTracking for everyone》中提出了iTracker神经网络,并构建了一个叫GazeCapture的数据库,将其部分数据集下载后,可以看到文件的层次结构如下图所示:
其中,整个数据集的后缀名是npz,内部文件的后缀名是npy。由于该数据集是面向Apple产品系列的,而我的目标是面向笔记本电脑的,需要根据要求制作自己的数据集,这就涉及到如何去制作npz和npy格式的文件。
二、npz文件和npy文件
首先需要了解,在深度学习的数据集格式中,常用的有csv、json、npy、npz格式等等。并且npy和npz文件的内存大小在这几种中相对来说,也是比较小的。
2.1 npz和npy的区别
npy是将numpy生成的数组保存为二进制格式数据,主要用来保存单个np.array数组;npz将多个数组保存到一个文件,且保存为二进制格式,可视为多个npy文件的打包。正如上图所示。
2.2 如何制作npy文件
制作npy文件的程序如下所示:
// 打开一张图片,并转换为np数组
raw_image=Image.open("face_scipy.jpg")
image_array=np.array(raw_image)
// 将图像数据数组保存到npy文件中去
np.save('test.npy',image_array)
上面这段程序,可以实现将一张图片的数据保存到npy文件中
2.3 如何制作npz文件
关键程序如下所示:
// 以a~j表示要存放到不同npy文件中的np数组,当然实际过程中是图像数组
a=np.arange(3)
b=np.arange(4)
c=np.arange(5)
d=np.arange(6)
e=np.arange(7)
f=np.arange(3)
g=np.arange(4)
h=np.arange(5)
i=np.arange(6)
j=np.arange(7)
// 保存为npz文件
np.savez('train_and_val.npz', train_face=a,train_eye_left=b, train_eye_right=c, train_face_mask=d, train_y=e
, val_face=f, val_eye_left=g, val_eye_right=h, val_face_mask=i, val_y=j);
// 读取npz文件,输出其中的文件
data=np.load('train_and_val.npz')
print(data.files)
执行上述程序,就会在指定路径中生成“train_and_val.npz”文件,其中的层次结构如下图所示:
与原始数据集保持一致。
对上述生成npz文件的程序作一些修改,其余不动,即将一张人脸图像数据保存到train_face.npy中。
raw_image=Image.open("face_scipy.jpg")
a=np.array(raw_image)
三、如何将多张图片读取到np数组?
尽管在上面,我们已经实现了将一张图片的数据保存到.npy和.npz文件中,但是实际过程中,不可能只有一张图片,因此需要探讨如何将大量图片批量保存到numpy数组中。
以下载的GazeCapture数据集为例,利用下面的程序即可查看train_face.npy文件中的数据信息。
import numpy as np
face_data=np.load('C:/Users/Lenovo/Desktop/eye_tracker_train_and_val.npz')
// 查看数据类型
print(type(face_data['train_face']))
// 查看数组元素数据类型
print((face_data['train_face']).dtype)
// 查看数组元素总数
print((face_data['train_face']).size)
// 查看数组shape
print((face_data['train_face']).shape)
// 查看数组的维度信息
print((face_data['train_face']).ndim)
在控制台输出的结果如下:
<class 'numpy.ndarray'>
uint8
589824000
(48000, 64, 64, 3)
4
其中,(48000, 64, 64, 3)说明该文件是由48000张64×64的3通道彩色图像构成,并且48000×64×64×3=58982400个元素。
那么,如何制作具有类似的shape的npy文件呢?
3.1 查看指令路径中的所有文件
代码如下:
import os
def getAllImages(folder):
assert os.path.exists(folder)
assert os.path.isdir(folder)
imageList = os.listdir(folder)
imageList = [os.path.abspath(item) for item in imageList if os.path.isfile(os.path.join(folder, item))]
return imageList
// 调动函数打印指定路径下的所有文件
print(getAllImages(r"C:\Users\Lenovo\Desktop\Eyetracking for everyone程序\我的调试"))
控制台结果如下图所示:
3.2 查看指令路径中具有指令后缀名的文件
代码如下:
// 此函数返回指令路径path下后缀名为.jpg文件的所有路径
def get_imlist(path):
return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')]
// 调用函数打印所有jpg图像的完整路径
print(get_imlist(r"C:\Users\Lenovo\Desktop\Eyetracking for everyone程序\我的调试"))
// 获取.jpg文件的数量
print(len(get_imlist(r"C:\Users\Lenovo\Desktop\Eyetracking for everyone程序\我的调试")))
控制台输出结果如下图所示:
3.3 将所有图片数据保存到一个4位数组中
首先准备一些图片,从数据集保存20张图片到指定文件夹,程序如下:
path='C:/Users/Lenovo/Desktop/eye_tracker_train_and_val.npz'
data=np.load(path)
for i in range(20):
im = Image.fromarray(data['train_face'][i])
im.show()
# 根据i的值格式化字符串
im.save("C:\\Users\Lenovo\Desktop\Eyetracking for everyone程序\我的调试\样本图片\%s.png" % i)
结果如下:
利用下面的程序,即可将所有图片数据转化为数组,并存放到1个四维数组中。
def get_imlist(path):
return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.png')]
filename=get_imlist(r"C:\Users\Lenovo\Desktop\Eyetracking for everyone程序\我的调试\样本图片");
# png图像文件的数量
d=len(filename)
# 创建一个4维的空数组,可以容纳d张64*64的三通道图像数据
data=numpy.empty((d,64,64,3),dtype=numpy.uint8)
while d>0:
# filename是存放指定路径下所有文件完整路径字符串的一维数组
# 从0开始索引,一开始读取最后一张图片
img=Image.open(filename[d-1])
# 将图片转化为数组
img_ndarray=numpy.array(img)
#print(img_ndarray.shape)
# 将第d-1张图片的数据给data的第d-1个,达到一一对应的关系
data[d-1]=img_ndarray
# 下一张
d=d-1
print ("data.shape:",data.shape)
并且在控制台输入如下结果,经过验证,data中的数据与原始数据集中的数据保持一致。
data.shape: (20, 64, 64, 3)
3.4 将四维数组保存为npz文件
得到一个保存所有图像数据的四维数组后,即可转换为npz文件。
numpy.savez('train_and_val.npz', train_face=data);
并且可以利用下面的程序加载保存的npz文件,并且查看图片:
data_new=numpy.load('train_and_val.npz');
img=Image.fromarray(data_new['train_face'][0]);
img.show()
至此,如何批量读取自制的样本图片,并且保存为npz文件的过程就结束啦!!!
懒得复制,需要源码的我把下载链接挂在这里了:
* 程序