将csv转换为对应的灰度图

(听着好像有点多余,原本就是要把灰度图转为csv来读取。。)
代码:

import numpy as np
import os
from PIL import Image
import cv2
import matplotlib.pyplot as plt
from tqdm import tqdm
import pandas as pd
#from config import *
import dlib
#********************check over
# 目的是实现从csv到jpg的转换
# conver_csv_to_jpg是实现转换
# crop_face_area是实现ROI区域的提取


def convert_csv_to_jpg(csv_path):
    # 加载opencv的人脸识别文件
    # 'haarcascade_frontalface_alt' 的准确度更高,但是速度更慢
    # 'haarcascade_frontalface_default' 准确度较低,但是更快而且更轻巧
    # detector = cv2.CascadeClassifier(haarcascade_frontalface_alt)
    detector = dlib.get_frontal_face_detector()
    landmark_predictor = dlib.shape_predictor(
        'D:\\realsense_window\\CNN-Facial-Expression-Recognition-master\\data\\shape_predictor_68_face_landmarks.dat')

    # 将csv通过PIL转换为jpg
    data = pd.read_csv(csv_path, encoding="ISO-8859-1")

    train_path_data = {'path': [], 'emotion': []}
    valid_path_data = {'path': [], 'emotion': []}
    test_path_data = {'path': [], 'emotion': []}

    train_landmark = []
    valid_landmark = []
    test_landmark = []

    if not os.path.exists(TRAIN_DIR):
        os.mkdir(TRAIN_DIR)

    if not os.path.exists(TEST_DIR):
        os.mkdir(TEST_DIR)

    if not os.path.exists(VALID_DIR):
        os.mkdir(VALID_DIR)

    total = 0
    # 将cssv文件中的数据如emotion,pixel,usage打包成之后读取,同时需要处理多个数据的常用手段
    for label, pixels, usage in tqdm(zip(data['emotion'], data['pixels'], data['Usage'])):

        # 修改文件为指定大小
        img = np.asarray(pixels.split()).astype(
            np.int32).reshape([img_size, img_size])
        # 裁剪文件为所需要的人脸部分
        all_faces, all_landmarks = crop_face_area(
            detector, landmark_predictor, img, img_size)
        if all_faces is None:
            continue
        for img, landmarks in zip(all_faces, all_landmarks):
            # fromarray可以说明img此时为np的矩阵格式,Image中的fromarray这个函数实现从矩阵保存的像素值到照片的转换
            img = Image.fromarray(img).convert(mode='L')  # 转为单通道
            fname = str(total) + '.jpg'  # filename的格式
            # fer2013.csv中已经实现将各个csv文件的对应内容写好,包括pixel(与转换为照片有关),emotion(0-6对应于不同的情绪),usage对应于training,testing,validing
            if usage == 'Training':
                save_path = TRAIN_DIR + '\\' + fname  # 文件的保存路径
                train_path_data['path'].append(fname)
                train_path_data['emotion'].append(label)
                train_landmark.append(landmarks)
            elif usage == 'PrivateTest':
                save_path = VALID_DIR + '\\' + fname
                valid_path_data['path'].append(fname)
                valid_path_data['emotion'].append(label)
                valid_landmark.append(landmarks)
            else:
                save_path = TEST_DIR + '\\' + fname
                test_path_data['path'].append(fname)
                test_path_data['emotion'].append(label)
                test_landmark.append(landmarks)
            img.save(save_path)
            total += 1

    # 将train_landmark中的内容转为array格式,np.asarray(file,dtype=floatxx,ord)
    train_landmark = np.asarray(train_landmark)
    valid_landmark = np.asarray(valid_landmark)
    test_landmark = np.asarray(test_landmark)

    np.savez(TRAIN_LANDMARK_PATH, landmark=train_landmark)  # 生成npz的压缩文件
    np.savez(VALID_LANDMARK_PATH, landmark=valid_landmark)
    np.savez(TEST_LANDMARK_PATH, landmark=test_landmark)

    # dataframe是pandas的存储数据的方式,类似与matlab的矩阵和excel的表格,第一个参数与是用于存储的数据,可以是字符什么的,
    # 第二个数据index和第三个数据column分别代表行和列的标记,注意长度要和所给数据的行列大小一致
    # 例如df=pd.DataFrame([[1,2,3,4],[2,3,4,5],
    #              [3,4,5,6],[4,5,6,7]],
    #             index=list('ABCD'),columns=list('ABCD'))
    # df=
    '''A  B  C  D
    A  1  2  3  4
    B  2  3  4  5
    C  3  4  5  6
    D  4  5  6  7
    '''
    train_path_data = pd.DataFrame(train_path_data)
    train_path_data.to_pickle(TRAIN_PATH)
    valid_path_data = pd.DataFrame(valid_path_data)
    valid_path_data.to_pickle(VALID_PATH)
    test_path_data = pd.DataFrame(test_path_data)
    test_path_data.to_pickle(TEST_PATH)
    # 输出training,testing,validing中文件的个数
    print('Total: {}, training: {}, valid: {}, test: {}'.format(
        total, len(train_path_data), len(valid_path_data), len(test_path_data)))


