Skip to Content
New: codec-png-native and codec-png-wasm bring the blazediff-png codec to Node and WebAssembly, faster than spng and jSquash. Read more β†’
Comparevs OpenCV

BlazeDiff vs OpenCV

The blazediff Python wheel is ~3.3x faster than reading two files with OpenCV and running cv2.absdiff, and it answers the question a visual test asks: how many pixels differ, and where. OpenCV gives you a difference array, and the counting, thresholding and anti-aliasing handling are up to you.

cv2.absdiff subtracts two arrays per channel and returns the absolute values. That is a building block, not a test assertion: it has no perceptual threshold and no anti-aliasing detection, so one-pixel font rendering changes count as differences. blazediff.compare decodes both files, runs a YIQ color delta with optional anti-aliasing detection, and can write a diff image.

At a glance

OpenCV (opencv-python)BlazeDiff (blazediff)
LicenseApache-2.0 (wheels bundle LGPL FFmpeg and Qt)MIT
DependenciesnumpyNone
Inputnumpy arrays, after cv2.imreadFile paths (PNG, JPEG, QOI)
OutputPer-channel difference arraymatch, diff_count, diff_percentage, diff image
Perceptual thresholdNo, you threshold the arrayYes, YIQ delta with threshold
Anti-aliasingNoOptional detection
ScopeFull computer vision libraryImage diffing

Benchmarks

The OpenCV side reads both files as grayscale, runs cv2.absdiff, and counts the non-zero pixels. The BlazeDiff side reads both files in color and runs compare. Decode is included for both.

vs opencv-python (cv2.absdiff)

TOTAL TIME Β· 34 FIXTURES Β· MEAN OF 25 RUNS Β· IO INCLUDED

BlazeDiffOther librariesLower is better

Apple M1 Max Β· darwin/arm64 Β· Node v22.14.0 Β· rustc 1.97.1 (8bab26f4f 2026-07-14) Β· Python 3.11.14 Β· 2026-10-22 Β· 234b300-dirty Β· pnpm benchmark python-opencv

Per-fixture results (34)
FixtureOpenCV absdiffBlazeDiffBlazeDiff vs OpenCV absdiff
4k/1617ms222ms2.77x
4k/1 (identical)782ms197ms3.97x
4k/2710ms263ms2.69x
4k/2 (identical)695ms233ms2.98x
4k/3820ms275ms2.98x
4k/3 (identical)790ms264ms2.99x
blazediff/14.94ms1.09ms4.52x
blazediff/1 (identical)4.50ms0.83ms5.40x
blazediff/24.14ms1.13ms3.67x
blazediff/2 (identical)4.01ms1.06ms3.80x
blazediff/344.59ms15.84ms2.81x
blazediff/3 (identical)44.49ms15.85ms2.81x
blazediff/430.53ms5.13ms5.95x
blazediff/4 (identical)30.23ms5.03ms6.01x
page/11.06s310ms3.43x
page/1 (identical)1.21s269ms4.48x
page/2306ms109ms2.81x
page/2 (identical)288ms54.88ms5.25x
pixelmatch/13.46ms1.29ms2.68x
pixelmatch/1 (identical)4.40ms1.08ms4.06x
pixelmatch/21.16ms0.75ms1.55x
pixelmatch/2 (identical)1.07ms0.50ms2.16x
pixelmatch/33.40ms1.03ms3.29x
pixelmatch/3 (identical)3.96ms0.92ms4.29x
pixelmatch/47.76ms2.88ms2.69x
pixelmatch/4 (identical)6.00ms2.17ms2.76x
pixelmatch/51.84ms0.57ms3.22x
pixelmatch/5 (identical)1.89ms0.57ms3.29x
pixelmatch/62.64ms1.20ms2.21x
pixelmatch/6 (identical)4.48ms0.88ms5.10x
pixelmatch/71.89ms0.75ms2.52x
pixelmatch/7 (identical)2.06ms0.62ms3.33x
same/118.29ms3.60ms5.08x
same/1 (identical)19.38ms3.15ms6.16x
TOTAL7.53s2.27s3.32x

Switching

# Before import cv2 import numpy as np a = cv2.imread("baseline.png", cv2.IMREAD_GRAYSCALE) b = cv2.imread("current.png", cv2.IMREAD_GRAYSCALE) changed = np.count_nonzero(cv2.absdiff(a, b)) # After from blazediff import compare result = compare("baseline.png", "current.png", "diff.png", threshold=0.1, antialiasing=True) if not result.match and result.reason == "pixel-diff": print(f"{result.diff_count} pixels differ")

compare returns reason == "layout-diff" when the two images differ in size, where cv2.absdiff raises an error.

When to keep OpenCV

  • The diff is one step in a larger vision pipeline: alignment, contours, morphology or feature matching.
  • You need formats that only OpenCV reads, such as TIFF, WebP or HDR.
  • You need GPU processing.
Last updated on