--- license: apache-2.0 library_name: onnx pipeline_tag: object-detection pretty_name: "Receipt Detection" tags: - computer-vision - onnx - object-detection - yolox-m - pictograph model-index: - name: "Receipt Detection" results: - task: type: object-detection dataset: type: "evaluation" name: "Evaluation set" metrics: - type: "mAP" value: 0.872 name: "mAP" - type: "mAP50" value: 1.0 name: "mAP@50" - type: "recall" value: 0.875 name: "Recall" --- [![Receipt Detection - a computer-vision model on Pictograph](https://storage.googleapis.com/pictograph-assets/hf/heroes/receipt-detection.png?v=5)](https://pictograph.io/models/clearobject/ornate-walking-seal) [![Open in](https://img.shields.io/badge/Open_in-Pictograph-6d28d9)](https://pictograph.io/models/clearobject/ornate-walking-seal) ![task](https://img.shields.io/badge/task-object_detection-6d28d9) ![arch](https://img.shields.io/badge/arch-YOLOX--M-555) ![mAP](https://img.shields.io/badge/mAP-87.2%25-1a4480) [![license](https://img.shields.io/badge/license-apache--2.0-3cb44b)](https://www.apache.org/licenses/LICENSE-2.0) **[View on Pictograph](https://pictograph.io/models/clearobject/ornate-walking-seal)** · ClearObject · Object Detection · YOLOX-M · FP32 · [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) ## Overview This is an object detection model built on **YOLOX-M**. It expects **640x640** input and runs in FP32 precision. The ONNX weights are in this repo; run them with the Pictograph SDK (below) or [open the model on Pictograph](https://pictograph.io/models/clearobject/ornate-walking-seal) to test it in-browser, call the hosted API, or deploy it as an always-on endpoint. ## Performance Headline: **87.2% mAP**. | Metric | Value | | :--- | ---: | | mAP | 87.2% | | mAP@50 | 100.0% | | Recall | 87.5% | ## Classes Class index matches the model's output order. | # | Class | | ---: | :--- | | 0 | receipt | ## Training | Setting | Value | | :--- | :--- | | Input size | 640x640 | | Model size | M | | Precision | FP32 | | Version | 1.0.0 | ## Use this model The weights ship as ONNX (`yolox-c4b9f885.onnx`) with a `config.json`. The Pictograph SDK applies the model's exact pre/post-processing for you: ### [Pictograph SDK](https://pictograph.io/docs) ```bash pip install "pictograph[inference]" ``` ```python from huggingface_hub import hf_hub_download from pictograph import load_model, DetectionModel onnx = hf_hub_download("pictograph/receipt-detection", "yolox-c4b9f885.onnx") config = hf_hub_download("pictograph/receipt-detection", "config.json") model: DetectionModel = load_model(onnx, config, task="object_detection") result = model.predict("photo.jpg") # applies the model's pre/post-processing print(result) ```
Raw ONNX Runtime (no SDK) ```python from huggingface_hub import hf_hub_download import onnxruntime as ort, numpy as np from PIL import Image onnx = hf_hub_download("pictograph/receipt-detection", "yolox-c4b9f885.onnx") sess = ort.InferenceSession(onnx, providers=["CPUExecutionProvider"]) S = 640 # model input size # letterbox to SxS, pad 114, CHW float32 (YOLOX uses raw 0-255, NO /255) img = Image.open("photo.jpg").convert("RGB") w0, h0 = img.size; r = min(S / h0, S / w0) resized = img.resize((round(w0 * r), round(h0 * r))) canvas = np.full((S, S, 3), 114, np.uint8) canvas[: resized.height, : resized.width] = np.array(resized) x = canvas.transpose(2, 0, 1)[None].astype(np.float32) pred = sess.run(None, {sess.get_inputs()[0].name: x})[0][0] # [8400, 5+C] # decode the YOLOX grid (strides 8/16/32) grids, strides = [], [] for s in (8, 16, 32): n = S // s xv, yv = np.meshgrid(np.arange(n), np.arange(n)) grids.append(np.stack((xv, yv), 2).reshape(-1, 2)) strides.append(np.full((n * n, 1), s)) grids = np.concatenate(grids); strides = np.concatenate(strides) pred[:, :2] = (pred[:, :2] + grids) * strides pred[:, 2:4] = np.exp(pred[:, 2:4]) * strides xy, wh = pred[:, :2], pred[:, 2:4] boxes = np.concatenate([xy - wh / 2, xy + wh / 2], 1) / r # xyxy, source px s = pred[:, 4:5] * pred[:, 5:] cls, conf = s.argmax(1), s.max(1) keep = conf > 0.3 boxes, conf, cls = boxes[keep], conf[keep], cls[keep] def nms(b, sc, iou=0.45): order = sc.argsort()[::-1]; out = [] while len(order): i = order[0]; out.append(i) x1 = np.maximum(b[i, 0], b[order[1:], 0]); y1 = np.maximum(b[i, 1], b[order[1:], 1]) x2 = np.minimum(b[i, 2], b[order[1:], 2]); y2 = np.minimum(b[i, 3], b[order[1:], 3]) inter = np.clip(x2 - x1, 0, None) * np.clip(y2 - y1, 0, None) ai = (b[i, 2] - b[i, 0]) * (b[i, 3] - b[i, 1]) ar = (b[order[1:], 2] - b[order[1:], 0]) * (b[order[1:], 3] - b[order[1:], 1]) order = order[1:][inter / (ai + ar - inter + 1e-9) < iou] return out final = nms(boxes, conf) print(boxes[final], conf[final], cls[final]) # [x1,y1,x2,y2], score, class index ```
- Test it in-browser, call the hosted API, or deploy an endpoint: [open the model on Pictograph](https://pictograph.io/models/clearobject/ornate-walking-seal). - SDK + local inference guide: [docs](https://pictograph.io/docs/local-inference). ## License Released under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). ## Citation This model uses the YOLOX-M architecture: ```bibtex @article{ge2021yolox, title={YOLOX: Exceeding YOLO Series in 2021}, author={Ge, Zheng and Liu, Songtao and Wang, Feng and Li, Zeming and Sun, Jian}, journal={arXiv preprint arXiv:2107.08430}, year={2021} } ``` --- *Trained and published with [Pictograph](https://pictograph.io/models/clearobject/ornate-walking-seal) - annotate, train, and deploy from one API.*