├── EvaluateEmotionDetector.py ├── TestEmotionDetector.py ├── TrainEmotionDetector.py ├── emotion_model.h5 ├── emotion_model.json └── haarcascade_frontalface_default.xml /EvaluateEmotionDetector.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | from keras.models import model_from_json 4 | import matplotlib.pyplot as plt 5 | from keras.preprocessing.image import ImageDataGenerator 6 | from sklearn.metrics import confusion_matrix, classification_report,ConfusionMatrixDisplay 7 | 8 | 9 | emotion_dict = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral", 5: "Sad", 6: "Surprised"} 10 | 11 | 12 | json_file = open('C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\model\\emotion_model.json', 'r') 13 | loaded_model_json = json_file.read() 14 | json_file.close() 15 | emotion_model = model_from_json(loaded_model_json) 16 | 17 | 18 | emotion_model.load_weights("C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\model\\emotion_model.h5") 19 | print("Loaded model from disk") 20 | 21 | 22 | test_data_gen = ImageDataGenerator(rescale=1./255) 23 | 24 | 25 | test_generator = test_data_gen.flow_from_directory( 26 | 'C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\data\\test', 27 | target_size=(48, 48), 28 | batch_size=64, 29 | color_mode="grayscale", 30 | class_mode='categorical') 31 | 32 | 33 | predictions = emotion_model.predict_generator(test_generator) 34 | 35 | 36 | 37 | print("-----------------------------------------------------------------") 38 | 39 | c_matrix = confusion_matrix(test_generator.classes, predictions.argmax(axis=1)) 40 | print(c_matrix) 41 | cm_display = ConfusionMatrixDisplay(confusion_matrix=c_matrix, display_labels=emotion_dict) 42 | cm_display.plot(cmap=plt.cm.Blues) 43 | plt.show() 44 | 45 | # Classification report 46 | print("-----------------------------------------------------------------") 47 | print(classification_report(test_generator.classes, predictions.argmax(axis=1))) 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /TestEmotionDetector.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | from keras.models import model_from_json 4 | 5 | 6 | emotion_dict = {0: "Angry", 1: "Disgusted", 2: "Fearful", 3: "Happy", 4: "Neutral", 5: "Sad", 6: "Surprised"} 7 | 8 | 9 | json_file = open('model/emotion_model.json', 'r') 10 | loaded_model_json = json_file.read() 11 | json_file.close() 12 | emotion_model = model_from_json(loaded_model_json) 13 | 14 | 15 | emotion_model.load_weights("model/emotion_model.h5") 16 | print("Loaded model from disk") 17 | 18 | 19 | cap = cv2.VideoCapture(0) 20 | 21 | 22 | #cap = cv2.VideoCapture("C:\\Users\slhem\\Downloads\\video (2160p).mp4") 23 | 24 | while True: 25 | 26 | ret, frame = cap.read() 27 | frame = cv2.resize(frame, (1280, 720)) 28 | if not ret: 29 | break 30 | face_detector = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml') 31 | gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 32 | 33 | 34 | num_faces = face_detector.detectMultiScale(gray_frame, scaleFactor=1.3, minNeighbors=5) 35 | 36 | 37 | for (x, y, w, h) in num_faces: 38 | cv2.rectangle(frame, (x, y-50), (x+w, y+h+10), (0, 255, 0), 4) 39 | roi_gray_frame = gray_frame[y:y + h, x:x + w] 40 | cropped_img = np.expand_dims(np.expand_dims(cv2.resize(roi_gray_frame, (48, 48)), -1), 0) 41 | 42 | 43 | emotion_prediction = emotion_model.predict(cropped_img) 44 | maxindex = int(np.argmax(emotion_prediction)) 45 | cv2.putText(frame, emotion_dict[maxindex], (x+5, y-20), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv2.LINE_AA) 46 | 47 | cv2.imshow('Emotion Detection', frame) 48 | if cv2.waitKey(1) & 0xFF == ord('q'): 49 | break 50 | 51 | cap.release() 52 | cv2.destroyAllWindows() 53 | -------------------------------------------------------------------------------- /TrainEmotionDetector.py: -------------------------------------------------------------------------------- 1 | 2 | import cv2 3 | from keras.models import Sequential 4 | from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten 5 | from keras.optimizers import Adam 6 | from keras.preprocessing.image import ImageDataGenerator 7 | 8 | 9 | train_data_gen = ImageDataGenerator(rescale=1./255) 10 | validation_data_gen = ImageDataGenerator(rescale=1./255) 11 | 12 | 13 | train_generator = train_data_gen.flow_from_directory( 14 | 'C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\data\\train', 15 | target_size=(48, 48), 16 | batch_size=64, 17 | color_mode="grayscale", 18 | class_mode='categorical') 19 | 20 | 21 | validation_generator = validation_data_gen.flow_from_directory( 22 | 'C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\data\\test', 23 | target_size=(48, 48), 24 | batch_size=64, 25 | color_mode="grayscale", 26 | class_mode='categorical') 27 | 28 | 29 | emotion_model = Sequential() 30 | 31 | emotion_model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(48, 48, 1))) 32 | emotion_model.add(Conv2D(64, kernel_size=(3, 3), activation='relu')) 33 | emotion_model.add(MaxPooling2D(pool_size=(2, 2))) 34 | emotion_model.add(Dropout(0.25)) 35 | 36 | emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu')) 37 | emotion_model.add(MaxPooling2D(pool_size=(2, 2))) 38 | emotion_model.add(Conv2D(128, kernel_size=(3, 3), activation='relu')) 39 | emotion_model.add(MaxPooling2D(pool_size=(2, 2))) 40 | emotion_model.add(Dropout(0.25)) 41 | 42 | emotion_model.add(Flatten()) 43 | emotion_model.add(Dense(1024, activation='relu')) 44 | emotion_model.add(Dropout(0.5)) 45 | emotion_model.add(Dense(7, activation='softmax')) 46 | 47 | cv2.ocl.setUseOpenCL(False) 48 | 49 | emotion_model.compile(loss='categorical_crossentropy', optimizer=Adam(lr=0.0001, decay=1e-6), metrics=['accuracy']) 50 | 51 | 52 | emotion_model_info = emotion_model.fit_generator( 53 | train_generator, 54 | steps_per_epoch=28709 // 64, 55 | epochs=50, 56 | validation_data=validation_generator, 57 | validation_steps=7178 // 64) 58 | 59 | 60 | model_json = emotion_model.to_json() 61 | with open("emotion_model.json", "w") as json_file: 62 | json_file.write(model_json) 63 | 64 | 65 | emotion_model.save_weights('C:\\Users\slhem\\Downloads\Emotion_detection_with_CNN(2)\Emotion_detection_with_CNN-main\model\\emotion_model.h5') 66 | 67 | -------------------------------------------------------------------------------- /emotion_model.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tharunkrish14/Emotion-detection-using-CNN-Algorithm/0fb55ae63ea446e87c6ef314814106d75a3169b8/emotion_model.h5 -------------------------------------------------------------------------------- /emotion_model.json: -------------------------------------------------------------------------------- 1 | {"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": [null, 48, 48, 1], "dtype": "float32", "sparse": false, "ragged": false, "name": "conv2d_input"}}, {"class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "batch_input_shape": [null, 48, 48, 1], "dtype": "float32", "filters": 32, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.25, "noise_shape": null, "seed": null}}, {"class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "valid", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.25, "noise_shape": null, "seed": null}}, {"class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 1024, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 7, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}]}, "keras_version": "2.4.0", "backend": "tensorflow"} --------------------------------------------------------------------------------