import numpy as np
import cv2

import glob
import random
import numpy as np

emotions = ["neutral", "anger", "contempt", "disgust", "fear", "happy", "sadness", "surprise"] #Emotion list
LBPHF = cv2.face.LBPHFaceRecognizer_create() #Initialize fisher face classifier

data = {}

def get_files(emotion): #Define function to get file list, randomly shuffle it and split 80/20
    files = glob.glob("dataset\\%s\\*" %emotion)
    random.shuffle(files)
    training = files[:int(len(files)*0.8)] #get first 80% of file list
    prediction = files[-int(len(files)*0.2):] #get last 20% of file list
    return training, prediction

def make_sets():
    training_data = []
    training_labels = []
    prediction_data = []
    prediction_labels = []
    for emotion in emotions:
        training, prediction = get_files(emotion)
        #Append data to training and prediction list, and generate labels 0-7
        for item in training:
            image = cv2.imread(item) #open image
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) #convert to grayscale
            training_data.append(gray) #append image array to training data list
            training_labels.append(emotions.index(emotion))
    
        for item in prediction: #repeat above process for prediction set
            image = cv2.imread(item)
            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
            prediction_data.append(gray)
            prediction_labels.append(emotions.index(emotion))

    return training_data, training_labels, prediction_data, prediction_labels

def run_recognizer():
    training_data, training_labels, prediction_data, prediction_labels = make_sets()
    
    print ("training fisher face classifier")
    print ("size of training set is:", len(training_labels), "images")
    LBPHF.train(training_data, np.asarray(training_labels)) #train it

    print ("predicting classification set")
    cnt = 0
    correct = 0
    incorrect = 0
    for image in prediction_data:
        pred, conf = LBPHF.predict(image) #predict emotion
        if pred == prediction_labels[cnt]: #validate it
            correct += 1
            cnt += 1
        else:
            incorrect += 1
            cnt += 1
    return ((100*correct)/(correct + incorrect))

	
#Now run it
metascore = []
for i in range(0,15):
    correct = run_recognizer()
    print ("got", correct, "percent correct!")
    metascore.append(correct)

print ("\n\nend score:", np.mean(metascore), "percent correct!")

#Video part
cap = cv2.VideoCapture('./../widea/laughter_480.mkv') #open video

while(cap.isOpened()):
	ret, frame = cap.read() #read frame

	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #make it gray

	font = cv2.FONT_HERSHEY_SIMPLEX
	pred, conf = LBPHF.predict(gray) #predict emotion
	
	cv2.putText(gray,"emotion: " + emotions[pred],(200,50), font, 1, (200,255,155), 2, cv2.LINE_AA)
	
	cv2.imshow('frame',gray)
	
	if cv2.waitKey(25) & 0xFF == ord('q'): #load another frame after 25ms
		break

cap.release()
cv2.destroyAllWindows()