Image Quality Assessment using BRISQUE algorithm
Project description
Blind/Referenceless Image Spatial Quality Evaluator (BRISQUE)
BRISQUE is a no-reference image quality score.
🆕 What's New in v0.2.0
Flexible OpenCV Dependencies
Starting with v0.2.0, BRISQUE no longer forces a specific OpenCV variant. This allows you to use whichever OpenCV package best suits your environment.
| OpenCV Variant | Best For |
|---|---|
opencv-python |
Desktop applications with GUI support |
opencv-python-headless |
Servers, Docker, CI/CD (no GUI) |
opencv-contrib-python |
Desktop with extra OpenCV modules |
opencv-contrib-python-headless |
Servers with extra modules |
Why this change?
- OpenCV variants are mutually exclusive - installing one removes others
- Previous versions required
opencv-python, causing conflicts for users with different variants - Server/headless environments don't need GUI dependencies from
opencv-python
Installation Options
Option 1: Install with OpenCV (Recommended for new users)
pip install brisque[opencv-python] # Desktop applications
pip install brisque[opencv-python-headless] # Servers / Docker (recommended)
pip install brisque[opencv-contrib-python] # With extra OpenCV modules
pip install brisque[opencv-contrib-python-headless] # Servers with extra modules
Option 2: Use existing OpenCV installation
# If you already have OpenCV installed
pip install opencv-python-headless # or any variant you prefer
pip install brisque # will use your existing OpenCV
Option 3: Install OpenCV separately (for Docker/corporate environments)
# In your Dockerfile or controlled environment
pip install opencv-python-headless
pip install brisque # Uses the pre-installed OpenCV
⚠️ Note: BRISQUE requires OpenCV to function. If you install brisque without OpenCV, you'll get a helpful error message with installation instructions.
Migration from v0.1.x
If you're upgrading from v0.1.x or earlier:
Scenario A: Standard desktop usage (no changes needed)
# Your existing OpenCV will be detected and used
pip install --upgrade brisque
Scenario B: Clean install or server environment
# Uninstall old version
pip uninstall brisque
# Install with your preferred OpenCV variant
pip install brisque[opencv-python-headless] # Recommended for servers
Scenario C: Docker/CI environments
# In your Dockerfile
RUN pip install opencv-python-headless
RUN pip install brisque
What changed:
- v0.1.x:
pip install brisqueautomatically installedopencv-python - v0.2.0: OpenCV is no longer auto-installed - you choose your variant
Code compatibility: No changes needed! Your existing code continues to work:
from brisque import BRISQUE # Still works exactly the same
obj = BRISQUE(url=False)
score = obj.score(image)
Installation
Quick Start:
# For servers/Docker (recommended):
pip install brisque[opencv-python-headless]
# For desktop applications:
pip install brisque[opencv-python]
See the Installation Options section above for more details.
Usage
1. Image Quality Assessment on Local Images
from brisque import BRISQUE
obj = BRISQUE(url=False)
obj.score("<Ndarray of the Image>")
2. Image Quality Assessment on Web Images
from brisque import BRISQUE
obj = BRISQUE(url=True)
obj.score("<URL for the Image>")
3. Using Custom Trained Models
from brisque import BRISQUE
obj = BRISQUE(url=False, model_path={
"svm": "path/to/custom_svm.txt",
"normalize": "path/to/custom_normalize.pickle"
})
obj.score(image)
Examples
Local Image
from brisque import BRISQUE
import numpy as np
from PIL import Image
img_path = "brisque/tests/sample-image.jpg"
img = Image.open(img_path)
ndarray = np.asarray(img)
obj = BRISQUE(url=False)
obj.score(img=ndarray)
Output:
34.84883848208594
URL
from brisque import BRISQUE
URL = "https://www.mathworks.com/help/examples/images/win64/CalculateBRISQUEScoreUsingCustomFeatureModelExample_01.png"
obj = BRISQUE(url=True)
obj.score(URL)
Output:
71.73427549219988
Training Custom Models
The BRISQUETrainer class allows you to train custom BRISQUE models using your own image quality datasets. This is useful when you need a model tailored to specific image types or distortion patterns.
When to Train a Custom Model
- Domain-specific images (medical, satellite, underwater, etc.)
- Specific distortion types not well-represented in the default model
- Custom quality scales or scoring methodologies
- Research purposes requiring reproducible quality assessment
Step-by-Step Guide: Training a Custom BRISQUE Model
Step 1: Install the Package
pip install brisque
Step 2: Prepare Your Dataset
Organize your images and quality scores. You'll need:
- A directory containing your images
- A CSV file with image filenames and their quality scores
Dataset structure:
my_dataset/
├── images/
│ ├── img_001.jpg
│ ├── img_002.jpg
│ ├── img_003.jpg
│ └── ...
└── scores.csv
CSV format (scores.csv):
image,score
img_001.jpg,23.5
img_002.jpg,45.2
img_003.jpg,31.8
img_004.jpg,12.1
...
Note on Quality Scores: Lower scores should indicate better quality. Use consistent scoring methodology across all images. Common scales include:
- MOS (Mean Opinion Score): 1-5 scale
- DMOS (Differential MOS): 0-100 scale
- Custom scales specific to your application
Step 3: Create a Training Script
Create a file called train_brisque.py:
from brisque import BRISQUETrainer, BRISQUE
import numpy as np
# Initialize the trainer
trainer = BRISQUETrainer()
# Load your dataset
trainer.add_dataset(
image_dir="my_dataset/images",
scores_file="my_dataset/scores.csv",
image_column="image", # column name for image filenames
score_column="score" # column name for quality scores
)
print(f"Loaded {len(trainer.features)} images")
# Train the model with custom SVM parameters
trainer.train(
svm_c=10.0, # Regularization (higher = less tolerance for errors)
svm_gamma=0.1, # RBF kernel coefficient
svm_epsilon=0.1, # Epsilon-tube for SVR
kernel="rbf" # Kernel type: "rbf", "linear", "poly", or "sigmoid"
)
# Save the trained model
trainer.save_model(
svm_path="custom_model/svm.txt",
norm_path="custom_model/normalize.pickle"
)
print("Model saved successfully!")
Step 4: Run the Training
python train_brisque.py
Step 5: Evaluate the Model (Optional)
Evaluate your model on a separate test set:
from brisque import BRISQUETrainer
import numpy as np
from PIL import Image
# After training, evaluate on test data
test_images = [np.array(Image.open(f"test_images/img_{i}.jpg")) for i in range(10)]
test_scores = [25.3, 42.1, 18.9, ...] # ground truth scores
metrics = trainer.evaluate(test_images, test_scores)
print(f"RMSE: {metrics['rmse']:.4f}") # Root Mean Square Error (lower is better)
print(f"PLCC: {metrics['plcc']:.4f}") # Pearson correlation (closer to 1 is better)
print(f"SROCC: {metrics['srocc']:.4f}") # Spearman correlation (closer to 1 is better)
Step 6: Use Your Trained Model
from brisque import BRISQUE
import numpy as np
from PIL import Image
# Load your custom model
obj = BRISQUE(url=False, model_path={
"svm": "custom_model/svm.txt",
"normalize": "custom_model/normalize.pickle"
})
# Score a new image
image = np.array(Image.open("new_image.jpg"))
quality_score = obj.score(image)
print(f"Quality Score: {quality_score}")
Step 7: Integrate into Your Pipeline
from brisque import BRISQUE
import numpy as np
# Initialize once at application startup
brisque = BRISQUE(url=False, model_path={
"svm": "custom_model/svm.txt",
"normalize": "custom_model/normalize.pickle"
})
# Use throughout your application
def assess_image_quality(image_array: np.ndarray) -> float:
"""Assess image quality using custom BRISQUE model."""
return brisque.score(image_array)
# Example usage
for image_path in image_paths:
img = np.array(Image.open(image_path))
score = assess_image_quality(img)
print(f"{image_path}: {score:.2f}")
Alternative: Training with Individual Images
If you prefer to add images individually instead of from a CSV:
from brisque import BRISQUETrainer
import numpy as np
from PIL import Image
trainer = BRISQUETrainer()
# Add images one by one
images = ["img1.jpg", "img2.jpg", "img3.jpg"]
scores = [23.5, 45.2, 31.8]
for img_path, score in zip(images, scores):
img = np.array(Image.open(img_path))
trainer.add_image(img, score)
# Train and save
trainer.train()
trainer.save_model("custom_svm.txt", "custom_normalize.pickle")
Training Tips
Data Requirements
| Dataset Size | Expected Performance |
|---|---|
| 2-10 images | Minimal - for testing only |
| 50-100 images | Basic functionality |
| 200+ images | Good performance |
| 500+ images | Optimal performance |
SVM Parameter Tuning
| Parameter | Effect | Typical Range |
|---|---|---|
svm_c |
Regularization strength | 0.1 - 100 |
svm_gamma |
RBF kernel width | 0.001 - 1 |
svm_epsilon |
Tolerance for errors | 0.01 - 0.5 |
kernel |
Kernel function | "rbf" (default), "linear" |
Best Practices
- Normalize scores: Ensure all scores use the same scale
- Balance quality levels: Include images across the quality spectrum
- Use representative images: Training images should match your target domain
- Validate on held-out data: Keep 20% of data for testing
- Experiment with parameters: Try different
svm_candsvm_gammavalues
API Reference
BRISQUE Class
BRISQUE(url=False, model_path=None)
Parameters:
url(bool): If True, accept URLs inscore(). If False, accept numpy arrays. Default: False.model_path(dict, optional): Custom model paths with keys:"svm": Path to SVM model file"normalize": Path to normalization parameters file
Methods:
score(img): Compute quality score for an image
BRISQUETrainer Class
BRISQUETrainer()
Methods:
add_image(image, score): Add single image with quality scoreadd_dataset(image_dir, scores_file, image_column="image", score_column="score"): Load from directory and CSVtrain(svm_c=1.0, svm_gamma=0.1, svm_epsilon=0.1, kernel="rbf"): Train the modelsave_model(svm_path, norm_path): Save trained modelevaluate(images, scores): Evaluate model, returns dict with RMSE, PLCC, SROCCclear(): Clear all data and model
Testing
Run the test suite:
# Run all tests
pytest brisque/tests/ -v
# Run specific test file
pytest brisque/tests/test_trainer.py -v
# Run with coverage
pytest brisque/tests/ -v --cov=brisque
How BRISQUE Works
BRISQUE extracts 36 features from each image:
- 18 features from the original scale (MSCN coefficients)
- 18 features from the half-scale (downsampled image)
Features are based on:
- Mean Subtracted Contrast Normalized (MSCN) coefficients
- Pairwise products (horizontal, vertical, diagonal)
- Asymmetric Generalized Gaussian Distribution fitting
The SVM regression model maps these features to quality scores.
Citation
If you use this package in your research, please cite:
@software{brisque2024,
author = {Guha, Rehan},
title = {BRISQUE: Blind/Referenceless Image Spatial Quality Evaluator},
year = {2024},
doi = {10.5281/zenodo.11104461}
}
License
Apache-2.0
A good place to know how BRISQUE works : LearnOpenCV
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file brisque-0.2.0.tar.gz.
File metadata
- Download URL: brisque-0.2.0.tar.gz
- Upload date:
- Size: 158.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0132097db969874d531b0a86bf96a25035f6fbe7333b1c0b2bccea51d588012a
|
|
| MD5 |
d67624b930bb8894d01d6c0e301f6827
|
|
| BLAKE2b-256 |
cc4bab4cb5141e83b097f79bdebbe5b4eaa5224cfb4ecad5aa830097070a4676
|
File details
Details for the file brisque-0.2.0-py3-none-any.whl.
File metadata
- Download URL: brisque-0.2.0-py3-none-any.whl
- Upload date:
- Size: 155.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56f1839e5179a294d0598d63b2ee488fcbedeac7cee3e32c7c8d06c30a6269e1
|
|
| MD5 |
67e4aaacc5af0db0f1af126ac5d0aaeb
|
|
| BLAKE2b-256 |
d99d18a793cfce3f37acf2913b3699443e3a1b19db25fef0f6388da52d6cd364
|