Skip to main content

PSNR-HVS-M, PSNR-HA and PSNR-HMA metrics for NumPy and PyTorch

cibuildwheel python_versions pypi license

Accelerated Python package for computing several image metrics based on human perception with backends in NumPy, PyTorch and C++.

This is an implementation of the PSNR-HVS, PSNR-HVS-M, PSNR-HA and PSNR-HMA metrics developed by Nikolay Ponomarenko.

The values produced by this library have been cross-checked against the results within the TID2013 dataset. (See the folder tid2013_results.) The only difference is that this library follows the common convention that PSNR for identical signals equals 100.0.

A miniscule discrepancy for PSNR-HMA (<0.01dB on average) is under investigation.

Bibliography

Installation

psnr_hvsm supports Python 3.10-3.15. Packages are distributed on PyPi. Be sure to have an up-to-date pip to be able to install the correct packages on Linux:

python -m pip install --upgrade pip
pip install psnr_hvsm

With PyTorch support:

pip install psnr_hvsm[torch]

NumPy and PyTorch support policy

The NumPy requirement carries no upper bound. The compiled extension is built against NumPy 2 headers with a fixed backward-compatible ABI target, so a single wheel serves both NumPy 1.x and NumPy 2.x runtimes. Installing the package never forces a downgrade from NumPy 2.x, and its runtime floor is numpy>=1.19. Note that NumPy 1.x itself is only installable on Python 3.10-3.12: the last 1.x release ships wheels only that far, so on Python 3.13 and newer the runtime resolves NumPy 2.x.

PyPI publishes PyTorch wheels for Python 3.10-3.14 only, so the torch extra is unavailable on 3.15 and the PyTorch backend cannot be installed there.

MSVC runtime on Windows

Linux manylinux wheels bundle libstdc++ via auditwheel. The Windows wheels do not bundle the MSVC C++ runtime: CMake installs only the FFTW DLLs into the wheel. On CPython 3.10-3.14 the package therefore declares msvc-runtime for Windows, which pip installs into the environment along with the package, so no system-wide Visual C++ runtime is required. The MSVC or clang toolchain supplies the CRT when the extension is compiled, which is why it is not a build requirement.

On CPython 3.15 the requirement is not declared. msvc-runtime publishes its wheels per CPython ABI and has no cp315 wheel, so asking for it there would leave the newest supported interpreter uninstallable. A CPython install from python.org brings the C runtime it was built with (its installer updates the C Runtime Library on the machine when one is needed), so 3.15 works without anything extra. If an import nevertheless fails with a missing vcruntime140.dll or msvcp140.dll - a possibility with the minimal layouts such as the embeddable package, MSYS2 or NuGet-based installs - install the Microsoft Visual C++ 2015-2022 redistributable for your architecture, or use CPython 3.10-3.14, where the requirement is declared.

Usage

Command line

Command line support is an extra that pulls imageio:

pip install psnr_hvsm[command_line]
python -m psnr_hvsm original.png distorted.png

Choosing a backend

The backend can be set by setting the PSNR_HVSM_BACKEND environment variable. Valid backends are:

  • numpy - pure NumPy using scipy.fft for DCT
  • cpp - C++ using FFTW3
  • torch - PyTorch; install as psnr_hvsm[torch] to install PyTorch as well
export PSNR_HVSM_BACKEND=torch
python -m psnr_hvsm original.png distorted.png

The default device for PyTorch is cuda but it can be changed by setting the PSNR_HVSM_TORCH_DEVICE environment variable.

As a library

The function psnr_hvs_hvsm accepts images as single-channel floating-point NumPy arrays. The images need to be normalised, i.e. the values need to be in the range [0,1]. This can be achieved by converting the image to float and dividing by the maximum value given the bit depth. For 8 bits per component this is 255.

The images must be padded to a multiple of 8 in each dimension.

from imageio import imread
from psnr_hvsm import psnr_hvs_hvsm, bt601ycbcr

image1 = imread('tests/baboon.png').astype(float) / 255
image2 = imread('tests/baboon_msk.png').astype(float) / 255

image1_y, *_ = bt601ycbcr(image1)
image2_y, *_ = bt601ycbcr(image2)

psnr_hvs, psnr_hvsm = psnr_hvs_hvsm(image1, image2)

print(psnr_hvs, psnr_hvsm)
34.427054505764424 51.64722121999962

If you need to measure PSNR-HVS and PSNR-HVS-M on an RGB image, you need to convert it to an YUV colorspace and pass in only the luma component.

BT.601 conversion precision

When 8-bit RGB input is converted to the BT.601 YCbCr colorspace, the luma and both chroma components are by default rounded to 8-bit code values. This quantisation matches the 8-bit YCbCr pipeline of the reference implementation and is what reproduces the published TID2013 reference values this library is cross-checked against, which is why it remains the default. Every metric output computed with the default is bit-identical to previous releases.

