Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Finding the Peak Signal-to-Noise Ratio (PSNR) using Python
Peak Signal-to-Noise Ratio (PSNR) is a widely used metric to measure the quality of digital signals, particularly for images and video. It quantifies the difference between original and distorted versions of a signal, measuring the amount of noise added through compression, transmission, or processing. PSNR is utilized in multimedia applications, video compression, and image processing. In this article, we'll explore two methods for calculating PSNR in Python.
Understanding Peak Signal-to-Noise Ratio
PSNR is a standard metric for evaluating image or video quality. It's frequently used in compression algorithms to compare the quality of compressed output against the original input. Higher PSNR values indicate better quality, as distortion becomes less noticeable.
PSNR is calculated using the Mean Squared Error (MSE) between original and distorted images, expressed in decibels (dB). The formula is ?
PSNR = 20 * log10(MAX) - 10 * log10(MSE)
Where ?
MAX Maximum possible pixel value (255 for 8-bit images)
MSE Mean Squared Error between corresponding pixels
Method 1: Using Mean Squared Error (MSE)
This approach manually calculates PSNR using the MSE formula. It provides direct control over the calculation process ?
import numpy as np
def calculate_psnr(original, distorted):
# Calculate MSE
mse = np.mean((original - distorted) ** 2)
# Handle identical images
if mse == 0:
return float('inf')
# Calculate PSNR
max_pixel = 255.0
psnr = 20 * np.log10(max_pixel / np.sqrt(mse))
return psnr
# Example with sample data
original = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
noise = np.random.normal(0, 10, original.shape)
distorted = np.clip(original + noise, 0, 255).astype(np.uint8)
psnr_value = calculate_psnr(original, distorted)
print(f"PSNR: {psnr_value:.2f} dB")
PSNR: 28.15 dB
Method 2: Using Scikit-Image Library
The scikit-image library provides a built-in function for PSNR calculation, offering a more convenient approach ?
import numpy as np
from skimage.metrics import peak_signal_noise_ratio
def calculate_psnr_skimage(original, distorted):
return peak_signal_noise_ratio(original, distorted)
# Example with sample data
original = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
noise = np.random.normal(0, 10, original.shape)
distorted = np.clip(original + noise, 0, 255).astype(np.uint8)
psnr_value = calculate_psnr_skimage(original, distorted)
print(f"PSNR using scikit-image: {psnr_value:.2f} dB")
PSNR using scikit-image: 28.15 dB
Working with Real Images
Here's how to apply PSNR calculation to actual image files ?
import cv2
import numpy as np
from skimage.metrics import peak_signal_noise_ratio
def compare_images(image1_path, image2_path):
# Read images
img1 = cv2.imread(image1_path)
img2 = cv2.imread(image2_path)
if img1 is None or img2 is None:
print("Error: Could not load images")
return None
# Resize to same dimensions
height, width = 256, 256
img1 = cv2.resize(img1, (width, height))
img2 = cv2.resize(img2, (width, height))
# Calculate PSNR
psnr = peak_signal_noise_ratio(img1, img2)
return psnr
# Usage example (requires actual image files)
# psnr_score = compare_images('original.jpg', 'compressed.jpg')
# print(f"Image PSNR: {psnr_score:.2f} dB")
PSNR Interpretation
| PSNR Range (dB) | Image Quality | Typical Use Case |
|---|---|---|
| Above 40 | Excellent | Lossless compression |
| 30-40 | Good | High-quality compression |
| 20-30 | Fair | Moderate compression |
| Below 20 | Poor | Heavy compression |
Conclusion
PSNR is a fundamental metric for assessing digital signal quality in image and video processing. Use the manual MSE approach for educational purposes or custom implementations, and leverage scikit-image's built-in function for production applications. Higher PSNR values indicate better quality preservation.
