"""
# Import from libraries
"""
pip install google.colab
import cv2
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from google.colab.patches import cv2_imshow
import os
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten, BatchNormalization
path = '../input/rating-opencv-emotion-images/Images/train'
"""
# Training and testing bases
"""

training_generator = ImageDataGenerator(rescale=1./255,
                                         rotation_range=7,
                                         horizontal_flip=True,
                                         zoom_range=0.2)
training_dataset = training_generator.flow_from_directory('../input/rating-opencv-emotion-images/Images/train',
                                                              target_size = (48, 48),
                                                              batch_size = 16,
                                                              class_mode = 'categorical',
                                                              shuffle = True)
training_dataset.classes
training_dataset.class_indices
sns.countplot(x = training_dataset.classes)
folder_names = os.listdir(path)
print(folder_names)
def plot_examples(folder_names, selected_folder, path):    
    
    fig, axs = plt.subplots(1, 5, figsize=(25, 12))
    fig.subplots_adjust(hspace = .2, wspace=.2)
    axs = axs.ravel()
    file_names = os.listdir(path + '/' + selected_folder)
    for i in range(5):
        print(file_names[i])
        img = cv2.imread(path + '/' + selected_folder + '/' + file_names[i])
        axs[i].imshow(img)
        axs[i].set_xticklabels([])
        axs[i].set_yticklabels([])
        
plot_examples(folder_names,'Neutral', path)
plot_examples(folder_names,'Sad', path)
plot_examples(folder_names,'Surprise', path)
plot_examples(folder_names,'Fear', path)
plot_examples(folder_names,'Angry', path)
plot_examples(folder_names,'Disgust', path)
plot_examples(folder_names,'Happy', path)
test_generator = ImageDataGenerator(rescale=1./255)
test_dataset = test_generator.flow_from_directory('../input/rating-opencv-emotion-images/Images/validation',
                                                  target_size = (48, 48),
                                                  batch_size = 1,  
                                                  class_mode = 'categorical',
                                                  shuffle = False)
"""
# Construction and training of the neural network
"""
number_classes = 7
detectors_number = 32 
width, height = 48, 48
epochs = 50
network = Sequential()

network.add(Conv2D(filters=number_classes, kernel_size=(3,3), activation='relu', padding='same', input_shape=(width, height, 3)))
network.add(BatchNormalization())  
network.add(Conv2D(filters=number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(MaxPooling2D(pool_size=(2,2)))
network.add(Dropout(0.2))
                            
network.add(Conv2D(filters=2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(Conv2D(filters=2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(MaxPooling2D(pool_size=(2,2)))
network.add(Dropout(0.2))

network.add(Conv2D(filters=2*2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(Conv2D(filters=2*2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(MaxPooling2D(pool_size=(2,2)))
network.add(Dropout(0.2))

network.add(Conv2D(filters=2*2*2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(Conv2D(filters=2*2*2*number_classes, kernel_size=(3,3), activation='relu', padding='same'))
network.add(BatchNormalization())
network.add(MaxPooling2D(pool_size=(2,2)))
network.add(Dropout(0.2))

network.add(Flatten())

network.add(Dense(units=2 * number_classes, activation='relu'))
network.add(BatchNormalization())
network.add(Dropout(0.2))

network.add(Dense(units=2 * number_classes, activation='relu'))
network.add(BatchNormalization())
network.add(Dropout(0.2))

network.add(Dense(units=number_classes, activation='softmax'))
print(network.summary())
network.compile(optimizer='Adam', loss='categorical_crossentropy', metrics=['accuracy'])
network.fit(training_dataset, epochs=epochs)   
"""
# Neural network evaluation
"""
network.evaluate(test_dataset)
forecasts = network.predict(test_dataset)
forecasts
forecasts = np.argmax(forecasts, axis = 1)
forecasts
test_dataset.classes
from sklearn.metrics import accuracy_score
accuracy_score(test_dataset.classes, forecasts)
test_dataset.class_indices
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(test_dataset.classes, forecasts)
cm
sns.heatmap(cm, annot=True);
from sklearn.metrics import classification_report
print(classification_report(test_dataset.classes, forecasts))
"""
# Single image classification
"""
image = cv2.imread('../input/celebridades/Jennifer-Lawrence-2.jpg')
cv2_imshow(image)
image.shape
detector_face = cv2.CascadeClassifier('../input/casdadefrontal/haarcascade_frontalface_default.xml')
original_image = image.copy()
deteccoes = detector_face.detectMultiScale(original_image)
deteccoes
roi = image[60:280 + 120, 90:380 + 120]
cv2_imshow(roi)
roi.shape
roi = cv2.resize(roi, (48,48))
cv2_imshow(roi)
roi.shape
roi
roi = roi / 255
roi
roi.shape
roi = np.expand_dims(roi, axis = 0)
roi.shape
probs = network.predict(roi)
probs
forecasts = np.argmax(probs)
forecasts
test_dataset.class_indices
"""
# Classification¶ 2
"""
image = cv2.imread('../input/celebridades/17-impresionantes-datos-de-celebridades-que-te-de-2-19568-1493914661-8_dblbig.jpg')
cv2_imshow(image)
original_image = image.copy()
deteccoes = detector_face.detectMultiScale(original_image)
roi = image[30:200 + 100, 60:250 + 100]
cv2_imshow(roi)
roi = cv2.resize(roi, (48,48))
roi = roi / 255
roi = np.expand_dims(roi, axis = 0)
probs = network.predict(roi)
probs
forecasts = np.argmax(probs)
forecasts
"""
# Multiple image classification
"""
image = cv2.imread('../input/multiple/emocoes-trabalho.jpg')
cv2_imshow(image)
deteccoes = detector_face.detectMultiScale(image)
deteccoes
test_dataset.class_indices.keys()
emotions = ['Angry', 'Disgust', 'Fear', 'Happy', 'Neutral', 'Sad', 'Surprise']
for (x, y, w, h) in deteccoes:
 
  cv2.rectangle(image, (x, y), (x + w, y + h), (0,255,0), 1)
  roi = image[y:y + h, x:x + w]
 
  roi = cv2.resize(roi, (48,48))

  roi = roi / 255
  roi = np.expand_dims(roi, axis = 0)

  forecasts = network.predict(roi)
  
  cv2.putText(image, emotions[np.argmax(forecasts)], (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,255,0), 2, cv2.LINE_AA)
cv2_imshow(image)
"""
# **Conclusion**

**One of the great challenges of this database is that the attributes are very unbalanced, making us have to run more times in the training of the algorithm.**
"""
"""
# **If you find this notebook useful, support with an upvote** 👍¶¶
"""