granular op• Data kinds: image2d → table
• Call: import fullseye as fs; fs.ledger.repose_angle_silhouette(side, *, threshold: 'float' = 0.5, toe_frac: 'float' = 0.15, apex_frac: 'float' = 0.15, min_points: 'int' = 8, correct_ground: 'bool' = False, method: 'str' = 'edge') -> 'dict' (implementation को सीधे call करना हो तो import granular; granular.repose_angle_silhouette(side, *, threshold: 'float' = 0.5, toe_frac: 'float' = 0.15, apex_frac: 'float' = 0.15, min_points: 'int' = 8, correct_ground: 'bool' = False, method: 'str' = 'edge') -> 'dict', registry से लेना हो तो opsdrive.get("repose_angle_silhouette"))
side image (powder coverage) से angle of repose φ पढ़ता है —— बाएँ और दाएँ ढलानों पर अलग-अलग line fit करता है, तलहटी और शिखर को छोड़कर।
प्रक्रिया (Sunday आदि 2020 §5.3 की पद्धति को नियमबद्ध करते हुए): (1) हर स्तंभ में पाउडर-सतह की ऊँचाई = उस किनारे के पिक्सेल की स्थिति जहाँ आवरण threshold से नीचे जाता है + उसका आवरण (उप-पिक्सेल; method="edge", डिफ़ॉल्ट) (2) भूमि = हर स्तंभ का सबसे निचला प्रतिच्छेद (वही प्रक्षेप) → measure.fit_line से भूमि का झुकाव β। method="column_sum" आवरण का स्तंभ-योग है (किनारा एंटी-एलियास हो तो यथार्थ उप-पिक्सेल, पर पाउडर का पिक्सेल मान 1 से हटे तो उसी अनुपात में tan φ खिसकता है: केवल समान शोर ±0.1 को [0, 1] पर काटने से 0.62 डिग्री कम आया, मापा गया)
(3) शिखर = अधिकतम ऊँचाई वाला स्तंभ (4) भूमि से ऊँचाई toe_frac·H या अधिक और (1 − apex_frac)·H या कम वाले बिंदुओं पर ही
बाएँ-दाएँ अलग-अलग fit_line (पूर्ण न्यूनतम वर्ग) (5) φ = बाएँ-दाएँ का औसत।
• correct_ground: संदर्भ तल का झुकाव β tan घटाकर हटाता है (tan φ' = tan θ ∓ tan β; अपरूपण-प्रकार के datum झुकाव के लिए यथार्थ)। कैमरा रोल हो तो कोण घटाना सही है, और β = 5 डिग्री पर दोनों में 1 डिग्री से अधिक का अंतर है, इसलिए डिफ़ॉल्ट रूप से नहीं हटाया जाता। केवल तब संदर्भ तल पर संदेह करें जब बाएँ-दाएँ का अंतर asymmetry_deg बड़ा हो।
• रिटर्न: phi_deg, phi_left_deg, phi_right_deg, asymmetry_deg, ground_deg, height_px, base_px, apex_col, left_cols / right_cols (फ़िट किए गए स्तंभों की सीमा), rms_left / rms_right (रेखा से अवशेष [px]), n_left / n_right।
• Raises ValueError: छवि नहीं / आवरण [0, 1] से बाहर / पाउडर दिखाई नहीं देता / ढेर छवि के ऊपरी, बाएँ या दाएँ किनारे को छूता है (कटा हुआ) / फ़िट बिंदु min_points से कम (ढेर बहुत छोटा) / toe_frac + apex_frac ≥ 1 / method की वर्तनी गलत।
विभेदन का अनुमान (आवरण पर समान शोर ±0.1, 4 कोण × 6 seed का मापन): ढेर की चौड़ाई 400 px पर 0.007 डिग्री, 50 px पर 0.2 डिग्री, 25 px पर 0.6 डिग्री।
• 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_granular_heap_repose — py -3.11 examples/poc_granular_heap_repose.py
table को input के रूप में लेते हैं)course_layout · course_occupancy · course_contains · world_build · world_camera · world_move · lidar_scan · rss_longitudinal_same
granular)heap_volume_cone · heap_mass · heap_volume_heightmap · beverloo_rate · beverloo_fit · discharge_synth · dispense_mass_from_video · hopper_discharge_rate
*Provenance: granular.py — DRIVE operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.