def crop_face_area(detector, landmark_predictor, image, img_size):
    """
    裁剪图像的人脸部分,并resize到img_size尺寸

    :param detector:
    :param image:
    :param img_size:
    :return: Two numpy arrays containing the area and landmarks of all faces.
    None if no face was detected.
    """
    # p_img = Image.fromarray(image).convert(mode='RGB')
    # cv_img = cv2.cvtColor(np.asarray(p_img), cv2.COLOR_RGB2GRAY)
    # faces = detector.detectMultiScale(
    #     image=cv_img,
    #     scaleFactor=1.1,
    #     minNeighbors=1,
    #     minSize=(30, 30),
    #     flags=0
    # )
    # if len(faces) != 0:
    #     x, y, w, h = faces[0]
    #     cv_img = cv2.resize(cv_img[x:x + w, y:y + h], (img_size, img_size))
    #     return np.asarray(cv_img)
    # else:
    #     return None

    # 将image从np.array转化为RGB的照片的格式
    p_img = Image.fromarray(image).convert(mode='RGB')
    # 将P_img从RGB转为灰度图
    cv_img = cv2.cvtColor(np.asarray(p_img), cv2.COLOR_RGB2GRAY)
    # 检测灰度图cv_img中的人脸
    faces = detector(cv_img, 1)
    all_landmarks = []
    all_faces = []
    if len(faces) > 0:
        for face in faces:
            shape = landmark_predictor(cv_img, face)
            landmarks = np.ndarray(shape=[68, 2])
            for i in range(68):
                landmarks[i] = (shape.part(i).x, shape.part(i).y)
            all_landmarks.append(landmarks)
            x1, y1, x2, y2 = face.left(), face.top(), face.right(), face.bottom()
            # 裁剪照片多余的部分
            if x1 < 0:
                x1 = 0
            if x1 > cv_img.shape[1]:
                x1 = cv_img.shape[1]
            if x2 < 0:
                x2 = 0
            if x2 > cv_img.shape[1]:
                x2 = cv_img.shape[1]
            if y1 < 0:
                y1 = 0
            if y1 > cv_img.shape[0]:
                y1 = cv_img.shape[0]
            if y2 < 0:
                y2 = 0
            if y2 > cv_img.shape[0]:
                y2 = cv_img.shape[0]
            img = cv2.resize(cv_img[y1:y2, x1:x2], (img_size, img_size))
            all_faces.append(img)
        # 返回每张照片img中的人脸所在的位置
        return np.asarray(all_faces), np.asarray(all_landmarks)
    else:
        return None, None


'''
def count_lines(csv_path):
    data = pd.read_csv(csv_path, encoding="ISO-8859-1")
    return data.shape[0]
    #data.shape[0]代表csv文件中有多少行,也即有多少张照片
'''
'''
def show_class_distribution(file_path):
    label_num = np.zeros([7], dtype=np.int32)
    data = pd.read_csv(file_path)

    for label in data['emotion']:
        label_num[label] += 1  # get the name of emotions alreay-known

    rects = plt.bar(class_names, label_num)
    plt.title('Label Distribution')
    plt.xlabel("Label")
    plt.ylabel("Number")

    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2, height +
                 1, str(height), ha="center", va="bottom")
    plt.show()
'''

if __name__ == '__main__':
    DATA_PATH = 'D:\\2019-10-19\\csv\\fer2013_2.csv'
    convert_csv_to_jpg(DATA_PATH)
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值