This is a Hugging Face-compatible port of
rtmw-x-384x288 from
OpenMMLab MMPose.
Detector: human AP = 56.4 on COCO val2017.
1from transformers import AutoConfig, AutoModel, AutoImageProcessor
2from PIL import Image
3import torch
4
5config = AutoConfig.from_pretrained("akore/rtmw-x-384x288", trust_remote_code=True)
6model = AutoModel.from_pretrained("akore/rtmw-x-384x288", trust_remote_code=True)
7model.eval()
8
9processor = AutoImageProcessor.from_pretrained("akore/rtmw-x-384x288")
10# Supply a pre-cropped person patch (will be resized to model input resolution)
11image = Image.open("person_crop.jpg").convert("RGB")
12inputs = processor(images=image, return_tensors="pt")
13
14with torch.no_grad():
15 # coordinate_mode="model" → raw 288×384 (or 192×256) pixel coords
16 outputs = model(**inputs, coordinate_mode="model")
17
18# outputs.keypoints: (1, 133, 2) — [x, y] in model-input pixel space
19# outputs.scores: (1, 133) — confidence in [0, 1]
20print(outputs.keypoints.shape, outputs.scores.shape)
1import torch
2
3# Mode 1 — model space (no extra args)
4out_model = model(**inputs, coordinate_mode="model")
5
6# Mode 2 — image space (pass the bbox used to crop the person)
7bbox = torch.tensor([[120, 40, 380, 620]]) # [x1, y1, x2, y2] in original image
8out_image = model(**inputs, coordinate_mode="image", bbox=bbox)
9
10# Mode 3 — root-relative (skeleton-normalised, useful for action recognition)
11out_root = model(**inputs, coordinate_mode="root_relative")
Uses
akore/rtmdet-tiny for detection and
RTMW for pose estimation. Both preprocessors handle all the resize / normalise bookkeeping
— no manual mean/std or scaling arithmetic required.
1from transformers import AutoModel, AutoImageProcessor
2from PIL import Image
3import torch
4
5# ── Load once ────────────────────────────────────────────────────────────────
6rtmdet = AutoModel.from_pretrained("akore/rtmdet-tiny", trust_remote_code=True).eval()
7rtmdet_proc = AutoImageProcessor.from_pretrained("akore/rtmdet-tiny")
8
9rtmw = AutoModel.from_pretrained("akore/rtmw-x-384x288", trust_remote_code=True).eval()
10rtmw_proc = AutoImageProcessor.from_pretrained("akore/rtmw-x-384x288")
11
12# ── Load image ───────────────────────────────────────────────────────────────
13pil_img = Image.open("photo.jpg").convert("RGB")
14orig_w, orig_h = pil_img.size # PIL gives (width, height)
15
16# ── Detect people — boxes returned in original image pixel coords ─────────────
17det_inputs = rtmdet_proc(images=pil_img, return_tensors="pt")
18with torch.no_grad():
19 det_out = rtmdet(pixel_values=det_inputs["pixel_values"],
20 original_size=(orig_h, orig_w)) # ← scale happens inside
21
22boxes = det_out.boxes[0] # (N, 4) already in original image pixels
23labels = det_out.labels[0] # (N,)
24scores = det_out.scores[0] # (N,)
25
26# ── Batch all person crops through the RTMW preprocessor ─────────────────────
27person_boxes = [
28 (boxes[i], scores[i]) for i in range(len(labels))
29 if int(labels[i]) == 0 and float(scores[i]) > 0.3
30]
31
32if person_boxes:
33 # PIL.Image.crop handles resize bookkeeping; processor handles normalize + batch
34 crops = [pil_img.crop(b.tolist()) for b, _ in person_boxes]
35 bboxes = torch.stack([b for b, _ in person_boxes]) # (P, 4)
36
37 inputs = rtmw_proc(images=crops, return_tensors="pt") # resize + normalize
38 with torch.no_grad():
39 out = rtmw(pixel_values=inputs["pixel_values"],
40 coordinate_mode="image", bbox=bboxes)
41
42 # out.keypoints: (P, 133, 2) — [x, y] in original image pixels
43 # out.scores: (P, 133) — confidence in [0, 1]
44 for i, (_, sc) in enumerate(person_boxes):
45 visible = (out.scores[i] > 0.3).sum()
46 print(f"Person {float(sc):.2f}: {visible} / 133 keypoints visible")
Raw SimCC confidence scores vary across model variants (0–1 for 256×192 models, 0–10 for 384×288 models). This port applies fixed min–max normalization so all model variants output scores in [0, 1]. The score_min and score_max hyperparameters used are stored in the config and were determined empirically from real-world inference.
1@article{jiang2024rtmw,
2 title={RTMW: Real-Time Multi-Person 2D and 3D Whole-body Pose Estimation},
3 author={Jiang, Tao and Xie, Xinchen and Li, Yining},
4 journal={arXiv preprint arXiv:2407.08634},
5 year={2024}
6}
7
8@misc{https://doi.org/10.48550/arxiv.2303.07399,
9 doi = {10.48550/ARXIV.2303.07399},
10 url = {https://arxiv.org/abs/2303.07399},
11 author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},
12 title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},
13 publisher = {arXiv},
14 year = {2023},
15 copyright = {Creative Commons Attribution 4.0 International}
16}
17
18@misc{mmpose2020,
19 title={OpenMMLab Pose Estimation Toolbox and Benchmark},
20 author={MMPose Contributors},
21 howpublished = {\url{https://github.com/open-mmlab/mmpose}},
22 year={2020}
23}
24
25@misc{lyu2022rtmdet,
26 title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},
27 author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},
28 year={2022},
29 eprint={2212.07784},
30 archivePrefix={arXiv},
31 primaryClass={cs.CV}
32}
33
34@inproceedings{jin2020whole,
35 title={Whole-Body Human Pose Estimation in the Wild},
36 author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},
37 booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},
38 year={2020}
39}