Butteraugli
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0Butteraugli
Section titled “Butteraugli”:::danger Help Wanted This section is in need of contributions. If you believe you can help, please see our Contribution Guide to get started as a contributor! :::
Butteraugli is a perceptual distance metric that estimates the psychovisual similarity of two images. It is capable of outputting a heatmap containing differences between two input clips.
While a reference implementation by Google exists,
most people will want to use the HIP/CUDA implementation vship.
Vship is intended for use in Vapoursynth scripts or as a standalone CLI tool without Vapoursynth and runs on GPU (Nvidia and AMD Radeon).
Installing
Section titled “Installing”The Release page of the repository provides up-to-date binaries for Windows users.
To compile Vship, follow the instructions on the repository.
On archlinux, you may use the AUR to install.
Simply use your favorite AUR helper to install vapoursynth-plugin-vship-cuda-git (Nvidia) or vapoursynth-plugin-vship-amd-git (AMD Radeon)
paru -S vapoursynth-plugin-vship-amd-gitRunning
Section titled “Running”Using the standalone FFVship library
Section titled “Using the standalone FFVship library”usage: ./FFVship [-h] [--source SOURCE] [--encoded ENCODED] [-m {SSIMULACRA2, Butteraugli}] [--start start] [--end end] [-e --every every] [-t THREADS] [-g gpuThreads] [--gpu-id gpu_id] [--json OUTPUT] [--list-gpu] Specific to Butteraugli: [--intensity-target Intensity(nits)]In Vapoursynth scripts
Section titled “In Vapoursynth scripts”Example script:
import vapoursynth as vscore = vs.core
# Load reference and distorted clipsref = core.bs.VideoSource("reference.mp4")dist = core.bs.VideoSource("distorted.mp4")
# Calculate Butteraugli scores# intensity_multiplier controls sensitivityresult = ref.vship.BUTTERAUGLI(dist, distmap=0, numStream = 4)
# Extract scores from frame properties (three different norms available)scores_2norm = [frame.props["_BUTTERAUGLI_2Norm"] for frame in result.frames()]scores_3norm = [frame.props["_BUTTERAUGLI_3Norm"] for frame in result.frames()]scores_infnorm = [frame.props["_BUTTERAUGLI_INFNorm"] for frame in result.frames()]
# Get all scores in one passall_scores = [[frame.props["_BUTTERAUGLI_2Norm"], frame.props["_BUTTERAUGLI_3Norm"], frame.props["_BUTTERAUGLI_INFNorm"]] for frame in result.frames()]
# Print average scoresprint(f"Average Butteraugli 3Norm distance: {sum(scores_3norm) / len(scores_3norm)})print(f"Average Butteraugli 2Norm distance: {sum(scores_2norm) / len(scores_2norm)})print(f"Average Butteraugli MaxNorm distance: {sum(scores_infnorm) / len(scores_infnorm)}):::tip Graphical visualization You can optionally generate visual distortion maps with:
# Set distmap=1 to visualize distortiondistmap_result = ref.vship.BUTTERAUGLI(dist, distmap=1)
# The resulting clip is a grayscale visualization of distortionsdistmap_result.set_output():::
Scoring
Section titled “Scoring”Butteraugli outputs score in the range 0..inf with lower being better (closer to the source). A score below 1.0 is usually considered very good.