Detecting Emotion with Computer Vision
Abstract
In this project, you will use computer vision to detect human emotions from facial expression images. You will train a model to classify emotions such as happiness, sadness, anger, and fear, while experimenting with different parts of the model architecture.
Summary
None
Readily available
No issues
Objective
To build and evaluate a computer vision model that uses a convolutional neural network, or CNN, to classify human emotions from facial expression images.
Introduction
Researchers have long been interested in whether computers can recognize facial expressions and how reliable that recognition really is. In healthcare, researchers are exploring whether facial expression analysis could someday help clinicians better understand the well-being of patients who have difficulty communicating. In transportation safety, researchers are studying whether vehicle systems could recognize when a driver appears panicked or highly stressed, so the vehicle could respond, for example, by suggesting a break. Before any system like this could be trusted in situations where people's health or safety is at stake, researchers need to know how accurate it is, and when and why it makes mistakes.
One way computers can study facial expressions is through machine learning, which enables them to learn patterns from data rather than being directly programmed for every situation. Many machine learning models are built using neural networks, which are computational systems inspired by how the human brain processes information. A neural network is made of layers of connected “neurons” that work together to recognize patterns in data. In this project, the focus is on computer vision, a branch of artificial intelligence that enables computers to interpret and understand images and videos. Computer vision can be used for tasks such as identifying objects, recognizing faces, and, in this case, detecting emotions from images of facial expressions.
Watch this video for a simple introduction to neural networks:
A type of machine learning model called a convolutional neural network, or CNN, is especially useful for image analysis. CNNs are designed to look at small parts of an image at a time and learn important visual features, such as edges, shapes, and facial patterns. As the network processes more images, it can become better at recognizing features associated with different emotions, such as happiness, sadness, anger, and fear. Because CNNs are effective at detecting visual patterns, they are a strong choice for emotion detection in computer vision.
Watch this video to learn more about CNNs:
However, emotion-detection models are not perfect and should be used with care. Facial expressions do not always accurately reveal a person's true emotions. People may hide how they feel, express emotions differently, or have expressions misinterpreted by others or by a computer model. Model predictions can also be affected by dataset bias, lighting conditions, camera angle or pose, cultural differences in facial expression, and individual differences in how people show emotion. For these reasons, facial emotion recognition should not be treated as perfectly accurate.
In this project, you will modify one part of a CNN model: the number of filters in its convolutional layers. Filters help the model detect visual patterns in an image, such as edges, shapes, and facial features. By testing different numbers of filters, you will explore how this design choice can affect the model’s performance.
The goal is not only to build a model that can classify emotions, but also to understand how computer vision models learn from images. By comparing your results, you will see how testing and iteration can help improve a machine learning model.
Terms and Concepts
- Facial expressions
- Facial expression analysis
- Neural network
- Computer vision
- Convolution neural network (CNN)
- Filter
- Overfit
- Hidden layer
- Epoch
- Training accuracy
- Validation accuracy
- Training loss
- Validation loss
- Test accuracy
- Confusion matrix
Questions
- What is computer vision, and how is it used in this project?
- Why are CNNs useful for analyzing images?
- What are filters in a CNN, and what do they help the model detect?
- Why should emotion-detection models not be treated as perfectly accurate?
- What do you predict will happen when you change the number of filters in the CNN model?
Bibliography
To learn more about computer vision and emotion detection:
- Pereira R, et. al. (2024, May). Systematic Review of Emotion Detection with Computer Vision and Deep Learning. PubMed Central. Retrieved June 30, 2026.
To learn more about neural networks:
- Science Buddies. (2024, May). Simple Explanation of Neural Networks. YouTube. Retrieved June 30, 2026.
To learn about convolutional neural networks:
- Futurology -- An Optimistic Future. (2020, December). Convolutional Neural Networks Explained (CNN Visualized). YouTube. Retrieved June 30, 2026.
To learn more about why we split datasets into train, validation, and test sets:
- deeplizard. (2017, November). Train, Test, & Validation Sets explained. YouTube. Retrieved June 30, 2026.
Materials and Equipment
- Computer with Internet access
- Phone, camera, or webcam on a computer
Experimental Procedure

