vision-classifier / methodology.md
Anvit25's picture
Create methodology.md (#1)
0e2c15c verified

A newer version of the Gradio SDK is available: 6.14.0

Upgrade

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.