Scrutinizer v1.8: Scientific Accuracy Audit & Feature Congestion

v1.8.0 release notes →

Two themes in this release. First, a scientific accuracy audit that replaces geometric cutoffs with linear M-scaling and recalibrates E2, the distance from fixation where spatial resolution drops to half its foveal value. Second, a new analytical tool: Feature Congestion (Rosenholtz et al. 2007) ships as a real-time visual clutter metric with an interactive HUD overlay.

Linear M-scaling

The v1.6 DoG band cutoffs used a geometric 2× series (0.3, 0.6, 1.2, 2.4 × E2), which over-predicts resolution loss near fixation. Biological M-scaling (Rovamo & Virsu 1979) predicts linear growth of minimum resolvable detail with eccentricity:

$$s_{\min}(e) = s_0 \times \left(1 + \frac{e}{E_2}\right)$$

Band $k$ (spatial scale $2^k$–$2^{k+1}$ px) drops out when $s_{\min}(e) > 2^{k+1}$, giving cutoff eccentricity $= E_2 \times (2^{k+1} - 1)$:

BandSpatial ScaleCutoff (× E2)Content
band 01–2 px1Serifs, hairlines
band 12–4 px3Letter bodies, small icons
band 24–8 px7Words, UI elements
band 38–16 px15Buttons, layout blocks
residual16 px+AlwaysOverall color/luminance

Coarse structure (bands 2–3) now persists further into the periphery, so you see where a button is but can’t read its label. Fine detail (band 0) drops at the same rate as before. This is the mechanism behind the F-shaped reading pattern (Nielsen 2006; Pernice 2017): fine text detail requires foveal fixation, but coarse layout structure (headings, indentation, spacing) is available parafoveally, so users scan the left edge for structure without fixating every line. E2 values were recalibrated to preserve the band-0 onset point under the new formula: 0.15 (High-Key), 0.12 (Biological).

Update (2026-10-01): The F-pattern is a scanning pattern that NN/g reports when text lacks headings, bullets and other formatting, the user wants to be efficient, and the user is not committed to reading every word (Pernice 2017). Peripheral access to coarse layout has not been shown to be its mechanism.

Two additional correctness fixes. Hardware MIP levels use box/bilinear downsampling. A true Laplacian pyramid uses Gaussian convolution. Every doc, shader comment, and paper reference that said “Laplacian pyramid” now says approximate Laplacian pyramid and notes the distinction from Burt & Adelson (1983). And final color output is clamped to [0,1] to prevent negative-going band artifacts from the DoG subtraction reaching the framebuffer.


Feature Congestion

Feature Congestion (Rosenholtz, Li & Nakano 2007) measures visual clutter as local feature variance in color, luminance contrast and orientation (Scrutinizer’s simplified version uses Oklab lightness and color variance plus edge density). Saliency is a measure of what pops out (center-surround contrast, relative). Congestion is a measure of how much is going on (local variance, absolute). A dense product grid with nothing that particularly pops out still scores high on congestion.

Congestion heatmap overlay on Techmeme, showing blue (low) to yellow (high) feature variance across the page
Congestion heatmap on Techmeme. Yellow regions have high local feature variance: dense text, overlapping elements, competing visual signals. Blue regions are visually quiet.

Implementation settled on a fixed σ=2.5. Auto-scaling σ with resolution, the standard approach for natural images, fails on web content because pages at different resolutions are the same layout at different pixel densities. Natural-image scaling assumes the same scene at different zoom levels. Scaling σ up smears text, borders, and UI into indistinguishable blobs. Fixed σ keeps the neighborhood matched to the size of text and UI features.

ResolutionAuto σρFixed σ=2.5ρ
512 px5.00.53 FAIL2.50.89
768 px7.50.60 FAIL2.50.93
1024 px10.00.65 FAIL2.50.92

