[基于tensorflow的人脸检测] 基于神经网络的人脸检6——数据的存储与加载

    技术2022-07-13  74

    1.数据存储与加载方式

    2.数据的存储

    3.数据的加载

    正文:

    1.数据存储与加载方式

    这里将数据的存储与加载方式分为两种,一种是在tensorflow框架中,提供的统一格式——TFRecord。另外一种是直接利用数组的形式进行存储与加载。

    TFRecord数组
    2.数据的存储

    1)TFRecord

    TFRecord是一种文件的存储格式,通过将数据按照一定的格式生成 .tfrecords文件进行储存。 关键步骤如下。

    读取图片(三维)/标签→ 存储为四维数组/二维数组 → 将数组存为.tfrecords文件

    以下实现利用TFRecord存储十张图片以及标签。

    import tensorflow as tf import os import cv2 import numpy as np def get_int64(value): """获取整型属性""" return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) def get_bytes(value): """获取字符串属性""" return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) #--------第一/二步————读取图片/标签并存储为数组 #从txt文件中读取十张图片和标签 image_txt = 'train_images.txt' label_txt = 'train_labels.txt' #神经网络输入维度 input_h = 224 input_w = 224 input_c = 3 #获取10张照片 number = 10 #初始化数组 images = np.zeros((number,input_h,input_w,input_c),dtype='uint8') labels = np.zeros((number,2),dtype='uint8') #每个标签维度为1*2 #把图片存入数组 image_root_path = r"C:\Users\user\Desktop\wider_data" with open(image_txt) as obj1: i = 0 for l1 in obj1.readlines()[:10]: image_name = l1.strip('\n') all_path = os.path.join(image_root_path, image_name) #图片根目录 iamge_data = cv2.imread(all_path, 1) image = cv2.resize(iamge_data, (input_h, input_w)) images[i] = image i += 1 #把标签存入数组 with open(label_txt) as obj2: i = 0 for l2 in obj2.readlines()[:10]: label_str = l2.strip('\n') #'[0, 1]' (第一位数在第二位,第二位数在第五位) label_array = (float(label_str[1]), float(label_str[4])) labels[i] = label_array i += 1 #--------第三步————存储为.tfrecords格式 #输出文件名称 output_path = 'data.tfrecords' #写入器 writer = tf.io.TFRecordWriter(output_path) for i in range(number): image_str = images[i].tostring() #写入形式为字符串 将图片转为字符串 label = np.argmax(labels[i]) #取最大值下标 即正确答案 #以字典的结构生成样例 example = tf.train.Example(features=tf.train.Features(feature={ 'label': get_int64(label), 'image': get_bytes(image_str)})) #写入样例 writer.write(example.SerializeToString()) writer.close() #关闭写入器

    2)数组

    数组的存储方法很简单,对于图片存储而言,首先初始化一个数组,再把所有的图片数据存到大数组中。关键步骤如下:

    创建一个大数组(四维,第一维是图片数,其他三维是图片维度) → 读取图片(三维数组) → 把小数组储存到大数组中

    可以看出 ——TFRecord的存储方式比直接利用数组的存储方法只是多了一个存储为.tfrcords文件的步骤。具体来说,.tfrecords这个文件是tensorflow提供的一种文件格式,可以起到统一的作用,方便数据的存储和加载。以下实现直接利用数组存储。

    import cv2 import numpy as np import os def get_image_arrary(image_h, image_w, image_c): """输入参数:图片的三个维度(神经网络输入维度)""" #初始化列表 images = [] labels = [] root_path = r"C:\Users\user\Desktop\wider_data" #图片根目录 images_txt = 'train_images.txt' #图片地址文件 labels_txt = 'train_labels.txt' #对应的标签文件 with open(images_txt) as obj: for l in obj.readlines(): images.append(l.strip('\n')) with open(labels_txt) as obj2: for l in obj2.readlines(): labels.append(l.strip('\n')) sum_number = len(images) #创建数组 shape=(sum_number, image_h, image_w, image_c) images_array = np.zeros(shape,dtype='uint8') shape2 = (sum_number, 2) labels_array = np.zeros(shape2) for i in range(sum_number): #图片 path = images[i] all_path = os.path.join(root_path, path) image = cv2.imread(all_path, 1) image = cv2.resize(image, (image_h, image_w)) images_array[i] = image #标签 label_str = labels[i] #字符串列表 label_array = np.zeros((1,2), dtype=int) label_array = (float(label_str[1]), float(label_str[4])) labels_array[i] = label_array return images_array, labels_array
    3.数据的加载

    1)TFRecord

    TFRecord的文件读取要求与写入的格式一致。另外,由于图片在存储时以字符串的格式进行存储,所以读取出的图片也是字符串格式。在使用或者显示一张图片之前,需要将图片转为数组的形式。同时,读取出的图片维度为1xn,所以还需要将图片重塑为3维。下面是.tfrecords文件的读取。

    #tfrecords的加载 import tensorflow as tf import cv2 #创建读取器 reader = tf.TFRecordReader() #创建文件队列(管理文件,用于文件读取) filename_queue = tf.train.string_input_producer( ['data.tfrecords']) #读取一个样例 _,serialized_example = reader.read(filename_queue) #解析样例 格式需要与存储时一致 features = tf.parse_single_example( serialized_example, features = { 'label': tf.FixedLenFeature([], tf.int64), 'image': tf.FixedLenFeature([], tf.string) }) #将图像字符串转为数组 images = tf.decode_raw(features['image'], tf.uint8) labels = features['label'] sess = tf.compat.v1.Session() #创建会话 coord = tf.train.Coordinator() #生成 Coordinator 管理多线程 threads = tf.train.start_queue_runners(sess=sess,coord=coord) #读取结果展示 for i in range(10): image = sess.run(images) print(image.shape) #150528 = 224 x 224 x 3(存储时的维度) image = image.reshape(224,224,3) cv2.imshow(str(i), image) #展示 label = sess.run(labels) print(image, label)

    2)数组

    在存储数组时,只是将多个小的数组存储为一个大的数组。所以读取时只需要从大的数组中进行遍历。采用数组方法的缺点是,由于没有存储为类似.tfrecords的文件,所以数组的储存和读取其实是在同时进行的(也就是要读取必须先进行储存)。这样就会导致速度变慢,测试了将几万张图片进行储存为数组的情况下,大概需要花几分钟的时间。下面是数组的加载,采用随机加载一部分的方法进行加载,这样符合训练神经网络时的数据输入方法。

    import cv2 import numpy as np def get_batch(btch_size, images_array, labels_array, image_h, image_w, image_c): """得到一部分图片和标签""" #输入参数 一部分(batch)的大小,一部分的图片,一部分的标签,图片维度(h,w,c) lim = len(images_array) shape = (btch_size,image_h, image_w, image_c) shpae1 = (btch_size,2) batch_img_array = np.zeros(shape) batch_lab_array = np.zeros(shpae1) randoms = [] #避免重复 for i in range(btch_size): flag = True while flag: random = np.random.randint(lim) if random not in randoms: flag = False batch_img_array[i] = images_array[random] batch_lab_array[i] = labels_array[random] randoms.append(random) batch_lab_array = batch_lab_array.astype(np.float32) #类型转换 return batch_img_array, batch_lab_array

    结语: 如果对你有帮助,就给我一个赞吧,如何有问题,可以在评论区进行讨论。

    上一篇:[基于tensorflow的人脸检测] 基于神经网络的人脸检测5——神经网络的搭建 下一篇:[基于tensorflow的人脸检测] 基于神经网络的人脸检测7——神经网络的训练

    Processed: 0.018, SQL: 9