Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 12

Image Preprocessing: Metadata Analysis and Visual Inspection

Recommended resources

Welcome to the next step in our journey! In the previous lesson, we conducted a thorough exploratory data analysis (EDA) on your text data, uncovering key themes and complaint categories using techniques like n-gram analysis and topic modeling. This gave us a data-driven foundation for defining the labels for our future text classification model.

Now, we will apply the same analytical mindset to the other major component of your dataset: the images of midday meals. Images scraped from the internet are rarely uniform; they come in a variety of sizes, formats, and quality levels. Our goal in this lesson is to analyze these properties to design a robust preprocessing strategy. This "image EDA" is a critical step to ensure that the data we feed into our convolutional neural network (CNN) is clean, consistent, and optimized for training.

This diagram illustrates the fundamental properties of a digital image that we will investigate, such as its dimensions, file format, and other metadata. Understanding these characteristics is the first step toward preparing images for a machine learning model.

We will cover three main areas:

  1. Extracting and analyzing basic metadata, such as dimensions and file formats, across your entire image dataset.
  2. Visually inspecting a sample of images to identify qualitative issues like blurriness, incorrect orientation, or irrelevant content.
  3. Synthesizing these findings into a concrete preprocessing plan that will guide our work in the next module.

1. Understanding the Structure of an Image

Before we analyze metadata, it's essential to understand how a computer "sees" an image. At its core, a digital color image is a three-dimensional array (or tensor) of numbers. Your background with data structures and programming will make this concept intuitive.

The video below from Rob Mulla offers a clear explanation of how an image is represented as a NumPy array and what its dimensions signify.

Image Processing with OpenCV and Python

This video explains the fundamental representation of image data in Python.

Please watch the segment from 3:42 to 5:23. The presenter breaks down the three dimensions of an image array: Height: The number of pixels vertically. Width: The number of pixels horizontally. Channels: The color components. For most images, this will be 3, representing Red, Green, and Blue (RGB). Each pixel's color is a combination of the intensity values (typically 0-255) in these three channels.

Understanding that an image is just a numerical array is key, because our CNN will ultimately operate on these numbers. Inconsistencies in the shape of these arrays (i.e., different image dimensions) can cause errors or lead to poor model performance.


2. Analyzing Image Metadata at Scale

Our first task is to get a quantitative overview of the entire image collection. We'll write a Python script to iterate through your raw image directory (data/01_raw/images/), extract key metadata for each file, and aggregate it for analysis. The most important properties for our purposes are file format and dimensions (width and height).

The Python Imaging Library (Pillow or PIL) is the standard tool for this job. You can easily install it if you haven't already (pip install Pillow).

Here is a script that demonstrates how to perform this analysis. It gathers the data into a pandas DataFrame, which you are already familiar with, for easy summarization and visualization.

import os
import pandas as pd
from PIL import Image, UnidentifiedImageError
from pathlib import Path
from tqdm import tqdm # For a nice progress bar




# Define the path to your raw images
image_dir = Path('data/01_raw/images/')




# Get a list of all image files (e.g., jpg, png)
image_paths = list(image_dir.glob('*.[jp][pn]g'))

metadata_list = []

print(f"Found {len(image_paths)} images. Analyzing metadata...")

for img_path in tqdm(image_paths):
    try:
        with Image.open(img_path) as img:
            metadata_list.append({
                'filename': img_path.name,
                'format': img.format,
                'width': img.width,
                'height': img.height
            })
    except UnidentifiedImageError:
        print(f"Warning: Could not read or identify {img_path}. Skipping.")
    except Exception as e:
        print(f"An error occurred with {img_path}: {e}")




# Create a DataFrame from the list of dictionaries
df = pd.DataFrame(metadata_list)

print("\n--- Metadata Analysis Summary ---")



# Analyze File Formats
print("\nFile Format Distribution:")
print(df['format'].value_counts())




# Analyze Dimensions
print("\nDimension Statistics (in pixels):")
print(df[['width', 'height']].describe())




# You can also visualize this data
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
sns.histplot(df['width'], bins=50, kde=True)
plt.title('Distribution of Image Widths')

plt.subplot(1, 2, 2)
sns.histplot(df['height'], bins=50, kde=True)
plt.title('Distribution of Image Heights')

plt.tight_layout()
plt.show()

When you run this script, the output will tell you:

  • The mix of file formats (e.g., JPEG, PNG). This is important because PNGs can have a fourth "alpha" channel for transparency that may need to be handled.
  • The statistical summary and distribution of image widths and heights. You will likely see a wide range, from small thumbnail-sized images to very large photos from modern smartphones. This variance is precisely why a standardized resizing strategy is non-negotiable.

3. Visual Inspection and Qualitative Analysis

While numerical metadata gives us the "what," visual inspection tells us the "how." We need to look at a sample of images to understand their content and quality. Are they all usable? Are there common problems we need to fix automatically?

This following article provides an excellent guide to building a full preprocessing pipeline. For now, we'll focus on two key ideas it presents: detecting blurry images and the importance of visual inspection.

Part 1: Preprocessing and Preparing the CIFAR-10 Dataset

This article from DeepThought outlines a complete image preprocessing workflow. We will draw on its practical techniques for quality control.

Please read two specific sections: Start at the heading Blurriness Detection with OpenCV. This section introduces the concept of using the Laplacian variance to programmatically measure image sharpness. Pay close attention to the is_blurry function; it's a powerful tool for automatically filtering out low-quality images that could harm your model's performance. Next, read the section on Visual Inspection. This part emphasizes the need for a "sanity check" by displaying a sample of images. The rationale and the list of things to look for are directly applicable to your project.

Let's put this into practice. First, let's create a script to view a random sample of your meal images using matplotlib.

import random
import matplotlib.pyplot as plt
import matplotlib.image as mpimg




# Reuse the image_paths list from the previous script
num_samples = 12
sample_paths = random.sample(image_paths, num_samples)

plt.figure(figsize=(15, 10))
for i, img_path in enumerate(sample_paths):
    plt.subplot(3, 4, i + 1)
    try:
        img = mpimg.imread(img_path)
        plt.imshow(img)
        plt.title(img_path.name, fontsize=8)
        plt.axis('off')
    except Exception as e:
        plt.text(0.5, 0.5, f"Error loading:\n{img_path.name}", ha='center')
        plt.axis('off')
        
plt.suptitle('Random Sample of Scraped Meal Images', fontsize=16)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.show()

As you look at these images, ask yourself:

  • Content Validity: Are they all actually pictures of midday meals? You might find unrelated images that need to be filtered out.
  • Quality: How is the lighting? Are many images dark, overexposed, or blurry? This confirms the need for the blur detection we just read about.
  • Obstructions: Is there text, watermarks, or other overlays on the images? These could confuse the model.
  • Orientation: Are some images rotated sideways? Images can contain EXIF metadata that specifies orientation, but web scraping and social media platforms often strip this.

The note about WhatsApp stripping metadata in the GeeksForGeeks article is particularly relevant here, as many of your images might come from screenshots shared on such platforms. This means we cannot rely on EXIF data and may need to handle orientation issues manually or with other techniques.

How to extract image metadata in Python? - GeeksforGeeks

This article provides context on EXIF metadata.

Read the section "Using Exif to extract image metadata". The most important takeaway for your project is the note: "Whatsapp strips away all metadata". This reinforces why we must rely on analyzing the image pixels themselves, not just file metadata.


4. Designing Your Preprocessing Strategy

Based on our quantitative and qualitative analysis, we can now outline a clear preprocessing plan. The goal is to transform every raw image into a standardized format ready for the CNN.

The following video from Roboflow provides a great high-level overview of common preprocessing steps and, crucially, why they are necessary.

What is Image Preprocessing?

This video introduces the concept and common methods of image preprocessing.

Watch these key segments: 1:17 - 2:20: The presenter analyzes a chess dataset, noticing that images are large and not square, which necessitates a resizing step. This perfectly mirrors the analysis you just did on your own data. 2:30 - 3:25: This part discusses different ways to resize an image, such as stretching or padding. Padding is often preferred as it preserves the original aspect ratio, preventing distortion. 3:46 - 4:14: This is a critical rule: preprocessing steps must be applied consistently to your training, validation, and production data.

Synthesizing everything we've learned, here is a robust, initial preprocessing strategy for your project:

  1. Image Validation:

    • Iterate through all files and use PIL or OpenCV to check if they are readable and not corrupted. Skip any that fail.
    • Apply a blurriness filter using the Laplacian variance method from the deepthought.sh article to discard low-quality images.
  2. Resizing and Padding:

    • All images must be resized to a single, fixed size (e.g., 224x224 pixels, a common input size for many pretrained models).
    • To avoid distorting the food items, we will use a pad-and-resize strategy: add black padding to the shorter dimension to make the image square, then resize it to the target dimensions. The pad_and_resize function in the deepthought.sh article provides a perfect implementation.
  3. Color Space Conversion:

    • Ensure all images are in the RGB color space. Libraries like OpenCV read images in BGR (Blue-Green-Red) format by default, while matplotlib and PyTorch expect RGB. This mismatch can lead to incorrect colors and poor model performance if not handled. We will need to explicitly convert BGR to RGB.
  4. Normalization:

    • Scale pixel intensity values from the [0, 255] range to a smaller range, typically [0, 1] or [-1, 1]. This is done by dividing the pixel values by 255. Normalization helps the model train faster and more stably.

This four-step plan will be the foundation for the image processing pipeline we build in the next module.


Conclusion

In this lesson, you've conducted a comprehensive exploratory analysis of your image dataset. You've moved beyond simply collecting files to deeply understanding their characteristics.

Key Takeaways:

  • An image is represented as a 3D numerical array of (height, width, channels). Inconsistencies in these dimensions must be resolved.
  • Analyzing metadata at scale with Python and pandas reveals variations in file formats and dimensions, proving the need for a standardization pipeline.
  • Visual inspection is a crucial sanity check to identify qualitative issues like blurriness, irrelevant content, or incorrect orientation that numerical analysis might miss.
  • Your findings directly inform a concrete preprocessing strategy: Validate -> Pad & Resize -> Convert Color Space -> Normalize.

You are now perfectly positioned to move from analysis to implementation. In our next lesson, we will kick off the next module by writing the Python code to perform these essential preprocessing steps using OpenCV and Pillow, turning your raw, chaotic image data into a clean, model-ready dataset.