"""Minimal RF-DETR ONNX license-plate detector. License: Apache 2.0.""" import argparse import numpy as np import onnxruntime as ort from PIL import Image RES = 768 MEAN = np.array([0.485, 0.456, 0.406], np.float32) STD = np.array([0.229, 0.224, 0.225], np.float32) def detect(sess, in_name, pil, conf=0.5): w0, h0 = pil.size img = pil.convert("RGB").resize((RES, RES), Image.BILINEAR) x = (np.asarray(img, np.float32) / 255.0 - MEAN) / STD x = np.ascontiguousarray(x.transpose(2, 0, 1)[None], np.float32) dets, labels = sess.run(["dets", "labels"], {in_name: x}) d = dets[0] if dets.ndim == 3 else dets l = labels[0] if labels.ndim == 3 else labels scores = l.max(axis=-1) if l.ndim > 1 else l if scores.max() > 1 or scores.min() < 0: scores = 1 / (1 + np.exp(-scores)) out = [] for (cx, cy, bw, bh), s in zip(d, scores): if s < conf: continue out.append((max(0, (cx - bw / 2) * w0), max(0, (cy - bh / 2) * h0), min(w0, (cx + bw / 2) * w0), min(h0, (cy + bh / 2) * h0), float(s))) return out if __name__ == "__main__": ap = argparse.ArgumentParser() ap.add_argument("image") ap.add_argument("--onnx", default="rfdetr-large.onnx") ap.add_argument("--conf", type=float, default=0.5) args = ap.parse_args() sess = ort.InferenceSession(args.onnx, providers=ort.get_available_providers()) for box in detect(sess, sess.get_inputs()[0].name, Image.open(args.image), args.conf): print(f"x1={box[0]:.0f} y1={box[1]:.0f} x2={box[2]:.0f} y2={box[3]:.0f} score={box[4]:.2f}")