Image Histograms and Equalization Example with OpenCV in Python

      An image histogram represents a graphical distribution of pixel intensities in an image. Pixel range can be 0 to 255 that provides 256 possible intensity level for each color channel. Histogram provides an information about the overall contrast, brightness, and intensity and tonal distribution of an image. 

    By analyzing the distribution of pixel intensities, we can adjust image contrast, brightness, or apply techniques like histogram equalization to improve the overall quality of the image.

    OpenCV API provides functions to calculate image histogram and apply equalization techniques. In this tutorial, you'll briefly learn how to build image histogram and apply equalization method by using OpenCV in Python.
The tutorial covers:

  1. Grayscale histogram
  2. Color histogram
  3. Histogram equalization
  4. Source code listing

    We'll start by loading the required libraries.


import cv2
from matplotlib import pyplot as plt   
   

    The following code shows how to load an image and display it in a plot. Here, you have to change your file path. Since I use Matplotlib library to display images, the image color order needs to be adjusted into the Matplotlib type.
 

file = "/Users/user/Desktop/image.jpg" 
  
# Load an image
img = cv2.imread(file)
 
# OpenCV to Matplotlib color adjustment
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
plt.imshow(img)
plt.show() 

 

Grayscale histogram
 
    We'll convert the image into the grayscale and calculate histogram by using cv2.calcHist() function. The function takes several arguments, including the image, the channel for which the histogram is computed ([0] for grayscale), a mask (set to None for the entire image), the number of bins (256 in this case, representing the intensity levels), and the range of pixel values (from 0 to 256). After taking histogram values we can visualize it in a graph.
 
 
# Load as grayscale image
image = cv2.imread(file, 0) 

# Calculate the histogram
histogram = cv2.calcHist(image, [0], None, [256], [0, 256])

# Plot the histogram
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.plot(histogram, color='black')
plt.xlabel('Intensity')
plt.ylabel('Frequency')
plt.title('Image Histogram')
plt.tight_layout()
plt.show() 
   

Color histogram

    Next, we'll apply histogram calculation to all of channels of image and visualize it in graph. Below code shows how to split image into RGB and apply histogram calculation for each channel.

 
# Load image 
image = cv2.imread(file)  

# Split the image channels
channels = cv2.split(image)

# Define channel colors
colors = ('r', 'g', 'b')

plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) 
plt.title('Original Image')
plt.subplot(1, 2, 2)

# Plot the histograms for each channel
for channel, color in zip(channels, colors):
    histogram = cv2.calcHist(channel, [0], None, [256], [0, 256])
    plt.plot(histogram, color=color, label=color)

# Set the labels and title
plt.xlabel('Intensity')
plt.ylabel('Frequency')
plt.title('Image Histogram')
plt.tight_layout()
plt.show()
  


Histogram equalization

    Equalization process includes computing the cumulative distribution function (CDF) of the histogram, normalizing the CDF, and mapping normalized CDF values to obtain the equalized image.

    To apply histrgram equalization, we can use cv2.equalizeHist() function. Below example shows how to perfrom equalization on grayscale image.  

 
# Load the grayscale image
image = cv2.imread(file, cv2.IMREAD_GRAYSCALE)

# Apply histogram equalization
equalized = cv2.equalizeHist(image)

# Display the original and equalized images
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(equalized, cmap='gray')
plt.title('Equalized Image')
plt.tight_layout()
plt.show()

    Next we apply histogram equalization on color image. Here we apply equalization process for each color and merge equalized channels to build a final image.


# Load the RGB image
image = cv2.imread(file)

# Split the image channels
channels = cv2.split(image)

# Apply histogram equalization to each channel
equalized_channels = []
for channel in channels:
    equalized_channel = cv2.equalizeHist(channel)
    equalized_channels.append(equalized_channel)

# Merge the equalized channels back into an RGB image
equalized_image = cv2.merge(equalized_channels)

# Display the original and equalized images
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(equalized_image, cv2.COLOR_BGR2RGB))
plt.title('Equalized Image')
plt.tight_layout()
plt.show()

    In this tutorial, we've briefly learned how to perform image histogram and histgam eqaulization with OpenCV functions in Python. The full source code is listed below. 

 
Source code listing
 
  
import cv2
from matplotlib import pyplot as plt
 

file = "/Users/user/Desktop/image.jpg"  
 
# Load an image
img = cv2.imread(file)
# OpenCV to Matplotlib color adjustment
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)   
plt.imshow(img)
plt.show()
 
# Grayscale image histogram calculation
# Load as grayscale image
image = cv2.imread(file, 0) 

# Calculate the histogram
histogram = cv2.calcHist(image, [0], None, [256], [0, 256])

# Plot the histogram
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.plot(histogram, color='black')
plt.xlabel('Intensity')
plt.ylabel('Frequency')
plt.title('Image Histogram')
plt.tight_layout()
plt.show() 
 
 
# Color image histogram calculation
# Load image 
image = cv2.imread(file)  

# Split the image channels
channels = cv2.split(image)

# Define channel colors
colors = ('r', 'g', 'b')

plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) 
plt.title('Original Image')
plt.subplot(1, 2, 2)

# Plot the histograms for each channel
for channel, color in zip(channels, colors):
    histogram = cv2.calcHist(channel, [0], None, [256], [0, 256])
    plt.plot(histogram, color=color, label=color)

# Set the labels and title
plt.xlabel('Intensity')
plt.ylabel('Frequency')
plt.title('Image Histogram')
plt.tight_layout()
plt.show() 
 
 
# Grayscale image histogram equalization 
# Load the grayscale image
image = cv2.imread(file, cv2.IMREAD_GRAYSCALE)

# Apply histogram equalization
equalized = cv2.equalizeHist(image)

# Display the original and equalized images
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(equalized, cmap='gray')
plt.title('Equalized Image')
plt.tight_layout()
plt.show()

 
# Color image histogram equalization  
# Load the RGB image
image = cv2.imread(file)

# Split the image channels
channels = cv2.split(image)

# Apply histogram equalization to each channel
equalized_channels = []
for channel in channels:
    equalized_channel = cv2.equalizeHist(channel)
    equalized_channels.append(equalized_channel)

# Merge the equalized channels back into an RGB image
equalized_image = cv2.merge(equalized_channels)

# Display the original and equalized images
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Image')
plt.subplot(1, 2, 2)
plt.imshow(cv2.cvtColor(equalized_image, cv2.COLOR_BGR2RGB))
plt.title('Equalized Image')
plt.tight_layout()
plt.show() 
       
 
 


No comments:

Post a Comment