Metadata-Version: 2.4
Name: stamp-grader
Version: 0.2.0
Summary: Honest, on-device stamp centering & perforation measurement — a score you can see and verify, not a black-box valuation.
Author: Dan Matthew
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/DanMat/stamp-grader
Project-URL: Repository, https://github.com/DanMat/stamp-grader
Project-URL: Issues, https://github.com/DanMat/stamp-grader/issues
Keywords: philately,stamps,centering,computer-vision,opencv
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: End Users/Desktop
Classifier: Topic :: Scientific/Engineering :: Image Processing
Classifier: Topic :: Multimedia :: Graphics
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: opencv-python-headless>=4.8
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pillow; extra == "test"
Dynamic: license-file

# stamp-grader (working name — rename freely)

**An honest stamp condition tool: point your camera, get a centering score you
can see and understand, not a black-box valuation.**

## Why this exists

The consumer stamp-app category today is mostly predatory: point your camera,
get "it's worth $X," hit a paywall. The valuations are inflated to sell
subscriptions, and they answer the wrong question for the person holding the
stamp. The one genuinely useful, honest thing those apps do not do is help you
understand **condition** — and condition, especially **centering**, is what
actually drives a stamp's grade and value.

stamp-grader does that one thing well and honestly. Centering is geometry: the
distance from the printed design to the stamp's edges. We measure it, draw it on
your image, and explain it. You can see exactly why the score is what it is.

## The honest line

- **Measure the objective.** Centering and perforation gauge are geometric and
  measurable. We compute them and show our work.
- **Surface the subjective, never fake it.** Gum, cancellations, tears, thins,
  and creases are matters of judgement. We help you see them; we do not invent a
  number for them.
- **A centering score, not an official grade.** This is not a PSE/PSAG grade and
  never claims to be. It is a measurement you can trust because you can see it.

## Status: working, early release (0.2.x)

The measurement library is the **`stamp_grader`** package
([`src/stamp_grader/`](src/stamp_grader/)); its entry points are `measure()` (a file
path) and `measure_array()` (an in-memory RGB image). What works today:

- **Centering** for rectangular stamps, with perspective rectification (deskews a
  phone photo) and a colour-saturation / monochrome-darkness design detector.
- **Shape-correct centering** for triangles, diamonds, and round/oval stamps — each
  measured by the metric its geometry warrants, not forced through a rectangle.
- **Honest refusals** where a number would be meaningless: unsupported shapes,
  concave and design-hugging die-cuts, blank crops, and un-segmentable images all
  decline with a reason instead of a confident wrong score.
- **Perforation gauge** per axis (in catalogue units when a scale is given),
  declined when the stamp is not axis-aligned rather than guessed.
- **A cancellation flag** when a cancel crosses into the margin, built to abstain on
  anything but a genuinely clean margin.

Every call returns one stable [result contract](INTEGRATION.md) with a machine-readable
`status`. Behaviour is pinned by a test suite (`prototype/tests`).

```sh
pip install stamp-grader

# command line
stamp-grader path/to/stamp.jpg --json

# or from Python
python -c "import stamp_grader; print(stamp_grader.measure('path/to/stamp.jpg')['centering_score'])"
```

`measure_array(rgb, quad=None, mask=None, px_per_mm=None)` takes an in-memory RGB image
for callers that already hold one (no disk round-trip).

The hard, still-open problem is **design-box stability** across captures (the same
stamp can score a few percent apart between photos); until a capture-to-capture
cross-check exists, do not read a single score as precise. See [ROADMAP.md](ROADMAP.md)
and [GOALS.md](GOALS.md).

## Relationship to the wider stamp work

Standalone today — it works on a single photo, on device, with no shared catalogue
data — but **designed to plug into philatelyOS**, which would supply clean crops (and
optionally the stamp geometry) and consume the measurement. That contract is written up
in [INTEGRATION.md](INTEGRATION.md). It is also a sibling to the parked "doorway" app
(`stamp-atlas`).

## Contributing

Early prototype — issues and small PRs welcome; please open an issue before a large
change so we can agree the approach first.

## License

[Apache License 2.0](LICENSE).