If you are porting the metrics and want to compare against a non-quantised reference, pass precision='float' to compute the same BT.601 matrix arithmetic without the rounding step:

from psnr_hvsm import bt601ycbcr
from psnr_hvsm.compute_all_metrics import compute_all_metrics

image1_y, image1_cb, image1_cr = bt601ycbcr(image1_uint8, precision='float')

psnr_hvs, psnr_hvsm, psnr_ha, psnr_hma, psnr = compute_all_metrics(
    image1_uint8, image2_uint8, precision='float')

The precision option ('8-bit' default, 'float') is accepted by bt601ycbcr in both the NumPy and PyTorch backends with identical semantics, and by the compute_all_metrics entry point, which threads it through every metric that depends on the quantised 8-bit BT.601 YCbCr conversion. It applies only when that conversion runs. For grayscale input or non-uint8 color input, it has no effect.

On the command line the same choice is exposed as --precision {8-bit,float} on python -m psnr_hvsm, and the JSON output (--json) records the requested precision, so batch results are self-describing. The requested precision is applied wherever the quantised conversion runs; for grayscale or non-uint8 color input, the field has no effect.

PyTorch support

The PyTorch backend can be used for use with gradient descent algorithms and computation on GPUs. In order to use the PyTorch backend, either install the package with the torch extra:

pip install psnr_hvsm[torch]

If your PyTorch installation was manual, you need torch-dct in order to use the PyTorch backend:

pip install "torch-dct>=0.1.6"

An important distinction is that the functions that expect 3-channel input now expect (...,C,H,W) format in the PyTorch implementation. The PyTorch backend can be enabled by importing it directly from psnr_hvsm.torch:

import torch
from imageio import imread
from psnr_hvsm.torch import psnr_hvs_hvsm, bt601ycbcr

image1 = imread('tests/baboon.png').astype(float) / 255
image2 = imread('tests/baboon_msk.png').astype(float) / 255

image1 = torch.tensor(image1, device='cuda').moveaxis(-1, -3)  # convert to (N,C,H,W) format
image2 = torch.tensor(image2, device='cuda').moveaxis(-1, -3)  # convert to (N,C,H,W) format

image1_y, *_ = bt601ycbcr(image1)
image2_y, *_ = bt601ycbcr(image2)

psnr_hvs, psnr_hvsm = psnr_hvs_hvsm(image1_y, image2_y)

Alternatively, set the PSNR_HVSM_BACKEND environment variable to torch:

import os
os.environ['PSNR_HVSM_BACKEND'] = 'torch'

from psnr_hvsm import psnr_hvs_hvsm
# rest of code
# ...

Note on gradients

Some operations in the calculation of the HVS-M MSE lead to problems with the gradient and therefore a parameter called masking_epsilon (defaulting to 0.0) has been added to the PyTorch versions of hvs_hvsm_mse_tiles, hvs_hvsm_mse and psnr_hvs_hvsm. Set it to a small value (determined by your own experimentation) if you need the result of HVS-M for gradient descent.

Computing metrics for the TID2013 dataset

If you have a copy of the TID2013 dataset, you can re-verify the metrics for yourself:

python -m psnr_hvsm.tid2013_metrics D:\tid2013\ .\tid2013_results\

Other exported functions

  • hvs_hvsm_mse_tiles - compute HVS and HVS-M scores on all 8x8 tiles in the images, returns an array of numbers
  • hvs_hvsm_mse - compute average HVS and HVS-M scores

Building

Dependencies

psnr_hvsm has several dependencies:

FFTW3 is always fetched by CMake at the pinned release listed in psnr_hvsm/CMakeLists.txt. The remaining, header-only dependencies are installed at pinned, mutually compatible versions when they are not already installed, so a C++ compiler, a current CMake and pip or uv are enough to build from source:

pip install --upgrade -r requirements-build.txt
pip wheel --no-deps -w dist .

If you prefer a conda environment, create the provided one and CMake will discover the dependencies from it instead of fetching them:

conda env create -f psnr_hvsm-dev.yml

Development mode

To install in development mode:

pip install --upgrade -r requirements.txt

Creating Python wheel

pip install --upgrade -r requirements-build.txt
python -m build --wheel

Verifying a clean source build

To build from source in a scratch virtualenv that has no conda environment for CMake to discover and to run the test suite against the result:

./clean-build-check.sh

Running tests on different versions of Python using tox

pip install --upgrade -r requirements-tox.txt
tox --parallel auto

Metadata

Release files for psnr-hvsm 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for psnr-hvsm 0.3.0
File
psnr_hvsm-0.3.0-cp315-cp315-win_amd64.whl CPython 3.15 CPython 3.15 Windows x86-64 Details
psnr_hvsm-0.3.0-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.15 CPython 3.15 Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details
psnr_hvsm-0.3.0-cp314-cp314-win_amd64.whl CPython 3.14 CPython 3.14 Windows x86-64 Details
psnr_hvsm-0.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details
psnr_hvsm-0.3.0-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
psnr_hvsm-0.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 Details
psnr_hvsm-0.3.0-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
psnr_hvsm-0.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details
psnr_hvsm-0.3.0-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
psnr_hvsm-0.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details
psnr_hvsm-0.3.0-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
psnr_hvsm-0.3.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 Details

