Spaces:
Sleeping
Sleeping
| # Methodology | |
| ## Problem Framing | |
| Classify an input image into one of {rust, zinc, normal} using fast, interpretable color cues. We rely on CIELab chroma tendencies: | |
| Rustish surfaces skew a* positive (reddish/brownish). | |
| Zincish surfaces skew b* positive (yellowish). | |
| The method is heuristic (no material guarantees) but is fast, parameter-tunable, and explainable. | |
| ## Pipeline Overview | |
| Input → Preprocess → Color Analysis → Heuristic Ratios → Rule-based Classification → (Optional) Palette Visualization | |
| Read & (optional) Resize | |
| Load as BGR (cv.imread / bytes→cv.imdecode). | |
| If max(H, W) > resize_max, downscale with INTER_AREA to speed up. | |
| Color Space Transforms | |
| BGR → RGB, BGR → HSV, BGR → Lab (OpenCV 8-bit Lab). | |
| Compute per-space statistics (channel means/stds) for explainability. | |
| Dominant Colors (K-Means) | |
| Flatten pixels to N×3 (BGR float32). | |
| Run cv.kmeans with KMEANS_PP_CENTERS, termination criteria (eps + max_iter). | |
| Sort clusters by frequency to produce a palette (with shares) and a palette image. | |
| Heuristic Indicators (Lab) | |
| Split Lab: L*, a*, b*. | |
| Compute medians: a_med, b_med. | |
| Define thresholds: | |
| a_thr = a_med + Δ, b_thr = b_med + Δ where Δ = lab_delta (default 6.0). | |
| Ratios: | |
| rustish_ratio = mean(a* > a_thr) | |
| zincish_ratio = mean(b* > b_thr) | |
| Rule-based Classification | |
| If zincish_ratio > zinc_thr ⇒ zinc | |
| Else if rustish_ratio > rust_thr ⇒ rust | |
| Else ⇒ normal | |
| Outputs | |
| Class label, rustish_ratio, zincish_ratio | |
| Top k RGB colors and their shares | |
| (CLI) JSON report + palette image | |
| ## Parameters & Defaults | |
| k (clusters): 3 — palette granularity vs. speed. | |
| lab_delta (Δ): 6.0 — sensitivity around median; higher = stricter. | |
| rust_thr: 0.01 — minimum fraction of above-threshold a* pixels. | |
| zinc_thr: 0.02 — minimum fraction of above-threshold b* pixels. | |
| resize_max: 1200 — longest side cap for speed (CLI). | |
| Tuning tips: | |
| • Increase lab_delta to reduce false positives. | |
| • Decrease rust_thr/zinc_thr to increase sensitivity. | |
| • Keep k=3..5 unless you need very fine palettes. | |
| ## Implementation Mapping | |
| FastAPI (api.py): /classify/ accepts an image + query params → returns JSON with classification, ratios, and palette. | |
| Gradio (gradio_app.py): Interactive UI with sliders for k, thresholds, and lab_delta. | |
| CLI (reports): | |
| color.py / main.py → stats + palette + heuristics (+ classification in color.py). | |
| classify.py → reads a *_color_report.json and applies thresholds to output a label. | |
| All core logic is shared: color conversions, K-Means, Lab heuristics, and the rule-based decision. | |
| ## Complexity & Performance | |
| K-Means: ~O(N × k × iters), where N = pixels after optional resize. | |
| Heuristics: O(N) on the Lab channels. | |
| Typical runtime: Sub-second to a few seconds on commodity CPUs for ≤2MP images with k=3. | |
| ## Evaluation Protocol (Recommended) | |
| Dataset: Curate labeled images for rust, zinc, normal under varied lighting/backgrounds. | |
| Split: Train-free method; still use dev set to tune lab_delta, rust_thr, zinc_thr; hold out a test set. | |
| Metrics: Accuracy, per-class precision/recall/F1; confusion matrix to catch “rust↔zinc” confusions. | |
| Stress Tests: Vary illumination, white balance, exposure; add clutter/background metals; scale/resize sensitivity. | |
| Ablations: | |
| Different lab_delta values | |
| Median vs. mean baselines for a*/b* thresholds | |
| Removing K-Means (should not affect the classification, only explainability) | |
| ## Assumptions & Limitations | |
| Heuristic, not material science: Color alone can’t guarantee presence of oxides/plating. | |
| Lighting-dependent: Harsh color casts and shadows can skew ratios. | |
| Background leakage: Non-metal regions may influence medians and ratios. | |
| Specular highlights: Can wash out chroma; consider controlled lighting for best results. | |
| Mitigations: | |
| Encourage consistent, diffuse illumination and controlled background. | |
| Optionally crop/segment to the object of interest. | |
| Adjust lab_delta and thresholds per environment. | |
| ## Reproducibility | |
| Dependencies: pinned in requirements.txt (use opencv-python-headless). | |
| Determinism: OpenCV k-means with KMEANS_PP_CENTERS is typically stable; for strict reproducibility fix random seeds if you wrap k-means calls accordingly. | |
| Reports: JSON artifacts and palette images are saved for auditability. | |
| ## Deployment Notes | |
| API: uvicorn api:app --host 0.0.0.0 --port 8000; OpenAPI docs at /docs. | |
| UI: python gradio_app.py for operator testing/threshold tuning. | |
| Batch: Use color.py/main.py to generate reports; classify.py to re-classify with updated thresholds. | |
| ## Ethical Use | |
| Intended for screening/triage in industrial contexts, not definitive corrosion/plating certification. | |
| Users should verify with appropriate physical/chemical tests when decisions carry risk. |