receipt-detection / README.md
nvriese1's picture
Vertically center badge text (B338)
29800eb verified
|
Raw
History Blame Contribute Delete
5.93 kB
metadata
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
            name: mAP@50
          - type: recall
            value: 0.875
            name: Recall

Receipt Detection - a computer-vision model on Pictograph

Open in task arch mAP license

View on Pictograph 路 ClearObject 路 Object Detection 路 YOLOX-M 路 FP32 路 Apache 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 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

pip install "pictograph[inference]"
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)
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

License

Released under Apache 2.0.

Citation

This model uses the YOLOX-M architecture:

@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 - annotate, train, and deploy from one API.