Skip to main content

Image Quality Assessment using BRISQUE algorithm

Project description

Blind/Referenceless Image Spatial Quality Evaluator (BRISQUE)

DOI

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 brisque automatically installed opencv-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

  1. Normalize scores: Ensure all scores use the same scale
  2. Balance quality levels: Include images across the quality spectrum
  3. Use representative images: Training images should match your target domain
  4. Validate on held-out data: Keep 20% of data for testing
  5. Experiment with parameters: Try different svm_c and svm_gamma values

API Reference

BRISQUE Class

BRISQUE(url=False, model_path=None)

Parameters:

  • url (bool): If True, accept URLs in score(). 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 score
  • add_dataset(image_dir, scores_file, image_column="image", score_column="score"): Load from directory and CSV
  • train(svm_c=1.0, svm_gamma=0.1, svm_epsilon=0.1, kernel="rbf"): Train the model
  • save_model(svm_path, norm_path): Save trained model
  • evaluate(images, scores): Evaluate model, returns dict with RMSE, PLCC, SROCC
  • clear(): 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

brisque-0.2.0.tar.gz (158.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

brisque-0.2.0-py3-none-any.whl (155.5 kB view details)

Uploaded Python 3

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

Hashes for brisque-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0132097db969874d531b0a86bf96a25035f6fbe7333b1c0b2bccea51d588012a
MD5 d67624b930bb8894d01d6c0e301f6827
BLAKE2b-256 cc4bab4cb5141e83b097f79bdebbe5b4eaa5224cfb4ecad5aa830097070a4676

See more details on using hashes here.

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

Hashes for brisque-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56f1839e5179a294d0598d63b2ee488fcbedeac7cee3e32c7c8d06c30a6269e1
MD5 67e4aaacc5af0db0f1af126ac5d0aaeb
BLAKE2b-256 d99d18a793cfce3f37acf2913b3699443e3a1b19db25fef0f6388da52d6cd364

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page