Contrast Stretching

Theory

Contrast stretching is an image enhancement technique used to improve the visibility of features by expanding the range of intensity levels. Images with low contrast (pixel values clustered within a narrow range) often appear dull or washed out, and contrast stretching redistributes the intensities to utilize the full dynamic range.

1. How it Works

The original pixel intensity values, denoted by r, are mapped from an input range [r_min, r_max] to an output range [s_min, s_max] (usually 0–255). The transformation formula is:

s = (r - r_min) / (r_max - r_min) * (s_max - s_min) + s_min

2. Applications

  • Enhancing low-contrast images in medical imaging (X-rays, MRI scans).
  • Improving satellite and aerial imagery for better feature detection.
  • Preparing images for computer vision tasks like segmentation and object recognition.
  • General photography enhancement to make images visually appealing.

By stretching pixel intensities across the available range, subtle details in shadows and highlights become more pronounced, making the image more informative.

Python Code


import cv2
import numpy as np
import matplotlib.pyplot as plt

def contrast_stretching(img, s_min=0, s_max=255):
    """
    Perform contrast stretching on a grayscale image.
    """
    r_min, r_max = np.min(img), np.max(img)
    stretched = (img - r_min) / (r_max - r_min) * (s_max - s_min) + s_min
    return np.uint8(stretched)

# Load grayscale image
img = cv2.imread('assets/asd.jpeg', cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not found!"

# Apply contrast stretching
stretched_img = contrast_stretching(img)

# Plot images and histograms
plt.figure(figsize=(12, 8))

# Original Image and Histogram
plt.subplot(2, 2, 1)
plt.imshow(img, cmap='gray')
plt.title("Original Image")
plt.axis('off')

plt.subplot(2, 2, 2)
plt.hist(img.ravel(), bins=256, range=(0, 256), color='black')
plt.title("Original Histogram")
plt.xlabel("Intensity")
plt.ylabel("Frequency")

# Stretched Image and Histogram
plt.subplot(2, 2, 3)
plt.imshow(stretched_img, cmap='gray')
plt.title("Contrast Stretched Image")
plt.axis('off')

plt.subplot(2, 2, 4)
plt.hist(stretched_img.ravel(), bins=256, range=(0, 256), color='black')
plt.title("Stretched Histogram")
plt.xlabel("Intensity")
plt.ylabel("Frequency")

plt.tight_layout()
plt.show()
        

Example Output