人脸关键点数据集 300W 数据整理

人脸关键点数据集 300W 数据整理

  • 由于300W 数据集里面的图片尺寸大小不一,而且关键点数据为 .pts 文件,这些使得进行神经网络学习的时候,数据集必须经过一定的处理,才能使用。
  • 现在,我将使用 python 程序,将里面的图片尺寸全都转化为 500 * 500,同时读取并修改 .pts 文件的人脸关键点数据,最后将图片数据和人脸关键点数据保存为 numpy.ndarray 类型。

一. 导入模块

  • 本次程序所使用的模块有:re, os, numpy, cv2, matplotlib
    import re
    import os
    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    

二. 获得 300W 目录下所有的文件

  • 获得 300W 目录下所有的文件
    # 注意文件目录
    file_path_indoor = "E:/300W/300W/01_Indoor/"
    file_path_outdoor = "E:/300W/300W/02_Outdoor/"
    # os.listdir() 可以获得指定的文件夹包含的文件或文件夹的名字的列表
    indoor_file = os.listdir(file_path_indoor)
    outdoor_file = os.listdir(file_path_outdoor)
    print(indoor_file[0:10], "\n", outdoor_file[0:10])   # 打印 "G:/300W/01_Indoor/" 以及 "G:/300W/02_Outdoor/" 各 10 个文件
    
  • 运行结果:
    ['indoor_001.png', 'indoor_001.pts', 'indoor_002.png', 'indoor_002.pts', 'indoor_003.png', 'indoor_003.pts', 'indoor_004.png', 'indoor_004.pts', 'indoor_005.png', 'indoor_005.pts'] 
    ['outdoor_001.png', 'outdoor_001.pts', 'outdoor_002.png', 'outdoor_002.pts', 'outdoor_003.png', 'outdoor_003.pts', 'outdoor_004.png', 'outdoor_004.pts', 'outdoor_005.png', 'outdoor_005.pts']
    

三. 建立相应 ndarray 数组来保存数据

  • 要保存的数据有,人脸图片数据,人脸关键关数据,图片的缩放比例等。
    image_size_h, image_size_w = 500, 500                                      # 用来保存图片的尺寸
    files_num = int(len(indoor_file)/2) + int(len(outdoor_file)/2)            # 用来保存所有的图片数量
    facial_keypoints = np.zeros([files_num, 68*2], dtype=np.float64)          # 用来保存人脸关键点数据
    facial_image = np.zeros([files_num, image_size_h, image_size_w, 3], dtype=np.uint8)            # 用来保存人脸图片数据          
    image_scale = np.zeros([files_num, 2], dtype=np.float64)                  # 用来保存图片的缩放比
    

四. 读取图片数据以及人脸关键点数据

  • 主要通过 正则表达式 来获得 .pts 文件名,然后进行数据获取
    count = 0   # 用来计数
    
    # 读取 "G:/300W/01_Indoor/" 里面的图片和人脸关键点数据
    for i in indoor_file:
        ret = re.match(r"(.\w+)\.pts", i)    # 使用正则表达式读取 .pts 文件
        if ret:
            # 读取 pts 点
            pts_file = file_path_indoor  + i
            with open(pts_file, "r") as f:
                pts_str = f.read()
            # 读取当中的关键点数据
            key_point = re.findall(r"\d+\.\d+", pts_str)
            # 将列表中的字符串转化为数字
            key_point = [float(x) for x in key_point]
            # 添加到 facial_keypoints
            facial_keypoints[count] = key_point
            
            # 读取图片文件
            image_file = file_path_indoor + ret.group(1) + ".png"
            # 打开图片
            image = cv.imread(image_file, cv.IMREAD_COLOR)
            # 获取图片长和宽
            image_h, image_w = image.shape[:2]
            # 改变图片尺寸
            image = cv.resize(image, (image_size_h, image_size_w))
            # 得到缩放比
            image_scale[count] = [image_h/image_size_h, image_w/image_size_w]
            # 添加到 facial_image
            facial_image[count] = image
            
            count += 1
    
    # 读取 "G:/300W/01_Outdoor/" 里面的图片和人脸关键点数据
    for i in outdoor_file:
        ret = re.match(r"(.\w+)\.pts", i)
        if ret:
            # 读取 pts 点
            pts_file = file_path_outdoor  + i
            with open(pts_file, "r") as f:
                pts_str = f.read()
            # 读取当中的关键点数据
            key_point = re.findall(r"\d+\.\d+", pts_str)
            # 将列表中的字符串转化为数字
            key_point = [float(x) for x in key_point]
            # 添加到 facial_keypoints
            facial_keypoints[count] = key_point
            
            # 读取图片文件
            image_file = file_path_outdoor + ret.group(1) + ".png"
            # 打开图片
            image = cv.imread(image_file, cv.IMREAD_COLOR)
            # 获取图片长和宽
            image_h, image_w = image.shape[:2]
            # 改变图片尺寸
            image = cv.resize(image, (image_size_h, image_size_w))
            # 得到缩放比
            image_scale[count] = [image_h/image_size_h, image_w/image_size_w]
            # 添加到 facial_image
            facial_image[count] = image
            
            count += 1
    

五. 对人脸关键点数据进行缩放

  • 由于我们改变了图片的尺寸那么,我们也要对人脸关键点数据进行缩放
    count = 0  # 用来计数
    
    for i in image_scale:
        facial_keypoint = facial_keypoints[count]        # 获取单个人脸关键点数据
        facial_keypoint[::2] = facial_keypoint[::2] / i[1] # 对人脸关键点数据的宽进行缩放
        facial_keypoint[1::2] = facial_keypoint[1::2] / i[0] # 对人脸关键点数据的长进行缩放
        count += 1
    

六. 效果查看

  • 目前,我们的数据处理已经全部完成了,接下来,使用 matplotlib 来看一下效果
    for j in range(10):    # 总共展示十张图片
        image = facial_image[j]    # 获取图片数据
        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)   # 由于 matplotlib 支持的是 rgb 色彩空间,所以我们需要将 bgr 转化为 rgb
        for i in range(0, 68):
            cv.circle(image, (int(facial_keypoints[j, 2*i]), int(facial_keypoints[j, 2*i+1])), 5, (255, 0, 0), -1)   # 进行打点
        plt.subplot(2, 5, j+1)
        plt.imshow(image)
    plt.show()
    
  • 运行结果:

六. 保存数据与载入

  • 获取数据之后,我们就可以对这些 ndarray 数组进行保存了。
    np.save("./facial_image.npy", facial_image)
    np.save("./facial_keypoints.npy", facial_keypoints)
    
  • 使用 np.save() 保存的数据,我们可以通过 np.load() 来载入。
    facial_image = np.load(r"./facial_image.npy")
    facial_keypoints = np.load(r"./facial_keypoints.npy")
    

七. 结语

  • 如果文中有写的不对的地方,请大家指正。联系方式:[email protected]
  • 本文到这就结束了,最后感谢大家的观看。

你可能感兴趣的:(python)