# CVVDP

Canonical URL: https://encode.wiki/reference/metrics/cvvdp/
Content version: ca42e61ede0a24f789d7287a0001244ad22f4abf
Status: current
License: CC BY-SA 4.0
Checksum (SHA-256): 759b87c873c4d0d9fd713801ba63e3942c95bacb840242068faa12b8ce1e8126

ColorVideoVDP (CVVDP) is a full-reference visual difference predictor from the University of Cambridge, published at SIGGRAPH 2024. It models colour vision and spatial and temporal sensitivity together, and it takes the display and viewing conditions as input: size, resolution, viewing distance, peak brightness and room light. That makes it one of the few metrics that is genuinely video-aware and works for HDR.

## Scores and when to use it

CVVDP reports quality in **JOD** (just-objectionable-difference) units. 10 means no visible difference from the reference; lower is worse, and very strong distortion can go below 0. A difference of 1 JOD means about 75% of viewers would pick the higher-scoring version.

Use it when motion, colour or HDR matter, or when you care about a particular kind of screen. It complements [SSIMULACRA2](/reference/metrics/ssimulacra2/) and [Butteraugli](/reference/metrics/butteraugli/), which score frames independently, and unlike [VMAF](/reference/metrics/vmaf/), which has no HDR model, it handles HDR properly.

The score depends on the display model, so always say which one you used. The reference tool prints a line such as `ColorVideoVDP v0.5.7, 37.84 [pix/deg], Lpeak=200, ... (standard_fhd)` for exactly that purpose.

## Run the reference implementation

The reference implementation is a Python/PyTorch package. Install PyTorch with CUDA support first if you have an NVIDIA GPU (on a CPU it works, but video is slow), plus FFmpeg for video input, then:

```sh
pip install cvvdp
cvvdp --test distorted.mkv --ref reference.mkv --display standard_fhd
```

It prints the result as `cvvdp=9.3584 [JOD]`. Several `--test` files can be compared against one reference in one run.

| Option                          | Use                                                                                         |
| ------------------------------- | ------------------------------------------------------------------------------------------- |
| `--display NAME`                | Display and viewing model; `--display '?'` lists them                                      |
| `--full-screen-resize bicubic`  | Scale both videos to the display's resolution (video only)                                 |
| `--heatmap threshold`           | Write a heatmap video of where differences are visible (`supra-threshold` for large ones) |
| `--distogram`                   | Plot the differences per channel and per frame                                             |
| `--result results.csv`          | Write scores to a CSV file                                                                  |
| `--device cuda`                 | Pick the PyTorch device (`cpu`, `cuda`, `mps`)                                             |

## Choose a display model

| Model                 | Display and viewing conditions                                        |
| --------------------- | --------------------------------------------------------------------- |
| `standard_fhd`        | 24-inch 1080p monitor, 200 cd/m², office lighting, 2× display height |
| `standard_4k`         | 30-inch 4K monitor, 200 cd/m², office lighting, 2× display height    |
| `standard_hdr_pq`     | 30-inch 4K HDR monitor, 1500 cd/m², dim room, PQ input                |
| `standard_hdr_hlg`    | As above, HLG input                                                   |
| `standard_hdr_linear` | As above, for linear OpenEXR images in absolute units                 |
| `standard_phone`      | 6-inch 2400×1080 phone, 500 cd/m², office lighting, 40 cm away         |

The display model also sets how the input is decoded, so HDR video must use `standard_hdr_pq` or `standard_hdr_hlg`. For your own screen, copy `display_models.json`, add an entry, and pass its folder with `--config-paths`.

> **Caution — Resolution changes the score.**
>
> A video smaller than the display's resolution is assumed to fill only the middle of the screen at 1:1, which makes artifacts smaller and raises the score. If the video will be shown full screen, measure it that way with `--full-screen-resize` (or `--resizeToDisplay` in FFVship).
## Run it with Vship

[Vship](/tools/utilities/vship/) has a faster GPU implementation. With FFVship:

```sh
FFVship --source reference.mkv --encoded distorted.mkv -m CVVDP --displayModel standard_fhd
```

`--resizeToDisplay` does the same job as `--full-screen-resize`. In VapourSynth, `core.vship.CVVDP(ref, dist, model_name="standard_fhd")` stores a `_CVVDP` score on every frame, but the score on frame *i* covers frames 0 to *i*: request the frames in order and use the last one as the video's score.

Vship uses the same names for the standard displays (`standard_fhd`, `standard_4k`, `standard_hdr_pq`, `standard_hdr_hlg`), and its scores are close to, but not identical with, the reference implementation's. [fcvvdp](https://github.com/halidecx/fcvvdp) is a separate C implementation for CPUs. Use one implementation throughout a comparison, and note its version, since bug fixes have changed CVVDP scores in both Vship and the reference package.

## How it works

- The display model converts the input to absolute light, including black level and reflected room light.
- Colour is converted to an opponent space with one achromatic and two chromatic channels.
- Temporal filters split the signal into sustained channels and a transient (flicker and motion) luminance channel.
- A multi-scale pyramid splits each channel into spatial frequency bands, and contrast in each band is weighted by a contrast sensitivity model (castleCSF) that depends on frequency, luminance and colour.
- Visual masking reduces the weight of differences in busy areas, then the differences are pooled over space, bands, channels and time and mapped to JOD.

Details are in the [paper](https://doi.org/10.1145/3658144) and the [project page](https://www.cl.cam.ac.uk/research/rainbow/projects/colorvideovdp/).
