SharpenPicture
Menu

Sharpening engine report

Every claim this site makes about its sharpening passes is an arithmetic claim, and an arithmetic claim can be checked. These are the results of that check, taken from the run that built this page.

Run on
2026-10-25
Commit
8d0670461c03
Assertions
67 passed
Under
Node v23.11.0

The motion estimator and the solver

A plate of overlapping discs with no preferred direction is convolved with a line kernel of a known length and a known angle. The estimator is then asked to recover both, without being told either, and the deconvolution is run against whatever it found — not against the true kernel, which is the honest version of this test. RMSE is measured against the unblurred plate, ignoring a 24-pixel margin, so the padding at the edges of the transform is not scored.

Five kernel lengths, recovered and inverted
True length (px)True angle (°)Found length (px)Found angle (°)Confidence (0–1)RMSE beforeRMSE afterError removed (%)
51555.00155.00.600.06270.026059
8308.0027.50.920.07990.040549
1210012.0097.51.000.09780.052546
16015.500.01.000.11370.058049
206520.5065.01.000.12510.062650

Worst angle error in this run: 2.5°. Worst length error: 0.50 px. These are figures from a synthetic plate with one straight kernel and no subject motion, which is the best case the model has; a real photograph is described on the motion-path route, and it is not this.

What you inspected against what you exported

The 1:1 stage processes a patch cut out of the frame with an apron of real picture around it; the export processes the whole frame in tiles with the same apron and the same parameters, through the same function. This test runs both and compares the overlapping pixels, in 8-bit code values. Zero means the two are identical.

Patch against whole frame, worst pixel
PassApron (px)Worst difference (code values)
unsharp mask with clamps and edge mask480
clarity and structure1280
motion deconvolution961
region mask480
per-channel mode480
defocus deconvolution, disc961
defocus deconvolution, Gaussian960
document mode with clean black and white860
colour-noise reduction600
descreen notch480
JPEG deblock and dering560
transparency-aware, alpha edge sharpened560

Out of focus: the lens estimator and solver

The same plate blurred by a uniform lens disc and by a Gaussian of known size, then measured. The disc radius is read from the first zero ring of the spectrum; the Gaussian from the 10–90 % width of the strongest edges. The solver's error is measured at the true radius, and again at the radius the estimator found. The build fails if the error falls by less than 30 % at any radius.

Defocus estimator and Wiener solver, synthetic plate
Kernel and true radius (px)Found (px)ConfidenceRMSE beforeRMSE afterDrop (%)RMSE at found radius
disc 1.51.51.000.05400.0209610.0209
disc 2.52.51.000.07130.0361490.0361
disc 441.000.09070.0531420.0531
disc 661.000.11110.0662400.0662
disc 88.11.000.12800.0779390.0779
gaussian 110.560.05660.0246570.0246
gaussian 1.51.40.460.07160.0446380.0465
gaussian 21.80.400.08330.0542350.0581
gaussian 32.90.230.10240.0681340.0689
gaussian 43.50.140.11800.0792330.0864

The ringing guard

A deconvolution with a low noise term rings beside strong edges. The guard measures that ripple where the opened picture was flat and raises the noise term until it falls under 3 code values, or the term reaches its ceiling.

Ringing, before and after the guard
SolverNoise term fromNoise term toRinging before (cv)Ringing after (cv)
defocus disc 4 px0.0020.0629.23.9
defocus disc 8 px0.0020.01852.7

JPEG artefacts: deblocking

A smooth plate quantised through a real 8 × 8 DCT at known qualities, then passed through the deblock and dering step. The error is against the plate before quantisation.

Deblocking error, synthetic block-quantised plate
Source qualityRMSE beforeRMSE afterDrop (%)
500.00900.00856
700.00640.00606

Printed photographs: descreening

The plate multiplied by a dot screen of known period and angle, as a printed photograph is. The search must find the screen, and the notch must remove most of it.

Descreen, synthetic halftone
True period (px)True angle (°)Found periodFound anglePeaksRMSE beforeRMSE after
4.5454.534560.10480.0234

The rim taxonomy

Step edges sharpened with settings chosen to produce each kind of rim. The taxonomy reads the realised overshoot and undershoot and must name the kind correctly.

Fixture rims and what the taxonomy named
FixtureNamedOvershoot (cv)Undershoot (cv)
bright-halobright-halo60.378.8
dark-halodark-halo078.8
double-edgedouble-edge45.178.8
noise-crawlnoise-crawl4273
colour-fringecolour-fringe41.5110
nonenone00

Documents: counters kept open

A page of ring-shaped letters under a soft shadow, blurred, then run through document mode with levels measured by the page itself. The holes in the letters must stay open.

Document mode on a synthetic page
Counters foundOpen after (%)Stroke contrast (cv)Measured inkStroke width (px)
721002140.274.8

How this page is produced, and what would stop it

The harness is scripts/verify-engine.mjs in this site’s repository. It generates its own plates from a fixed seed, so the numbers above are reproducible rather than remembered, and it imports the same engine modules the browser loads — no reimplementation, no second code path to drift. It runs in prebuild, before the site is compiled. A failed assertion exits non-zero, the build stops there, and nothing is published; that is the mechanism by which this page cannot become a flattering record of an engine that has since regressed.

What it does not prove: that the sharpening looks good, that a photograph taken by a person behaves like a plate of discs, or that the browser’s decoder handed the engine the pixels the camera wrote. Those are different claims and this page does not make them. Everything on every route here is 8 bits per channel, including the figures above.

Photographic visual for Engine Report

Engine Report