{
  "schemaVersion": 1,
  "contentVersion": "ca42e61ede0a24f789d7287a0001244ad22f4abf",
  "id": "docs/reference/metrics/butteraugli",
  "collection": "docs",
  "title": "Butteraugli",
  "description": "Butteraugli is a psychovisual distance metric for the high-fidelity range; this page explains its distance and norms and how to run it on images with libjxl and on video with Vship.",
  "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/",
  "apiUrl": "https://encode.wiki/api/v1/documents/docs/reference/metrics/butteraugli.json",
  "markdownUrl": "https://encode.wiki/api/v1/markdown/docs/reference/metrics/butteraugli.md",
  "status": "current",
  "tags": [
    "migrated"
  ],
  "license": "CC BY-SA 4.0",
  "dates": {
    "lastVerified": "2026-10-08T00:00:00.000Z"
  },
  "authors": [],
  "sources": [
    {
      "title": "Google Butteraugli README (archived)",
      "url": "https://github.com/google/butteraugli/blob/master/README.md",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libjxl v0.12.0 butteraugli_main tool",
      "url": "https://github.com/libjxl/libjxl/blob/v0.12.0/tools/butteraugli_main.cc",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libjxl v0.12.0 encoder API (distance as target max Butteraugli distance)",
      "url": "https://github.com/libjxl/libjxl/blob/v0.12.0/lib/include/jxl/encode.h",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "libjxl v0.12.0 release archives",
      "url": "https://github.com/libjxl/libjxl/releases/tag/v0.12.0",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "Vship v5.1.2 Butteraugli API and frame properties",
      "url": "https://codeberg.org/Line-fr/Vship/src/tag/v5.1.2/doc/BUTTERAUGLI.md",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "FFVship v5.1.2 usage",
      "url": "https://codeberg.org/Line-fr/Vship/src/tag/v5.1.2/doc/FFVship.md",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    },
    {
      "title": "SSIMULACRA 2 README, metric correlation tables",
      "url": "https://github.com/cloudinary/ssimulacra2/blob/main/README.md",
      "accessedAt": "2026-10-08T00:00:00.000Z"
    }
  ],
  "provenance": {
    "originUrl": "https://github.com/av1-community-contributors/codec-wiki/blob/37c3317fd058b23c71a87679bed5619a98f77752/docs/metrics/butteraugli.mdx",
    "originCommit": "37c3317fd058b23c71a87679bed5619a98f77752",
    "migratedAt": "2026-08-21T00:00:00.000Z",
    "modified": true,
    "originPath": "docs/metrics/butteraugli.mdx"
  },
  "headings": [
    {
      "depth": 2,
      "text": "What it is good for",
      "anchor": "what-it-is-good-for"
    },
    {
      "depth": 2,
      "text": "Distance and norms",
      "anchor": "distance-and-norms"
    },
    {
      "depth": 2,
      "text": "Score images",
      "anchor": "score-images"
    },
    {
      "depth": 2,
      "text": "Score video",
      "anchor": "score-video"
    }
  ],
  "sections": [
    {
      "id": "_preamble",
      "title": "Page introduction",
      "depth": 0,
      "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/_preamble.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/_preamble.md",
      "checksum": "5002a884b34b85f7c7b28504c41c641bcd9d775debd7f4e09186442613ef3a59",
      "bytes": 431
    },
    {
      "id": "what-it-is-good-for",
      "title": "What it is good for",
      "depth": 2,
      "anchor": "what-it-is-good-for",
      "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/#what-it-is-good-for",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/what-it-is-good-for.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/what-it-is-good-for.md",
      "checksum": "913a5bf9fa142fce877db9cd90b00e16906b397f5821d2d6a1198b07a8b21946",
      "bytes": 1098
    },
    {
      "id": "distance-and-norms",
      "title": "Distance and norms",
      "depth": 2,
      "anchor": "distance-and-norms",
      "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/#distance-and-norms",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/distance-and-norms.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/distance-and-norms.md",
      "checksum": "a0cb762a5d4392ebd78c0b68f225e17266e8a55d885a2e8117a6c8a3da77ffcd",
      "bytes": 1614
    },
    {
      "id": "score-images",
      "title": "Score images",
      "depth": 2,
      "anchor": "score-images",
      "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/#score-images",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/score-images.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/score-images.md",
      "checksum": "99cc48c4f0c5dee4ecbcf0d627dc80b5504cac9bd4a9abd93bf00eb4954a2dbb",
      "bytes": 493
    },
    {
      "id": "score-video",
      "title": "Score video",
      "depth": 2,
      "anchor": "score-video",
      "canonicalUrl": "https://encode.wiki/reference/metrics/butteraugli/#score-video",
      "apiUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/score-video.json",
      "markdownUrl": "https://encode.wiki/api/v1/sections/docs/reference/metrics/butteraugli/score-video.md",
      "checksum": "fb1cba294bb670dc562812406563183af363f9cebb884c6e98dd7e7165dd49c3",
      "bytes": 1470
    }
  ],
  "outboundReferences": [
    "/guides/compare-encoding-quality/",
    "/reference/metrics/ssimulacra2/",
    "/tools/utilities/vship/",
    "https://github.com/libjxl/libjxl",
    "https://github.com/libjxl/libjxl/releases"
  ],
  "checksum": "a4fe05c8c1579a4e011f203087bbfdbb0b3fe0ddce4e0aee0c058c6001c9cb94",
  "contentFormat": "markdown",
  "markdown": "Butteraugli is a psychovisual image difference metric from Google. It models how the eye's colour receptors and early visual processing respond to an image, and outputs both a per-pixel difference map and a single **distance**: 0 for identical images, higher for more visible differences. It is maintained in [libjxl](https://github.com/libjxl/libjxl), whose encoder uses it; the original standalone Google repository is archived.\n\n## What it is good for\n\nButteraugli is designed for the **high-fidelity range**. Its authors describe it as reliable \"in the domain of barely noticeable differences\", tuned mostly around JPEG quality 90–95, and say they don't know how well it handles major distortions. libjxl's distance setting is defined as a target maximum Butteraugli distance, with 1.0 described as visually lossless, which gives a feel for the scale.\n\nThat makes it a good check when you are comparing high-quality or near-transparent encodes, alongside [SSIMULACRA2](/reference/metrics/ssimulacra2/), which covers a wider quality range. The correlation tables in the SSIMULACRA2 README show the split: on the near-threshold KonFiG-IQA set the Butteraugli 3-norm is among the best metrics, while on TID2013 and KADID-10k, which are full of heavy distortions, it does no better than PSNR. It is strict: Vship's documentation notes that it rarely calls a frame good when it isn't, but it does flag differences a typical viewer wouldn't see. Like SSIMULACRA2 it is an image metric, so on video it scores frames independently.\n\n## Distance and norms\n\nThe difference map has a value for every pixel, so a single score needs a pooling rule. Always say which one you report.\n\n| Norm         | What it measures                                                       | Where you see it                                                                    |\n| ------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |\n| Max (∞-norm) | The single worst spot in the image                                     | First line of libjxl's `butteraugli_main`; Vship `_BUTTERAUGLI_INFNorm`             |\n| 3-norm       | A mean over the whole map that weights larger errors more heavily      | Second line of `butteraugli_main` (default `--pnorm 3`); Vship `_BUTTERAUGLI_3Norm` |\n| q-norm       | Any other p-norm you choose                                            | `butteraugli_main --pnorm`; Vship `qnorm` (default 2), `_BUTTERAUGLI_QNorm`         |\n\nThe max norm is the classic Butteraugli score, but one bad block decides it, so it is noisy for comparing encodes. The 3-norm is the figure commonly used for comparisons, including the correlation tables in the SSIMULACRA2 README and Av1an's `butteraugli-3` target.\n\nButteraugli also assumes a display brightness, the **intensity target** in nits. A brighter display makes artifacts more visible and raises the distance. libjxl's tool uses 80 nits for SDR input by default, while Vship uses 203 nits, so the two give different numbers for the same images unless you set the same value.\n\n## Score images\n\n`butteraugli_main` is included in the [libjxl release archives](https://github.com/libjxl/libjxl/releases) for Linux and Windows, next to `ssimulacra2`:\n\n```sh\nbutteraugli_main reference.png distorted.png --distmap diff.png\n```\n\nIt prints the max-norm distance, then the 3-norm. `--distmap` writes a heatmap of where the differences are; `--pnorm` and `--intensity_target` change the pooling and display brightness. Images without an embedded colour profile are read as sRGB.\n\n## Score video\n\nButteraugli is slow on a CPU, so for video most people use [Vship](/tools/utilities/vship/) on a GPU. With FFVship:\n\n```sh\nFFVship --source reference.mkv --encoded distorted.mkv -m Butteraugli --json butteraugli.json\n```\n\nFFVship prints the mean, percentiles, minimum and maximum for the 2-norm, 3-norm and max norm. The JSON holds `[q-norm, 3-norm, max-norm]` for every frame. `--qnorm` and `--intensity-target` change the extra norm and the display brightness.\n\nIn VapourSynth, run with `python`:\n\n```python\nimport vapoursynth as vs\ncore = vs.core\n\nref = core.bs.VideoSource(\"reference.mkv\")\ndist = core.bs.VideoSource(\"distorted.mkv\")\n\nclip = core.vship.BUTTERAUGLI(ref, dist)\nd = sorted(f.props[\"_BUTTERAUGLI_3Norm\"] for f in clip.frames())\nprint(f\"3-norm mean {sum(d) / len(d):.3f}  95th percentile {d[len(d) * 19 // 20]:.3f}  worst {d[-1]:.3f}\")\n```\n\nLower is better here, so the bad tail is the high end: report the mean, a high percentile and the worst frames. With `distmap=1`, `core.vship.BUTTERAUGLI(ref, dist, distmap=1)` returns a greyscale clip of the difference map that you can step through in a previewer to see where an encode falls apart. The old `_BUTTERAUGLI_2Norm` property is a deprecated alias of `_BUTTERAUGLI_QNorm`.\n\nBoth clips must have the same dimensions and frame count; scale the encode to the reference size first if needed. See [Compare encoding quality](/guides/compare-encoding-quality/) for the rest of the workflow.\n"
}