Update (2026-10-01): The explanation above does not fit the sweep. Each resolution was a downscaled copy of the same native screenshot, so the inputs were scaled versions of each other, and the auto-scaled σ covered the same page area at every resolution. What changed between the runs was neighborhood size: at 512–1024 px, fixed σ=2.5 pools over 2–4× less page area than the auto-scaled σ. See the congestion journey doc.

Two Web Workers handle analysis: saliency (256 px, every 15th frame, continuous) and congestion (1024 px, on-demand when the HUD is toggled). The saliency map texture is now RGB-packed: R=saliency, G=congestion, B=edge density. Scoring formula:

$$\text{score} = \sqrt{\,\text{congestion}_{p90} \times 0.7 + \text{edgeDensity}_{p90} \times 0.3\,} \times 100$$

Side-by-side comparison: saliency map (purple, left) vs congestion heatmap (blue-yellow, right) on Techmeme
Saliency vs Congestion on the same page. Left: saliency highlights what pops out (images, logos, high-contrast elements). Right: congestion measures how much is going on everywhere, so dense text regions score high even when nothing individually pops.

The 90th percentile measures the busy regions and is unaffected by whitespace. Sqrt scaling spreads the [0,1] raw range into a discriminative [0,100] score. Validated at Spearman ρ=0.93 against visual-clutter, a third-party Python port of Rosenholtz et al.’s (2007) MATLAB code. The full algorithm (the fixed-σ discovery, validation pipeline, and scoring design) is in the congestion tech brief.

If you work in UX research, a congestion map shows where information foraging (Pirolli & Card 1999) breaks down at the pre-attentive level. When local feature variance is high, your peripheral vision can’t efficiently sample the page for navigation cues, and the “information scent” that guides scanning degrades before it reaches conscious processing. A high congestion score predicts that users will need more fixations to orient themselves.


ComplexityHUD

Interactive draggable overlay replacing the toolbar URL-bar approach. Three tabs: Score (live congestion score with color-coded badge), Stats (p50/p75/p90 breakdowns for congestion and edge density), Spatial (quadrant breakdown identifying congestion hotspots). The HUD is scroll- and navigation-aware: the heatmap hides immediately on scroll to prevent a stale overlay and reappears when fresh worker results arrive.

ComplexityHUD Score tab showing Complexity 65/100 High
Score tab: live complexity rating with color-coded severity.
ComplexityHUD Stats tab showing congestion and edge density means and P90 values
Stats tab: congestion and edge density breakdowns (mean, P90).
ComplexityHUD Spatial tab showing quadrant congestion scores with Bottom-Left hotspot at 42
Spatial tab: quadrant hotspot detection.

Mode 9: Congestion-Gated Pooling (Hypothesis)

Update (v2.2): Congestion-gated pooling shipped as the default in all research modes, with no measurable performance regression (p95 delta < 0.1 ms) at maximum resolution. v2.2 release post →

A new mode wired in modes.json with category: “hypothesis”. The shader reads u_congestionMap on TEXTURE4, but pooling modulation is not yet implemented. The hypothesis is that cluttered regions should get stronger peripheral pooling, because they are harder to resolve in the periphery when more local feature variance competes for the same summary-statistic representation.

This tests Rosenholtz’s (2012) prediction that visual clutter and crowding are manifestations of the same computation. High-congestion areas would receive increased MIP pooling, simulating the degraded feature access that occurs when peripheral receptive fields pool over diverse, competing features. Tagged hypothesis to distinguish from the validated modes (0–8).

Update (2026-10-01): At the v1.8.0 tag the shader already applied the modulation: with Mode 9 active, the pooling eccentricity was multiplied by 1 + congestion (up to 2×). Modes 0–8 were research and presentation modes. The first psychophysical validation waves ran in v2.1.


What’s next

Update (2026-10-01): The congestion validation corpus is still 10 images; the v2.1 badge is wrong. The oriented DoG bands shipped with a smaller cardinal advantage than the ~50% planned here; see the v2.2 post.


Links: GitHub · Changelog · Feature Congestion tech brief · Congestion journey (implementation log) · Pernice, “F-Shaped Pattern” (2017)