dichromatic op• Data kinds: rgbimage × labels → vector
• Call: import fullseye as fs; fs.ledger.illuminant_from_dichromatic_planes(image_rgb, labels, min_pixels=16, min_plane_ratio=1e-06, min_intersection_ratio=1e-06) (implementation को सीधे call करना हो तो import specularity; specularity.illuminant_from_dichromatic_planes(image_rgb, labels, min_pixels=16, min_plane_ratio=1e-06, min_intersection_ratio=1e-06), registry से लेना हो तो opsspecular.get("illuminant_from_dichromatic_planes"))
दो या अधिक materials से illuminant का रंग वापस निकालता है। → unit 3-vector।
> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।
Lee's construction (1986). Under the dichromatic model every pixel of one material lies in the plane spanned by that material's body colour and the illuminant colour, so each material contributes a plane through the origin of RGB, and all of those planes contain the illuminant direction. Two materials with different body colours therefore intersect in exactly one line, and that line is the answer — a null-space computation, closed form.
*labels* is an (H, W) integer map naming the material at each pixel; negative labels are ignored (background). Each material needs *min_pixels* pixels and genuine highlight variation: a material seen with no specular reflection at all has colours along a single ray, which defines no plane. That is measured by the second-to-first singular ratio of its colour matrix and rejected below *min_plane_ratio* rather than contributing an arbitrary normal.
The returned direction is unit length with a positive component sum (illuminant colours are positive; the null space fixes the line, not the sign). On synthetic data with three known materials it reproduces the true illuminant with a maximum component error of 4.4e-14 and an angular error that rounds to 0.0 degrees (measured in tests/test_specularity.py).
*min_intersection_ratio* guards the answer itself: if the plane normals are nearly parallel — two materials whose body colours differ only in brightness, which is the same material twice — the intersection is ill-conditioned and the call raises instead of returning a direction picked by rounding error.
Raises ValueError: shape or dtype problems as in specular_diffuse_split; *labels* is not an (H, W) integer map matching the image; more than MAX_MATERIALS distinct labels; fewer than two materials survive the *min_pixels* and *min_plane_ratio* tests; the surviving planes do not intersect in a well-determined line.
• specular_photometric family guide
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• poc_white_balance — py -3.11 examples/poc_white_balance.py
• specular_photometric — py -3.11 examples/specular_photometric.py
vector को input के रूप में लेते हैं)—
dichromatic)specular_diffuse_split · specular_coefficient_map · specular_free_transform
*Provenance: specularity.py — SPECULAR operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.