csv_to_numpy.py
from constants import CASC_PATH, SIZE_FACE, EMOTIONS, SAVE_DATASET_IMAGES_FILENAME, SAVE_DATASET_LABELS_FILENAME, SAVE_DIRECTORY, DATASET_CSV_FILENAME
import cv2
import pandas as pd
import numpy as np
from PIL import Image
from os.path import join
cascade_classifier = cv2.CascadeClassifier(CASC_PATH)
def format_image(image):
if len(image.shape) > 2 and image.shape[2] == 3:
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
else:
image = cv2.imdecode(image, cv2.CV_LOAD_IMAGE_GRAYSCALE)
gray_border = np.zeros((150, 150), np.uint8)
gray_border[:, :] = 200
gray_border[
int((150 / 2) - (SIZE_FACE / 2)): int((150 / 2) + (SIZE_FACE / 2)),
int((150 / 2) - (SIZE_FACE / 2)): int((150 / 2) + (SIZE_FACE / 2))
] = image
image = gray_border
faces = cascade_classifier.detectMultiScale(
image,
scaleFactor=1.3,
minNeighbors=5
)
# None is we don't found an image
if not len(faces) > 0:
return None
max_area_face = faces[0]
for face in faces:
if face[2] * face[3] > max_area_face[2] * max_area_face[3]:
max_area_face = face
# Chop image to face
face = max_area_face
image = image[face[1]:(face[1] + face[2]), face[0]:(face[0] + face[3])]
# Resize image to network size
try:
image = cv2.resize(image, (SIZE_FACE, SIZE_FACE),
interpolation=cv2.INTER_CUBIC) / 255.
except Exception:
print("[+] Problem during resize")
return None
return image
def emotion_to_vec(x):
d = np.zeros(len(EMOTIONS))
d[x] = 1.0
return d
def flip_image(image):
return cv2.flip(image, 1)
def data_to_image(data):
data_image = np.fromstring(
str(data), dtype=np.uint8, sep=' ').reshape((SIZE_FACE, SIZE_FACE)) #用字符串创建矩阵
data_image = Image.fromarray(data_image).convert('RGB') #numpy 转化为RGB 模式
data_image = np.array(data_image)[:, :, ::-1].copy() #BGR 模式
data_image = format_image(data_image)
return data_image
data = pd.read_csv(join(SAVE_DIRECTORY, DATASET_CSV_FILENAME))
labels = []
images = []
index = 1
total = data.shape[0]
for index, row in data.iterrows():
emotion = emotion_to_vec(row['emotion'])
image = data_to_image(row['pixels'])
if image is not None:
labels.append(emotion)
images.append(image)
# images.append(flip_image(image))
index += 1
print("Progress: {}/{} {:.2f}%".format(index, total, index * 100.0 / total))
print("Total: " + str(len(images)))
np.save(join(SAVE_DIRECTORY, SAVE_DATASET_IMAGES_FILENAME), images)
np.save(join(SAVE_DIRECTORY, SAVE_DATASET_LABELS_FILENAME), labels)
SAVE_DIRECTORY = './data/'
DATASET_CSV_FILENAME = 'fer2013.csv'
SAVE_DATASET_IMAGES_FILENAME = 'data_images.npy'
SAVE_DATASET_LABELS_FILENAME = 'data_labels.npy'
dataset_loader.py
from os.path import join
import numpy as np
from constants import *
import cv2
from sklearn.model_selection import train_test_split
class DatasetLoader:
def load_from_save(self):
images = np.load(join(SAVE_DIRECTORY, SAVE_DATASET_IMAGES_FILENAME))
images = images.reshape([-1, SIZE_FACE, SIZE_FACE, 1])
labels = np.load(join(SAVE_DIRECTORY, SAVE_DATASET_LABELS_FILENAME)).reshape([-1, len(EMOTIONS)])
self._images, self._images_test, self._labels, self._labels_test = train_test_split(images, labels, test_size=0.20, random_state=42)
@property # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
def images(self):
return self._images
@property
def labels(self):
return self._labels
@property
def images_test(self):
return self._images_test
@property
def labels_test(self):
return self._labels_test
参考:https://github.com/isseu/emotion-recognition-neural-networks