Setting Up the Google Colab Environment
- You will need a Google account. If you do not have one, make one when prompted.
- Download the emotion_detection.ipynb file from Science Buddies. This is the code you will need to process your data.
- Download the emotions.zip file. This contains the images our model will train on.
- Within your Google Drive, click on ‘MyDrive,’ then create a new folder and rename it
emotion_detection. Inside the folder, upload theemotion_detection.ipynbfile and the emotions.zip file. You do NOT need to unzip this file before uploading it. - Double-click on the
emotion_detection.ipynbfile. This should automatically open in Google Colab.- Read the Troubleshooting Tips and How to Use This Notebook sections. Follow the instructions you find in that section.
- Run the block under Importing Libraries to ensure you have access to all the functions we will use for this project.
Viewing the Dataset
- (Code Block 1A) This first code block will unzip the
emotions.zipfile you uploaded earlier. Run this code block.- Once this code block is done running, you should see a new folder called
imagesinside youremotion_detectionfolder. Within the images folder, you should see seven more folders named after the seven emotions:Anger,Disgust,Fear,Happy,Neutral,Sad, andSurprised. - If you don’t see the folders right away, wait a few minutes and refresh.
- Once this code block is done running, you should see a new folder called
- (Code Block 1B) This code block will display a count of images in each folder.
- Does the data look evenly distributed? If not, how can we address the class imbalance?
- (Code Block 1C) This code block defines a helper function that lets us view some of the images in the notebook. Run this code block.
- (Code Block 1D) Under the
#TODOcomment in this code block, you can change the name of the folder to view images from that folder. It is set to“Anger”by default. You can run this code block multiple times to view different images.- Note: Make sure to type the emotion folder exactly as it appears under Code Block 1B. For example,
“Neutral”is correct but not“neutral”.
- Note: Make sure to type the emotion folder exactly as it appears under Code Block 1B. For example,
Preprocessing
- (Code Block 2A) This code block converts the images to grayscale. Images are often converted to grayscale because it makes them simpler for the computer to study. Instead of looking at many different colors, the model only needs to focus on light and dark areas, which helps it notice shapes, edges, and facial expressions more easily. Run this code block.
- Converting to grayscale means the computer has less information to process, so training can be faster and use less computing power. For emotion detection, the most important clues usually come from facial features and expressions, not from the exact colors in the image.
- At the bottom of this code block, you should see the grayscale image's size printed. The image should be 64x64 pixels.
- Note: 64x64 is typically large enough for basic emotion classification if the image is a tightly cropped face (as in this dataset). In fact, some datasets use smaller images, although more subtle emotions may suffer at low resolution.
Creating the DataFrame
- (Code Block 2B) This code block creates a DataFrame, or data table, to organize our information. This makes the data easier for the machine learning model to understand and learn from. Run this code block.
Splitting the Data into Train, Validation, and Test Sets
- (Code Block 2C) This code block splits our dataset into training, validation, and test sets to help prevent overfitting, which occurs when a model memorizes the training data rather than learning generalizable patterns. It also makes sure the model is tested on data it has never seen before. Click on this link to learn more about splitting our data into train, validation, and test sets. Run this code block.
Creating Image Data Generators
- (Code Block 2D) This code block creates an
ImageDataGeneratorthat prepares images for training by loading them in small batches and generating slightly modified versions to help the model learn more effectively. For example, it may create images that are slightly rotated, flipped, or more or less saturated. Run this code block.
Building the CNN Model
- (Code Block 3A) Under the
#TODOcomment, you can edit the filters. Filters are pattern detectors. Early filters might detect edges or simple shapes, while deeper filters can detect more complex facial features. You can check out the documentation for the convolutional layer here.filter_1is the number of filters for the first layer,filter_2is the number of filters for the second layer, etc. There are four hidden layers. A hidden layer is any layer in a neural network that comes between the input layer and the output layer.- Note: The number of filters has a big effect on how much the model can learn. More filters give the model greater power to find patterns, but too many can slow training and lead to overfitting.
- Try these 3 different models and compare the results:
- Small model:
8, 16, 32, 32 - Medium model:
32, 64, 128, 128 - Large model:
64, 128, 256, 256
- Small model:
Compiling and Training the Model
- (Code Block 4A) This code block will compile and train the model you defined in Code Block 3A. Next to the
#TODOcomment, you can adjust the number of epochs the model trains for. An epoch is one full pass through the entire training dataset. By default, the model is set to train for 10 epochs.- Note: This code may take a few minutes to run, so this is a good time to stretch, take a short break, or grab a snack.
Evaluating the Model
- (Code Block 5A) This code block creates two graphs to show how your model performed during training.
- Training and Validation Accuracy Graph: This graph shows how often the model correctly predicts the emotion at each epoch.
- Training accuracy shows how well the model does on the data it was trained on.
- Validation accuracy indicates how well the model performs on new data it was not trained on.
- If both lines go up, the model is learning.
- If validation accuracy is also high, the model is performing well on new images rather than just memorizing the training set.
- If training accuracy gets much higher than validation accuracy, the model may be overfitting. That means it learned the trained images too specifically and does not generalize as well to new ones.
- Training and Validation Loss: This graph shows how far off the model is at each epoch.
- Training loss measures error on the training data.
- Validation loss measures error on the validation data.
- If both lines go down, that is usually a good sign.
- Lower loss means the model’s predictions are getting closer to the correct answers.
- If training loss keeps going down but validation loss starts going up, that is another sign of overfitting.
- How to read both graphs together:
- A strong model usually has:
- Accuracy increasing
- Loss decreasing
- Training and validation lines that stay fairly close together
- A model that is overfitting often has:
- Training accuracy much higher than validation accuracy
- Training loss is going down while validation loss goes up
- A strong model usually has:
- Training and Validation Accuracy Graph: This graph shows how often the model correctly predicts the emotion at each epoch.
- (Code Block 5B) This code block will print the final validation accuracy. Run this code block.
- What was your model’s final validation accuracy?
- If your validation accuracy was low, what changes could you make to improve your model?
- (Code Block 5C) This code block prints the model’s test accuracy, which indicates how well the trained model performs on the test dataset. The test dataset contains images the model has not used during training or validation, so test accuracy gives a final check of how well the model might perform on brand-new images. Run this code block.
- What was your model’s test accuracy?
- Was your test accuracy higher, lower, or about the same as your validation accuracy? What might that mean?
- (Code Block 5D) This code block displays a confusion matrix, a table that shows how well the model classified each emotion.
- In a confusion matrix, the actual emotion labels are compared with the model’s predicted emotion labels. Correct predictions usually appear along the diagonal of the matrix. Values outside the diagonal show where the model made mistakes, such as predicting “happy” when the actual label was “surprised.”
- Use the confusion matrix to look for patterns in the model’s errors. For example, are there certain emotions the model predicts very well? Are there emotions that are often confused with it?
- (Code Block 5E) This code block will randomly display one image that the model classified incorrectly. It will show the image, print the actual emotion label, and print the emotion the model predicted instead. You can re-run this block multiple times to show a different image each time.
- Look closely at the image. Why do you think the model confused these two emotions? Are there facial features, lighting, image quality issues, or ambiguous expressions that might have made the prediction difficult?
- Do you think the model could improve with more training data or a better architecture, or are some emotions naturally difficult to predict from facial expressions alone?
Testing Your Emotion Detection Model with Your Own Images
In this section, you will test your emotion detection model using either a webcam photo or an image uploaded from Google Drive.
You only need to choose one option:
- Use Code Blocks 6A-6B to take a picture directly in Google Colab using your webcam.
- (Code Block 6A) This block defines a helper function that lets us capture images directly within the Google Colab notebook. Run this code block.
- (Code Block 6B) This code block runs the helper function from Code Block 6A, allowing you to take a picture using your webcam. When you run this block, Google Colab will ask for permission to access your camera. Click Allow. If you do not have a webcam or do not want to grant camera access, you can use your own images instead, using Code Blocks 6C-6D.
- After running the block, your camera preview will appear with a Capture button. Click Capture to take a picture. The model will then print its predicted emotion.
- Was the predicted emotion the same as the emotion you were showing? Try making different facial expressions and see how well the model recognizes them.
- Use Code Blocks 6C-6D if you do not have a webcam, or do not want to give camera access, or prefer to test an image from Google Drive.
- (Code Block 6C) This code block defines a helper function that lets us test images stored in Google Drive. It also creates a folder called
testif one does not already exist.- After running this block, check your Google Drive for the new
testfolder. If you do not see it right away, refresh the Google Drive page.
- After running this block, check your Google Drive for the new
- (Code Block 6D) This code block runs the helper function from Code Block 6C, allowing you to test your model with an image from Google Drive.
- First, upload the image you want to test to the
testfolder in your Google Drive. Then, under the#TODOcomment, enter the name of the image file you uploaded (e.g., "happy.jpg") - When you run this block, the model will print its predicted emotion below the code.
- First, upload the image you want to test to the
- (Code Block 6C) This code block defines a helper function that lets us test images stored in Google Drive. It also creates a folder called
- Fill out a table similar to the one below. To fill out the confusion matrix table, record the emotion you were trying to show and the emotion the model predicted.
- The rows show the actual emotion. This is the emotion you were trying to show in your webcam photo or uploaded image.
- The columns show the predicted emotion. This is the emotion the model printed after testing your image.
- Test at least 10 images or facial expressions for each emotion: surprised, sad, neutral, happy, fear, disgust, and anger. This means you should test at least 70 total images or webcam photos. Testing multiple examples of each emotion gives you more reliable results and makes it easier to see patterns in the model’s predictions.
- Each time you test an image, find the row for the actual emotion and the column for the predicted emotion. Then add a tally mark or increase the number in that box by 1.
- For example, if you made a happy face but the model predicted neutral, you would add 1 to the box where the Happy row and Neutral column meet.
- If the model correctly predicts the emotion, the count will appear on the diagonal of the table, where the actual and predicted emotions match. For example, if you made a sad face and the model predicted sad, add 1 to the Sad-Sad box.
- After you finish testing, look at the table to see which emotions the model predicted well and which it confused with others.
| Predicted Emotion | ||||||||
|---|---|---|---|---|---|---|---|---|
| Surprised | Sad | Neutral | Happy | Fear | Disgust | Anger | ||
| Actual Emotion | Surprised | |||||||
| Sad | ||||||||
| Neutral | ||||||||
| Happy | ||||||||
| Fear | ||||||||
| Disgust | ||||||||
| Anger | ||||||||
- After you complete the confusion matrix, review your results and look for patterns. Which emotions did the model predict correctly most often? Which emotions were confused with each other?
- Then go back to Code Block 3A and test different numbers of filters in the CNN model. Train the model again, test it with your images, and compare the new confusion matrix to your first one.
- You can also check the project variations section for additional parts of the model you may be able to change. After each change, record your results so you can compare how different model settings affect the model’s performance.
Ask an Expert
Variations
- Compare model performance across different preprocessing choices, such as grayscale vs. color images, different image sizes, normalized vs. non-normalized pixel values, and cropped vs. uncropped faces.
- Train one model on regular images and another on augmented images (e.g., rotated, flipped, zoomed, or shifted).
- Look at a small set of test images and predict the emotions yourself, then compare your guess to the model’s predictions. This can lead to a discussion about why emotion detection is difficult, even for humans.
- You could also change more model parameters:
- Number of convolutional layers
- Size of the dense hidden layer
- Dropout rate
- Max pooling settings
- Kernel size
Careers
If you like this project, you might enjoy exploring these related careers:










