Profiling Energy Consumption in Image Processing with CodeCarbon: A Step Towards Sustainable Computing

Table of contents

Introduction

In the modern computing landscape, sustainability has become a crucial concern. With the increasing use of computationally expensive tasks, such as deep learning and image processing, it is vital to measure their energy consumption and environmental impact. This script performs image processing using OpenCV while tracking its energy consumption using CodeCarbon, a tool designed to estimate the carbon footprint of computational workloads. By executing various image operations, the script profiles how much energy is used and how emissions vary during execution.


What Does the Code Do?

The script follows a structured sequence of operations to perform image processing tasks while monitoring system energy consumption. It first initializes the CodeCarbon EmissionsTracker, loads an input image, processes it using grayscale conversion, edge detection, Gaussian blur, and rotation, and finally blends the processed images. Throughout execution, CodeCarbon tracks the power usage, calculates emissions, and logs the results for further analysis. This enables users to quantify the environmental impact of their computations and optimize workloads for energy efficiency.


Understanding CodeCarbon: What It Is and Why It’s Used?

CodeCarbon is an open-source tool designed to estimate the energy consumption and CO₂ emissions produced by Python scripts, particularly for AI/ML workloads. It helps developers and researchers measure their computational carbon footprint and make informed decisions to optimize energy efficiency.

How CodeCarbon Tracks Energy Consumption?
  • Energy Estimation Models: CodeCarbon estimates power consumption based on hardware specifications, such as CPU, GPU, RAM usage, and power draw.

  • Cloud & Local Tracking: It supports tracking on local machines (by monitoring power usage) and cloud platforms (by estimating based on region-specific energy sources).

  • Carbon Intensity Factor: CodeCarbon considers the electricity mix of the region where the computation is performed, assigning a carbon intensity factor (kg CO₂/kWh) to calculate the emissions.

  • Logging & Reporting: It stores all metrics in a CSV file, which helps in analyzing energy consumption patterns over time.

CodeCarbon starts tracking before the computations begin and stops after processing is completed. The final energy consumption and emissions data are logged in carbon_emissions.csv.

How CodeCarbon Tracks Energy Consumption?

FeatureDescription
Energy EstimationEstimates power consumption based on CPU, GPU, and RAM usage.
Cloud & Local TrackingTracks execution on local machines and cloud platforms by analyzing energy sources.
Carbon Intensity FactorAssigns a CO₂ intensity (kg CO₂/kWh) based on region-specific energy sources.
Logging & ReportingStores metrics in a CSV file, enabling trend analysis over time.

CodeCarbon - Visualized DashBoard


Introduction to OpenCV and Why It’s Used?

OpenCV (Open Source Computer Vision Library) is a widely used library for real-time image processing and computer vision applications. It provides fast and efficient functions for performing various operations on images, making it a preferred choice for image manipulation tasks.

Operations Performed in This Script Using OpenCV
  1. Loading an Image

    • The script reads an image file (Tom_Cruise.jpg) using cv2.imread(). If the file is missing, it exits with an error message to prevent unexpected behavior.
  2. Converting Image to Grayscale

    • The color image is converted to grayscale using cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), reducing the complexity of computations by removing color information.
  3. Applying Canny Edge Detection

    • Edge detection is performed using cv2.Canny(gray_image, 100, 200), where 100 and 200 are the threshold values that define the intensity gradient for edge detection.

  1. Computationally Intensive Workload Simulation

    • To create a stress test for the system, the script runs a loop 100 times performing:

      • Gaussian Blur: Applied using cv2.GaussianBlur(edges, (5,5), 0) to reduce noise in the image.

      • Image Rotation: Performed using cv2.rotate(blurred, cv2.ROTATE_90_CLOCKWISE), simulating a computationally heavy operation.

  1. Blending Processed Images

    • If the blurred and rotated images have the same dimensions, they are merged using cv2.addWeighted(blurred, 0.5, rotated, 0.5, 0), where both images contribute 50% to the final result. If the dimensions do not match, an error message is printed.

Operations Performed in This Script Using OpenCV

OperationFunctionPurpose
Loading Imagecv2.imread("Tom_Cruise.jpg")Reads an image into memory.
Grayscale Conversioncv2.cvtColor(image, cv2.COLOR_BGR2GRAY)Simplifies computations by removing color information.
Edge Detectioncv2.Canny(gray_image, 100, 200)Identifies object boundaries using Canny edge detection.
Gaussian Blurcv2.GaussianBlur(edges, (5,5), 0)Reduces noise to enhance edge detection.
Image Rotationcv2.rotate(blurred, cv2.ROTATE_90_CLOCKWISE)Simulates a computationally heavy transformation.
Blending Imagescv2.addWeighted(blurred, 0.5, rotated, 0.5, 0)Merges two processed images with equal weights.

How CodeCarbon Detects Emissions in Deep Learning and Image Processing?

In deep learning, models require intensive GPU and CPU resources, leading to high energy consumption. CodeCarbon helps track emissions by analyzing:

  • Hardware Power Consumption: It estimates the power used by CPUs, GPUs, and RAM, considering their efficiency.

  • Deep Learning Workload Intensity: The library accounts for the duration and intensity of computations performed by DL frameworks (TensorFlow, PyTorch, OpenCV, etc.).

  • Energy Sources & Regional Impact: CodeCarbon uses grid energy mix data to determine whether power comes from renewable sources or fossil fuels, refining its emission calculations.

  • Comparison & Optimization: Researchers can compare multiple hardware configurations, optimization techniques, and batch sizes to determine which setup consumes the least energy.

While this script focuses on image processing, the same principles apply to deep learning models, making CodeCarbon a valuable tool for AI researchers to measure sustainability.


Why This Matters?

The growing adoption of AI, deep learning, and image processing has increased the demand for computational power. However, this comes at an environmental cost due to high energy consumption and carbon emissions. By integrating tools like CodeCarbon, developers can measure, analyze, and optimize their workloads to reduce energy waste and improve sustainability.

This script demonstrates a practical approach to profiling energy usage in an image processing task, providing insights into how computation affects environmental impact. Such techniques can be extended to optimize machine learning pipelines, scientific simulations, and large-scale data processing workflows for a greener and more efficient future.


Code Breakdown and Execution Flow - CODE-LINK

1. Importing Required Libraries

The script starts by importing necessary Python libraries:

  • codecarbon.EmissionsTracker: Tracks and logs energy consumption.

  • cv2 (OpenCV): Handles image processing operations.

  • numpy: Used for array operations.

  • time: Provides time-related functions.

2. Initializing the Carbon Emissions Tracker

tracker = EmissionsTracker(output_file="carbon_emissions.csv")
tracker.start()

  • The EmissionsTracker is initialized with a CSV output file named "carbon_emissions.csv".

  • It starts recording energy consumption from this point onward.

3. Loading an Image

print("Loading Image.....")
image = cv2.imread("Tom_Cruise.jpg")

  • The script attempts to read an image file named "Tom_Cruise.jpg".

  • If the image file is missing, an error message is displayed, and the program exits:

if image is None:
    print("Error: Image not found!")
    exit()

  • This ensures that the program does not proceed with an invalid input.

4. Converting Image to Grayscale

print("Converting to grayscale.....")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

  • The loaded image is converted from BGR (Blue-Green-Red) format to grayscale.

  • This reduces the complexity of the image by removing color channels, keeping only intensity values.

5. Applying Edge Detection Using Canny Algorithm

print("Applying Canny edge detection..")
edges = cv2.Canny(gray_image, 100, 200)

  • The Canny Edge Detection algorithm detects prominent edges in the grayscale image.

  • Threshold values 100 and 200 define the intensity gradient required to classify edges.

6. Running a Computational Workload

print("Running workload...")
for in range(100):
    blurred = cv2.GaussianBlur(edges, (5,5), 0)
    rotated = cv2.rotate(blurred, cv2.ROTATE
90_CLOCKWISE)

  • The script simulates an intensive computation workload by performing:

    1. Gaussian Blur: Smooths the edges using a 5×5 kernel to reduce noise.

    2. Image Rotation: Rotates the blurred image 90 degrees clockwise.

  • This loop runs 100 times, stressing the CPU and memory.

7. Blending Two Images (Conditional Check)

if blurred.shape == rotated.shape:
    blended = cv2.addWeighted(blurred, 0.5, rotated, 0.5, 0)
else:
    print("Error: Image shapes do not match for addWeighted")

  • If the shapes of the blurred and rotated images match, image blending is performed:

    • cv2.addWeighted() merges two images with equal weight (0.5).
  • If shapes do not match, an error message is displayed.

8. Stopping the Carbon Emissions Tracker

tracker.stop()

  • Stops the energy tracking process and logs results in "carbon_emissions.csv".

  • The logged data includes:

    • Energy consumed (kWh)

    • CO₂ emissions (kg)

9. Completion Message

print("Profiling complete! Check logs for energy usage")

Run-IDExperiment-IDDurationEmissionsEmissions-RateCPU-PowerRam-PowerCPU-EnergyRam-EnergyEnergy -Consumed
cbdba861-93c8-4999-befb-825fa0fa106a5b0fa12a-3dd7-45bb-9766-cc326314d9f14.7645631.60E-053.35E-0642.50.1108685.58E-051.45E-075.60E-05
e2422456-6076-4940-894b-dba02f76c5f55b0fa12a-3dd7-45bb-9766-cc326314d9f14.4552621.49E-053.35E-0642.50.1111085.22E-051.36E-075.23E-05
0cf0c38e-fab8-4c48-afe4-1079cd957cfa5b0fa12a-3dd7-45bb-9766-cc326314d9f15.1192292.07E-054.04E-0642.50.1149197.23E-051.94E-077.25E-05

Detailed Explanation of the Sustainability Profiling Script: Sustainability Computation Index (SCI) - CODE-LINK

This script is designed to measure and analyze energy consumption, system performance, and carbon emissions during an image processing task. It achieves this by tracking CPU and memory usage, monitoring energy consumption, and computing a Sustainability Computation Index (SCI) to evaluate the environmental impact of running the task. The script also provides visualizations to help understand trends in energy usage and system performance.


1. Overview of the Script

The script follows these main steps:

  • Setup and Configuration

    • Import necessary libraries for system monitoring, energy tracking, and image processing.

    • Create a logging directory to store the results.

  • System Performance Monitoring

    • Capture CPU, memory, and RAM usage before and after processing.
  • Energy Consumption and Emission Tracking

    • Use the CodeCarbon library to measure power consumption and CO₂ emissions.
  • Image Processing Simulation

    • Apply Gaussian Blur and Canny Edge Detection on a sample image.
  • Sustainability Computation

    • Compute the Sustainability Computation Index (SCI) to quantify the environmental impact.
  • Data Visualization

    • Generate graphs showing energy consumption and memory usage.
  • Save and Log the Results

    • Store energy usage, emissions, and SCI scores in a CSV file for future analysis.

2. Importing Required Libraries

import os
import time
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import psutil
from codecarbon import EmissionsTracker

LibraryPurpose
osHandles file operations (creating directories, managing logs).
timeMeasures execution time for performance tracking.
numpyCreates and manipulates images using arrays.
pandasStores and processes data efficiently in CSV format.
matplotlib.pyplot & seabornVisualizes system performance and energy consumption.
psutilMonitors CPU, RAM, and memory usage before and after processing.
codecarbonTracks energy consumption and CO₂ emissions during execution.

The script relies on multiple Python libraries for different functionalities:


3. Setting Up the Log Directory

To store logs and results, a directory named logs is created if it does not exist:

log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)

This ensures that all the emission and performance data is saved in an organized manner.


4. Defining the Sustainability Computation Index (SCI)

The script defines a Sustainability Computation Index (SCI) to measure the environmental impact of the image processing task. The formula used is:

SCI=((Energyconsumed​*I)+M​ ) / R

ParameterMeaning
I = 0.4Marginal carbon emissions factor (kg CO₂/kWh), depends on energy source.
M = 10Embodied carbon emissions per functional unit (kg CO₂), representing manufacturing costs.
R = 1Functional unit, here representing one processed image.

I = 0.4
M = 10
R = 1

This formula helps quantify how much energy and emissions are used for processing each image.


5. Capturing System Usage

A function is created to fetch real-time system resource usage before and after the image processing task.

def get_system_usage():
    return {
        "cpu": psutil.cpu_percent(interval=1),
        "memory": psutil.virtual_memory().percent,
        "ram_used": round(psutil.virtual_memory().used / (1024 ** 3), 2),
    }

This function returns a dictionary containing:

MetricDescription
cpuCPU usage in percentage.
memoryPercentage of total memory used.
ram_usedRAM usage in gigabytes.

By calling this function before and after the image processing step, the script can measure how much CPU and RAM resources were consumed.


6. Initializing Energy Tracking

To track the power consumption and carbon footprint, the CodeCarbon EmissionsTracker is used:

tracker = EmissionsTracker(output_dir=log_dir, output_file="carbon_emission.csv")
tracker.start()

This starts logging the energy consumed and carbon emissions produced by the script while it runs.


7. Image Processing Task

The script simulates an image processing task using OpenCV (cv2) to apply blurring and edge detection on an image.

image = np.ones((512, 512, 3), dtype=np.uint8) * 255  # Creating a blank white image
blurred = cv2.GaussianBlur(image, (5, 5), 0)  # Applying Gaussian blur
edges = cv2.Canny(blurred, 100, 200)  # Detecting edges using Canny edge detection

StepFunctionality
Create ImageA blank 512x512 white image is created using NumPy.
Gaussian BlurReduces noise by blurring the image.
Canny Edge DetectionDetects edges by identifying intensity changes in the image.

Before and after this step, system performance metrics are recorded.


8. Stopping Energy Tracking and Retrieving Data

Once the processing is complete, the script stops the tracker and reads the recorded energy usage from carbon_emission.csv.

tracker.stop()
log_file = os.path.join(log_dir, "carbon_emission.csv")
if os.path.exists(log_file):
    df = pd.read_csv(log_file)
    energy_consumed = df["energy_consumed"].iloc[-1] if "energy_consumed" in df.columns else 0
    emissions = df["emissions"].iloc[-1] if "emissions" in df.columns else 0
else:
    energy_consumed = 0
    emissions = 0

This extracts energy consumed (in kWh) and carbon emissions (in kg CO₂) from the logged data.


9. Computing the SCI Score and Saving Metrics

The SCI score is calculated using the previously defined formula:

SCI = ((energy_consumed * I) + M) / R

All collected metrics are stored in a structured DataFrame:

data = {
    "Metric": ["Energy Consumed (kWh)", "Carbon Emissions (kg CO₂)", "SCI Score", "Memory Usage (%)", "RAM Used (GB)"],
    "Value": [energy_consumed, emissions, SCI, system_usage_after["memory"], system_usage_after["ram_used"]],
}
df_metrics = pd.DataFrame(data)

This makes it easy to store and analyze results.


10. Data Visualization

The script generates two graphs:

  1. Bar graph showing energy consumption and emissions

  2. Line graph showing memory usage before and after processing

plt.figure(figsize=(10, 5))
sns.barplot(x=df_metrics["Metric"], y=df_metrics["Value"], palette="coolwarm")
plt.title("Carbon Footprint & Energy Consumption")
plt.xticks(rotation=30)
plt.show()

plt.figure(figsize=(10, 5))
time_series = [system_usage_before["memory"], system_usage_after["memory"]]
plt.plot(["Before Processing", "After Processing"], time_series, marker="o", linestyle="-", color="blue")
plt.title("Memory Usage Over Time")
plt.xlabel("Stage")
plt.ylabel("Memory Usage (%)")
plt.show()


Final Output

The results are saved to a CSV file:

df_metrics.to_csv(os.path.join(log_dir, "sci_results.csv"), index=False)
print("Results saved to sci_results.csv")

This allows users to analyze the energy efficiency of the process.


Project: Energy Profiling of Image Processing Tasks- Visualization : CODE-LINK

This script evaluates energy consumption, CPU usage, memory usage, and execution time for different image processing methods. The goal is to highlight the efficiency differences between low-efficiency (brute force) and high-efficiency (optimized) techniques using:

  • CodeCarbon → Tracks power usage and emissions.

  • psutil → Monitors CPU & RAM usage.

  • OpenCV (cv2) → Performs image processing.

  • Matplotlib & Seaborn → Creates visual comparisons.


Step 1: Environment Setup & Logging

Before running any process, we ensure a clean working environment. If a lock file from a previous CodeCarbon run exists, we remove it. This prevents conflicts in logging energy consumption.

import os
import time
import psutil
import numpy as np
import cv2
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from codecarbon import EmissionsTracker

# Remove existing lock file (Prevents CodeCarbon errors)
lock_file = "/tmp/.codecarbon.lock"
if os.path.exists(lock_file):
    os.remove(lock_file)

# Ensure logs directory exists
log_dir = "logs"
os.makedirs(log_dir, exist_ok=True)

**🔹 Why?
**✔ CodeCarbon creates a lock file during execution, which might interfere with new runs.
✔ Creating a log directory ensures energy data is stored for future analysis.


Step 2: Energy & Resource Tracking Setup

To monitor energy usage, we initialize the EmissionsTracker from CodeCarbon. It logs power consumption and carbon emissions while our script runs.

tracker = EmissionsTracker(
    output_dir=log_dir,     
    output_file="carbon_emission.csv",
    measure_power_secs=1,    
    tracking_mode="process", 
    allow_multiple_runs=True 
)

**🔹 Why?
**✔ Helps analyze the environmental impact of different processing methods.
✔ Captures energy usage per second for fine-grained monitoring.


Step 3: Generating a Synthetic Image for Processing

Instead of using real images, we generate a random grayscale image (512x512 pixels). This ensures we always have a consistent test case.


image = np.random.randint(0, 256, (512, 512), dtype=np.uint8)

**🔹 Why?
**✔ Using a fixed synthetic image ensures reproducibility.
✔ A grayscale image (1 channel) simplifies computation compared to RGB (3 channels).


Step 4: Monitoring System Resource Usage (CPU & Memory)

Before and after each image processing task, we record CPU and memory usage using psutil.

def get_system_usage():
    """
    Retrieves current CPU and memory usage.
   
    Returns:
        dict: Dictionary containing CPU (%) and Memory (%) usage.
    """
    return {
        "cpu": psutil.cpu_percent(interval=1),  # CPU utilization in percentage
        "memory": psutil.virtual_memory().percent  # RAM usage in percentage
    }

**🔹 Why?
**✔ Provides real-time CPU and RAM usage data.
✔ Helps compare resource utilization across different methods.


Step 5: Implementing Image Processing Methods

Low-Efficiency Processing (Brute Force)

This method applies multiple redundant transformations inside a loop, making it inefficient.

def process_image(image, efficiency="low"):
    """
    Processes an image using either low-efficiency or high-efficiency methods.
   
    Args:
        image (numpy.ndarray): Input grayscale image.
        efficiency (str): "low" for inefficient processing, "high" for optimized processing.

    Returns:
        dict: Dictionary containing execution time, CPU usage, and memory usage.
    """
    start_time = time.time()
    system_usage_before = get_system_usage()
    height, width = image.shape[:2]  # Get image dimensions

    if efficiency == "low":
        # Inefficient method: Applies unnecessary repetitive operations
        for in range(200):
            blurred = cv2.GaussianBlur(image, (5, 5), 0)  # Blurring
            rotated = cv2.rotate(blurred, cv2.ROTATE
90_CLOCKWISE)  # Rotating
            rotated = cv2.resize(rotated, (width, height))  # Resizing
            blended = cv2.addWeighted(blurred, 0.5, rotated, 0.5, 0)  # Blending
    else:
        # Optimized method: Performs minimal necessary processing
        blurred = cv2.GaussianBlur(image, (5, 5), 0)
        edges = cv2.Canny(blurred, 100, 200)  # Detects edges

    end_time = time.time()
    system_usage_after = get_system_usage()

    return {
        "time": round(end_time - start_time, 4),
        "cpu_before": system_usage_before["cpu"],
        "cpu_after": system_usage_after["cpu"],
        "memory_before": system_usage_before["memory"],
        "memory_after": system_usage_after["memory"],
    }

**🔹 Why?
**✔ The low-efficiency method repeatedly processes the same data, wasting resources.
✔ The high-efficiency method minimizes redundant operations, reducing execution time and energy use.


Step 6: Running the Experiment & Collecting Data

We apply both methods and track performance.

tracker.start()

# Process the image using both methods
low_efficiency_metrics = process_image(image, efficiency="low")
high_efficiency_metrics = process_image(image, efficiency="high")

tracker.stop()

✔ The CodeCarbon tracker runs before and after processing to measure energy consumption.


Step 7: Extracting Energy Data

We extract energy and emissions data from the saved logs.

log_file_path = os.path.join(log_dir, "carbon_emission.csv")

if os.path.exists(log_file_path):
    df = pd.read_csv(log_file_path)
    energy_consumed = df["energy_consumed"].iloc[-1] if "energy_consumed" in df.columns else 0
    emissions = df["emissions"].iloc[-1] if "emissions" in df.columns else 0
else:
    energy_consumed = emissions = None

✔ Helps quantify the energy footprint of each method.


Step 8: Comparing & Visualizing Performance

Comparison Table

MetricLow-EfficiencyHigh-Efficiency
CPU Usage (Before)X%Y%
CPU Usage (After)X+Δ%Y+Δ%
Memory Usage (Before)X%Y%
Memory Usage (After)X+Δ%Y+Δ%
Processing TimeHighLow
Energy ConsumptionHighLow
Carbon EmissionsHighLow

Bar Chart Visualization

sns.set(style="darkgrid")
fig, axes = plt.subplots(2, 2, figsize=(12, 8))

axes[0, 0].bar(["Emissions (kg CO₂)", "Energy Consumed (kWh)"], [emissions, energy_consumed], color=["blue", "purple"])
axes[0, 1].bar(["Low Eff", "High Eff"], [low_efficiency_metrics["cpu_after"], high_efficiency_metrics["cpu_after"]])
axes[1, 0].bar(["Low Eff", "High Eff"], [low_efficiency_metrics["memory_after"], high_efficiency_metrics["memory_after"]])
axes[1, 1].bar(["Low Eff", "High Eff"], [low_efficiency_metrics["time"], high_efficiency_metrics["time"]])

plt.show()

Visualizes the performance differences between both methods.


Conclusion:

As AI and computational workloads grow, optimizing energy consumption is crucial for sustainable development. CodeCarbon leverages AI/ML-based estimation models to track power usage across CPUs, GPUs, and cloud platforms while factoring in regional carbon intensity. By profiling energy consumption in deep learning and image processing, it helps identify inefficiencies and optimize workloads for lower emissions.

This enables developers to make informed choices, such as using energy-efficient hardware or greener cloud providers. Integrating carbon tracking tools like CodeCarbon ensures that technological advancements remain environmentally responsible, promoting a sustainable future in AI and software development.


0
Subscribe to my newsletter

Read articles from ADITYA BHATTACHARYA directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

ADITYA BHATTACHARYA
ADITYA BHATTACHARYA

A fervent and a passionate fellow for Computer Science and Research, trying to bridge the gap between real life and code life. From print("Hello World ! ") to writing Scalable Language Codes, I am yet to discover the emerging future of AI in our forecasting life of Modern Technology.