Create methodology.md

#1
by mandarmgd-03 - opened
Files changed (1) hide show
  1. methodology.md +161 -0
methodology.md ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Methodology
2
+
3
+ ## Problem Framing
4
+
5
+ Classify an input image into one of {rust, zinc, normal} using fast, interpretable color cues. We rely on CIELab chroma tendencies:
6
+
7
+ Rustish surfaces skew a* positive (reddish/brownish).
8
+
9
+ Zincish surfaces skew b* positive (yellowish).
10
+
11
+ The method is heuristic (no material guarantees) but is fast, parameter-tunable, and explainable.
12
+
13
+ ## Pipeline Overview
14
+
15
+ Input → Preprocess → Color Analysis → Heuristic Ratios → Rule-based Classification → (Optional) Palette Visualization
16
+
17
+ Read & (optional) Resize
18
+
19
+ Load as BGR (cv.imread / bytes→cv.imdecode).
20
+
21
+ If max(H, W) > resize_max, downscale with INTER_AREA to speed up.
22
+
23
+ Color Space Transforms
24
+
25
+ BGR → RGB, BGR → HSV, BGR → Lab (OpenCV 8-bit Lab).
26
+
27
+ Compute per-space statistics (channel means/stds) for explainability.
28
+
29
+ Dominant Colors (K-Means)
30
+
31
+ Flatten pixels to N×3 (BGR float32).
32
+
33
+ Run cv.kmeans with KMEANS_PP_CENTERS, termination criteria (eps + max_iter).
34
+
35
+ Sort clusters by frequency to produce a palette (with shares) and a palette image.
36
+
37
+ Heuristic Indicators (Lab)
38
+
39
+ Split Lab: L*, a*, b*.
40
+
41
+ Compute medians: a_med, b_med.
42
+
43
+ Define thresholds:
44
+ a_thr = a_med + Δ, b_thr = b_med + Δ where Δ = lab_delta (default 6.0).
45
+
46
+ Ratios:
47
+ rustish_ratio = mean(a* > a_thr)
48
+ zincish_ratio = mean(b* > b_thr)
49
+
50
+ Rule-based Classification
51
+
52
+ If zincish_ratio > zinc_thr ⇒ zinc
53
+
54
+ Else if rustish_ratio > rust_thr ⇒ rust
55
+
56
+ Else ⇒ normal
57
+
58
+ Outputs
59
+
60
+ Class label, rustish_ratio, zincish_ratio
61
+
62
+ Top k RGB colors and their shares
63
+
64
+ (CLI) JSON report + palette image
65
+
66
+ ## Parameters & Defaults
67
+
68
+ k (clusters): 3 — palette granularity vs. speed.
69
+
70
+ lab_delta (Δ): 6.0 — sensitivity around median; higher = stricter.
71
+
72
+ rust_thr: 0.01 — minimum fraction of above-threshold a* pixels.
73
+
74
+ zinc_thr: 0.02 — minimum fraction of above-threshold b* pixels.
75
+
76
+ resize_max: 1200 — longest side cap for speed (CLI).
77
+
78
+ Tuning tips:
79
+ • Increase lab_delta to reduce false positives.
80
+ • Decrease rust_thr/zinc_thr to increase sensitivity.
81
+ • Keep k=3..5 unless you need very fine palettes.
82
+
83
+ ## Implementation Mapping
84
+
85
+ FastAPI (api.py): /classify/ accepts an image + query params → returns JSON with classification, ratios, and palette.
86
+
87
+ Gradio (gradio_app.py): Interactive UI with sliders for k, thresholds, and lab_delta.
88
+
89
+ CLI (reports):
90
+
91
+ color.py / main.py → stats + palette + heuristics (+ classification in color.py).
92
+
93
+ classify.py → reads a *_color_report.json and applies thresholds to output a label.
94
+
95
+ All core logic is shared: color conversions, K-Means, Lab heuristics, and the rule-based decision.
96
+
97
+ ## Complexity & Performance
98
+
99
+ K-Means: ~O(N × k × iters), where N = pixels after optional resize.
100
+
101
+ Heuristics: O(N) on the Lab channels.
102
+
103
+ Typical runtime: Sub-second to a few seconds on commodity CPUs for ≤2MP images with k=3.
104
+
105
+ ## Evaluation Protocol (Recommended)
106
+
107
+ Dataset: Curate labeled images for rust, zinc, normal under varied lighting/backgrounds.
108
+
109
+ Split: Train-free method; still use dev set to tune lab_delta, rust_thr, zinc_thr; hold out a test set.
110
+
111
+ Metrics: Accuracy, per-class precision/recall/F1; confusion matrix to catch “rust↔zinc” confusions.
112
+
113
+ Stress Tests: Vary illumination, white balance, exposure; add clutter/background metals; scale/resize sensitivity.
114
+
115
+ Ablations:
116
+
117
+ Different lab_delta values
118
+
119
+ Median vs. mean baselines for a*/b* thresholds
120
+
121
+ Removing K-Means (should not affect the classification, only explainability)
122
+
123
+ ## Assumptions & Limitations
124
+
125
+ Heuristic, not material science: Color alone can’t guarantee presence of oxides/plating.
126
+
127
+ Lighting-dependent: Harsh color casts and shadows can skew ratios.
128
+
129
+ Background leakage: Non-metal regions may influence medians and ratios.
130
+
131
+ Specular highlights: Can wash out chroma; consider controlled lighting for best results.
132
+
133
+ Mitigations:
134
+
135
+ Encourage consistent, diffuse illumination and controlled background.
136
+
137
+ Optionally crop/segment to the object of interest.
138
+
139
+ Adjust lab_delta and thresholds per environment.
140
+
141
+ ## Reproducibility
142
+
143
+ Dependencies: pinned in requirements.txt (use opencv-python-headless).
144
+
145
+ Determinism: OpenCV k-means with KMEANS_PP_CENTERS is typically stable; for strict reproducibility fix random seeds if you wrap k-means calls accordingly.
146
+
147
+ Reports: JSON artifacts and palette images are saved for auditability.
148
+
149
+ ## Deployment Notes
150
+
151
+ API: uvicorn api:app --host 0.0.0.0 --port 8000; OpenAPI docs at /docs.
152
+
153
+ UI: python gradio_app.py for operator testing/threshold tuning.
154
+
155
+ Batch: Use color.py/main.py to generate reports; classify.py to re-classify with updated thresholds.
156
+
157
+ ## Ethical Use
158
+
159
+ Intended for screening/triage in industrial contexts, not definitive corrosion/plating certification.
160
+
161
+ Users should verify with appropriate physical/chemical tests when decisions carry risk.