Spaces:
Sleeping
Sleeping
metadata
title: Ring Sizer
emoji: ๐
colorFrom: blue
colorTo: purple
sdk: docker
app_port: 7860
Ring Sizer
Local computer-vision CLI tool that measures finger outer diameter from a single image using a credit card as scale reference.
Live Demo
- Hugging Face Space: https://huggingface.co/spaces/feng-x/ring-sizer
- Anyone can try the hosted web demo directly in the browser.

What it does
- Detects a credit card and computes
px/cmscale. - Detects hand/finger with MediaPipe.
- Measures finger width in the ring-wearing zone.
- Regression calibration corrects systematic over-measurement (MAE: 0.158 โ 0.060 cm).
- Supports dual edge modes:
contour(v0 baseline)sobel(v1 sub-pixel refinement)auto(default, Sobel with quality fallback)compare(returns both method stats)
- Writes JSON output and always writes a result PNG next to it.
Accuracy
Validated on 10 subjects ร 3 fingers ร 2 photos = 60 measurements against caliper ground truth.
| Metric | Before Calibration | After Calibration |
|---|---|---|
| MAE | 0.158 cm | 0.060 cm |
| RMSE | 0.176 cm | 0.075 cm |
| Max error | 0.347 cm | 0.174 cm |
Pipeline stability: card detection CV = 0.44%, shot-to-shot repeatability = 0.028 cm.
See full report: doc/report/calibration_report.md
Install
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Run
python measure_finger.py --input input/test_image.jpg --output output/result.json
Common options
# Enable intermediate debug folders (card/finger/edge stages)
python measure_finger.py --input image.jpg --output output/result.json --debug
# Finger selection
python measure_finger.py --input image.jpg --output output/result.json --finger-index ring
# Disable calibration (raw measurement only)
python measure_finger.py --input image.jpg --output output/result.json --no-calibration
# Force method
python measure_finger.py --input image.jpg --output output/result.json --edge-method contour
python measure_finger.py --input image.jpg --output output/result.json --edge-method sobel
# Compare contour vs sobel
python measure_finger.py --input image.jpg --output output/result.json --edge-method compare
# Sobel tuning
python measure_finger.py --input image.jpg --output output/result.json \
--edge-method sobel --sobel-threshold 15 --sobel-kernel-size 3 --no-subpixel
CLI flags
| Flag | Values | Default | Description |
|---|---|---|---|
--input |
path | (required) | Input image (JPG/PNG) |
--output |
path | (required) | Output JSON path |
--debug |
flag | false | Save intermediate debug images |
--finger-index |
auto, index, middle, ring, pinky | index | Which finger to measure |
--confidence-threshold |
float | 0.7 | Minimum confidence threshold |
--edge-method |
auto, contour, sobel, compare | auto | Edge detection method |
--sobel-threshold |
float | 15.0 | Minimum gradient magnitude |
--sobel-kernel-size |
3, 5, 7 | 3 | Sobel kernel size |
--no-subpixel |
flag | false | Disable sub-pixel refinement |
--no-calibration |
flag | false | Output raw measurement only |
--skip-card-detection |
flag | false | Testing only |
Output JSON
{
"finger_outer_diameter_cm": 1.78,
"confidence": 0.91,
"scale_px_per_cm": 128.03,
"quality_flags": {
"card_detected": true,
"finger_detected": true,
"view_angle_ok": true
},
"fail_reason": null,
"edge_method_used": "sobel",
"raw_diameter_cm": 1.92,
"calibration_applied": true
}
Notes:
raw_diameter_cmis the pre-calibration measurement (present when calibration is applied).edge_method_usedandmethod_comparisonare optional (present when relevant).- Result image path is auto-derived:
output/result.jsonโoutput/result.png.
Documentation
| Path | Contents |
|---|---|
doc/v0/ |
v0 PRD, Plan, Progress (contour baseline) |
doc/v1/ |
v1 PRD, Plan, Progress (Sobel edge refinement) |
doc/v2/ |
v2 Plan, Progress (calibration & regression) |
doc/report/ |
Validation & calibration report |
doc/algorithms/ |
Algorithm documentation |
script/ |
Batch measurement & analysis scripts |
web_demo/ |
Web demo (Flask) |