Spaces:
Sleeping
Sleeping
File size: 5,417 Bytes
5d2a222 012b9a3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | Image Color Classifier — README
Classify an image as rust, zinc, or normal using simple, fast color-space heuristics (OpenCV + NumPy).
You get three ways to use it:
a FastAPI server (/classify/ endpoint)
a Gradio web UI for quick testing
CLI tools to generate color reports and classify offline
Features
Heuristic color analysis in CIELab:
rustish_ratio → fraction of pixels with elevated a* (reddish/brownish)
zincish_ratio → fraction of pixels with elevated b* (yellowish)
Dominant colors via K-Means (palette + relative shares)
Three thresholds you can tune: rust_thr, zinc_thr, and lab_delta
Repository Layout
.
├─ api.py # FastAPI app exposing /classify/
├─ app.py # Gradio demo UI
├─ classify.py # (named 'app.py' in your message) classify from *_color_report.json
├─ color.py # Report generator (stats + palette + heuristics)
├─ main.py # CLI variant (stats + palette + heuristics + classification)
├─ requirements.txt # Python deps (fix the typos—see below)
└─ color_out/ # (created at runtime) reports and palette images
⚠️ Fix your requirements.txt:
Replace:
"fastapi[all]"
opencv-python-headless
numpy
gardio
With:
fastapi[all]
uvicorn
opencv-python-headless
numpy
gradio
Quickstart
1) Environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
pip install -r requirements.txt
2) Run the FastAPI server
uvicorn api:app --host 127.0.0.1 --port 8000
Endpoint: POST /classify/
Body: multipart form with file field file (image)
Query params (optional):
k (int, default 3) — number of dominant colors
rust_thr (float, default 0.01)
zinc_thr (float, default 0.02)
lab_delta (float, default 6.0)
cURL example:
curl -X POST "http://127.0.0.1:8000/classify/?k=3&rust_thr=0.01&zinc_thr=0.02&lab_delta=6.0" \
-F "file=@/path/to/sample.jpg"
Response (JSON):
{
"filename": "sample.jpg",
"classification": "rust",
"rustish_ratio": 0.0342,
"zincish_ratio": 0.0051,
"top_colors_rgb": [[183, 98, 72], [220, 210, 205], [120, 85, 70]],
"top_colors_share": [0.62, 0.25, 0.13]
}
OpenAPI docs at: http://127.0.0.1:8000/docs
3) Run the Gradio demo
python gradio_app.py
Upload an image, tweak sliders, and see the JSON output instantly.
Parameters mirrored: k, rust_thr, zinc_thr, lab_delta.
4) CLI workflows
You have two report generators and one “classify from JSON” helper.
Pick either color.py or main.py to generate a report.
A) Generate a detailed report with color.py
Creates:
Stats in RGB/HSV/Lab
Dominant color palette image
Heuristic ratios
python color.py --img /path/to/img.jpg --k 3 --resize_max 1200 --outdir color_out \
--rust_thr 0.01 --zinc_thr 0.02 --lab_delta 6.0
Outputs:
color_out/<name>_palette.png
color_out/<name>_color_report.json (includes classification)
B) Alternative generator main.py
Similar to color.py, also prints a short console summary.
python main.py --img /path/to/img.jpg --k 3 --resize_max 1200 --outdir color_out
Outputs:
color_out/<name>_palette.png
color_out/<name>_color_report.json
C) Classify an existing report with classify.py
(Your message labeled this file as app.py—the code shows it’s a JSON classifier.)
python classify.py --report color_out/<name>_color_report.json \
--rust_thr 0.01 --zinc_thr 0.02
Console output:
{
"file": "img.jpg",
"rustish_ratio": 0.0342,
"zincish_ratio": 0.0051,
"classification": "rust"
}
How it works (short)
Convert image to CIELab: L*, a*, b* (OpenCV uses a scaled 8-bit Lab).
Compute medians of a* and b*, add lab_delta (e.g., 6.0) to form thresholds.
Rustish = fraction of pixels with a* > median(a*) + lab_delta.
Zincish = fraction with b* > median(b*) + lab_delta.
Decision rule:
If zincish_ratio > zinc_thr → zinc
Else if rustish_ratio > rust_thr → rust
Else → normal
These are simple heuristics for quick screening, not robust material detection.
Tuning tips
Increase lab_delta to be stricter (fewer pixels count as rustish/zincish).
Decrease thresholds rust_thr / zinc_thr to make classification more sensitive.
For large images, set --resize_max to speed up K-Means and stats.
Notes & gotchas
Color spaces: OpenCV reads images as BGR; conversions are handled internally.
Lighting & WB: Results vary with illumination and white balance. Try to keep input lighting consistent.
Performance: k=3 works well for speed. Increase for richer palettes at a compute cost.
Headless environments: Using opencv-python-headless avoids GUI dependencies.
Example programmatic use (Python)
import cv2 as cv
from api import rust_zinc_indicators, classify_from_ratios, dominant_colors_kmeans
bgr = cv.imread("sample.jpg", cv.IMREAD_COLOR)
inds = rust_zinc_indicators(bgr, delta=6.0)
label = classify_from_ratios(inds["rustish_ratio"], inds["zincish_ratio"],
rust_thr=0.01, zinc_thr=0.02)
palette = dominant_colors_kmeans(bgr, k=3)
print(label, inds, palette[:1])
Troubleshooting
Invalid image file. Could not decode image.
The upload wasn’t a valid image. Try a supported format (JPG/PNG).
ModuleNotFoundError / import errors:
Re-check your virtualenv and pip install -r requirements.txt.
Uvicorn not found:
Add uvicorn to requirements.txt and pip install -r requirements.txt.
License
Add your preferred license (e.g., MIT) as LICENSE. |