A high-performance VapourSynth plugin for GPU-accelerated visual fidelity metrics, focusing on SSIMULACRA2 & Butteraugli.
vship
provides hardware-accelerated implementations of:
- SSIMULACRA2: A perceptual image quality metric from Cloudinary's SSIMULACRA2
- Butteraugli: Google's psychovisual image difference metric from libjxl
The plugin uses HIP/CUDA for GPU acceleration, providing significant performance improvements over CPU implementations.
If you want to use Vship with a pre-defined workflow, here are some projects featuring Vship:
- SSIMULACRApy: A Python script to compare videos and output their SSIMU2 scores using various metrics (by Kosaka)
metrics
: A perceptual video metrics toolkit for video encoder developers (by the Psychovisual Experts Group)vs_align
: A vapoursynth plugin measuring temporal offset between two videoschunknorris
: A python script to adjust the quality encoding parameters at each scene of a video base on objective metrics- Media-Metrologist: Media-Metrologist is a library for measuring video quality using a suite of metrics on a per-scene and per-frame basis.
lvsfunc
: JET project containing various functions to help with video processing.
The steps to build vship
from source are provided below.
make
hipcc
(AMD) ornvcc
(NVIDIA)- VapourSynth
-
Ensure you have all of the dependencies properly installed.
-
Use the appropriate
make
command to build on your GPU
make buildcuda # for NVIDIA GPUs
make build # for AMD GPUs
- Install the
vship
library:
make install
Note: By default, the build is optimized for the specific GPU used during compilation.
In order to control the performance-to-VRAM trade-off, you may set
numStream argument
. 4 is typically a good compromise between both.
import vapoursynth as vs
core = vs.core
# Adjust based on your GPU's VRAM
result = core.vship.SSIMULACRA2(sourcefile, distortedfile, numStream = 4)
VRAM requirements per active Stream:
- SSIMULACRA2:
32 * 4 * width * height
bytes - Butteraugli:
31 * 4 * width * height
bytes
import vapoursynth as vs
core = vs.core
# Load reference and distorted clips
ref = core.bs.VideoSource("reference.mp4")
dist = core.bs.VideoSource("distorted.mp4")
# Calculate SSIMULACRA2 scores
#numStream is the newer way of controling the performance-to-VRAM trade-off
result = ref.vship.SSIMULACRA2(dist, numStream = 4)
# Extract scores from frame properties
scores = [frame.props["_SSIMULACRA2"] for frame in result.frames()]
# Print average score
print(f"Average SSIMULACRA2 score: {sum(scores) / len(scores)}")
import vapoursynth as vs
core = vs.core
# Load reference and distorted clips
ref = core.bs.VideoSource("reference.mp4")
dist = core.bs.VideoSource("distorted.mp4")
# Calculate Butteraugli scores
# intensity_multiplier controls sensitivity
result = ref.vship.BUTTERAUGLI(dist, intensity_multiplier=80, 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 pass
all_scores = [[frame.props["_BUTTERAUGLI_2Norm"],
frame.props["_BUTTERAUGLI_3Norm"],
frame.props["_BUTTERAUGLI_INFNorm"]]
for frame in result.frames()]
# Print average scores
print(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)})
You are also able to generate visual distortion maps with Butteraugli:
# Set distmap=1 to visualize distortion
distmap_result = ref.vship.BUTTERAUGLI(dist, intensity_multiplier=80, distmap=1)
# The resulting clip is a grayscale visualization of distortions
distmap_result.set_output()
vship
dramatically outperforms CPU-based implementations of these metrics
while preserving a high degree of accuracy.
- Butteraugli Source Code: libjxl/libjxl
- SSIMULACRA2 Source Code: cloudinary/ssimulacra2
Special thanks to dnjulek for the Zig-based SSIMULACRA2 implementation in vszip.
This project is licensed under the MIT license. License information is provided by the LICENSE.