Total release size: 79.0 MB

Release files / psnr_hvsm-0.3.0-cp315-cp315-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp315-cp315-win_amd64.whl
Size 3.0 MB
Tags CPython 3.15 Windows x86-64
SHA-256 checksum
How to use checksums
4b9346d41faafebe96b55904b50fba9e279c29803c0f2a059c8e6b51bda04650
BLAKE2b-256 checksum
How to use checksums
db62d20219978e7c1623d957f43008e7d06e3b7b9da7f54bbc1aaec6d7454c5f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.15 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
8cb6448e4884c49f77f39f9fc673e87a349ddf79c29eb77eaf018cd2f6458000
BLAKE2b-256 checksum
How to use checksums
568529aa8b95b6119d142f06f9ac4d9538d8f49869868361a97f3131dd271aee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp314-cp314-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp314-cp314-win_amd64.whl
Size 3.0 MB
Tags CPython 3.14 Windows x86-64
SHA-256 checksum
How to use checksums
267c85376269f883e713933776ee558a2994f4e622acdbc0860bfbe711aabd25
BLAKE2b-256 checksum
How to use checksums
3bb47e8cb1e0c4737752390aa79449cc1c69d5c8d7cd96e1c2f0b8fb00e9f652
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.14 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5f030d134e1a6f66079f64112a0c6f442bfd9cbbbdbc7cf86748865a1dd8af89
BLAKE2b-256 checksum
How to use checksums
fb28c6bcd7d95862e7ed44f40eaf847a9886ef04a7d44f624bec709f6ce47cd0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp313-cp313-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp313-cp313-win_amd64.whl
Size 3.0 MB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
67c8c589bc747be5e1768cd22f74f112f75e9669b65bdb8c8109deb3a81ebd00
BLAKE2b-256 checksum
How to use checksums
597a1832f6f1d651b2bb682a5e0050a757439649a42eb724da6347271c0080db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.13 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
a3992f2fe697a5f21ab5a0f8fc935459ca6a7b3de13d5f3f22ff4a26835bafdf
BLAKE2b-256 checksum
How to use checksums
37393a48263d249d68534e4dc7b7d4043d7c178d1448846a936b800eef1948f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp312-cp312-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp312-cp312-win_amd64.whl
Size 3.0 MB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
6552cca8eb470594bcb4b02a37e1bbe6c63346a26e44c2464e0f2970b080d64e
BLAKE2b-256 checksum
How to use checksums
ccca84df70570bb11c046371d12a5c23169aad9ffbb8c32b373b36104bb4d9d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.12 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
9c4754daf63a73f489014c17425f321c9ea1d3bde140de6acd135d6400be6f6d
BLAKE2b-256 checksum
How to use checksums
ee8504c2cb34fa6cdc91e802654b21623a8c75151c9b990ca0f4647412f89a57
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp311-cp311-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp311-cp311-win_amd64.whl
Size 3.0 MB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
3022c9e5ff83e805c966d25879f97c7c2c2f0823c52b17f96041feeff58be29d
BLAKE2b-256 checksum
How to use checksums
772b57a23bd1312d008cfdc8fa67c8d6e44a17beeb9770aabdb269aacd111120
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.11 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
b8914133f5b1b2de569311dd778db5620d62e2c91de60cdd6e4c802d3545fb74
BLAKE2b-256 checksum
How to use checksums
33e43a223c3e4fd7d6ad89b761aef08e51126958617ab0e2f2afcfa1f370beed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp310-cp310-win_amd64.whl

Download URL psnr_hvsm-0.3.0-cp310-cp310-win_amd64.whl
Size 3.0 MB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
6ba8eba930e51a2fb7f64330351df0a0285de3e4e1c707dfe09d8f01471fc211
BLAKE2b-256 checksum
How to use checksums
0b145b218dd63c713f9d64a8eab476f1347c92702de20679274db9d1b4d90858
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / psnr_hvsm-0.3.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

Download URL psnr_hvsm-0.3.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Size 10.2 MB
Tags CPython 3.10 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
00813d86330f9d9486df5b15dd8571411e31ecf1a8f96e83164dd2b12d246443
BLAKE2b-256 checksum
How to use checksums
fa491d68aa49b0c5f7b64e8f1097292c777f9f1cee803f14c2eaedcc439bf16b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.3.0 This release

12 release files

0.2.4

12 release files

0.2.3

12 release files

0.2.2

12 release files

0.2.1

10 release files

0.2.0

8 release files

0.1.2

8 release files

0.1.1

8 release files

0.1.0

8 release files

0.0.9

8 release files

0.0.8

8 release files

0.0.7

8 release files

0.0.6

8 release files

0.0.5

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page