polarization_separate — SPECULAR polarization op

Datenarten: polsweepimage2d

Aufruf: import specularity; specularity.polarization_separate(images, angles_deg=(0.0, 45.0, 90.0, 135.0), max_violation_frac=0.0) (oder opsspecular.get("polarization_separate"))

Verwendung

Zerlegt einen Polarisatordurchlauf in unpolarisierte und linear polarisierte Radianz. → (diffuse, specular), beide (H, W).

> Die ausführliche Beschreibung unten ist der Originaltext — Zusammenfassung und Überschriften sind übersetzt.

Fitting `I(t) = 0.5 (S0 + S1 cos 2t + S2 sin 2t)` per pixel gives

`I_min and I_max` in closed form, and the classical separation

(Wolff & Boult 1991; Nayar, Fang & Boult 1997) reads

`diffuse = 2 * I_min` (the unpolarised radiance)

`specular = I_max - I_min` (the linearly polarised radiance)

with `diffuse + specular = I_min + I_max` = the total scene radiance, so

nothing is lost or invented. Round-tripping

:func:polarization_render through this operator returns the inputs with a

maximum absolute error of 3.9e-16 for the four angles of a

division-of-focal-plane sensor and 4.4e-16 for a bare three-angle sweep

(measured in `tests/test_specularity.py`).

Read the names as shorthand. What is recovered exactly is the

unpolarised and polarised parts. Calling them diffuse and specular assumes

diffuse reflection is unpolarised and specular reflection is fully linearly

polarised — true near Brewster's angle for a dielectric, **false at normal

incidence**, where the specular reflection is unpolarised and this operator

returns all of it as "diffuse", and unreliable for metals. The polarisation

route is complementary to the colour route

(:func:specular_diffuse_split), not a replacement: it needs no illuminant

colour and works on textured, multi-material surfaces, but it needs a

favourable geometry.

*max_violation_frac* is the fraction of pixels allowed to fit a negative

minimum radiance before the call fails. The default 0 is fail-closed: a

negative fitted minimum means the modulation exceeded the mean, which no

analyser can produce, and it usually means the frames and *angles_deg* are

out of order. Raise it to clamp sensor-noise-level violations to zero as a

deliberate, recorded choice.

Raises `ValueError: *images* is not an (N, H, W)` stack of at

least 3 frames, or exceeds :data:MAX_LIGHTS / :data:MAX_STACK_ELEMENTS;

*angles_deg* does not match the frame count or leaves the fit

rank-deficient (two angles equal modulo 180); more than

*max_violation_frac* of the pixels fit a negative minimum.

Ausführlicher Anwendungsleitfaden

Leitfaden zur Familie specular_photometric

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

poc_polarization_specularpy -3.11 examples/poc_polarization_specular.py

specular_photometricpy -3.11 examples/specular_photometric.py

Typkompatible Folge-Operatoren (nehmen image2d als Eingabe)

polarization_render

Gleiche Kategorie (polarization)

polarization_render · polarization_dolp_map · polarization_stokes


*Provenance: specularity.py — SPECULAR Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.