Download dataset/layout.py from Tri1/t2m-gpt-vsl-code: direct link, hf CLI and curl.
- Browser
- Download file 3.91 kB
-
https://huggingface.co/Tri1/t2m-gpt-vsl-code/resolve/main/dataset/layout.py
- Command line
-
hf download hf://Tri1/t2m-gpt-vsl-code/dataset/layout.py
-
curl -L -o layout.py https://huggingface.co/Tri1/t2m-gpt-vsl-code/resolve/main/dataset/layout.py
3.91 kB
| """Keypoint layout, so a trimmed keypoint set can be trained without hardcoding 128. | |
| The full DWPose layout is 128 keypoints: body 0:18, face 18:86, left hand 86:107, | |
| right hand 107:128. Dropping keypoints (e.g. knees/ankles, which these clips crop | |
| out) changes the model's input dimension, so the group boundaries can no longer be | |
| constants. | |
| Keypoints are always re-ordered into body / face / lhand / rhand blocks, so group | |
| ranges stay contiguous slices -- only the boundaries move. A layout is persisted as | |
| `layout.json` next to the packed memmaps. | |
| """ | |
| import json | |
| import os | |
| # --- the full DWPose layout, used when no layout.json is present ------------- | |
| FULL_GROUPS = {"body": (0, 18), "face": (18, 86), "lhand": (86, 107), "rhand": (107, 128)} | |
| FULL_NKP = 128 | |
| # OpenPose-18 body indices, for reference when choosing what to drop: | |
| # 0 nose 1 neck 2 Rshoulder 3 Relbow 4 Rwrist 5 Lshoulder 6 Lelbow 7 Lwrist | |
| # 8 Rhip 9 Rknee 10 Rankle 11 Lhip 12 Lknee 13 Lankle | |
| # 14 Reye 15 Leye 16 Rear 17 Lear | |
| # Knees/ankles are detected in only ~19% / ~0.1% of Full_TriVis frames. | |
| LOWER_BODY = (9, 10, 12, 13) | |
| PRESETS = { | |
| "full": (), | |
| "upper": LOWER_BODY, # drop knees + ankles, keep hips (100% valid) | |
| "upper_nohip": LOWER_BODY + (8, 11), | |
| } | |
| class Layout: | |
| """Which original DWPose keypoints are kept, and where the groups sit.""" | |
| def __init__(self, keep, groups, name="full"): | |
| self.keep = list(keep) # original indices, in new order | |
| self.groups = {k: tuple(v) for k, v in groups.items()} | |
| self.name = name | |
| self.n_kpts = len(self.keep) | |
| self.dim = self.n_kpts * 2 | |
| # original index -> new index (None if dropped) | |
| self.old2new = {o: n for n, o in enumerate(self.keep)} | |
| # ------------------------------------------------------------------ build | |
| def full(cls): | |
| return cls(list(range(FULL_NKP)), FULL_GROUPS, "full") | |
| def from_drop(cls, drop, name="custom"): | |
| """Build a layout that drops `drop` (original indices), keeping group order.""" | |
| drop = set(int(d) for d in drop) | |
| keep, groups, cur = [], {}, 0 | |
| for g, (a, b) in FULL_GROUPS.items(): | |
| idx = [i for i in range(a, b) if i not in drop] | |
| keep.extend(idx) | |
| groups[g] = (cur, cur + len(idx)) | |
| cur += len(idx) | |
| return cls(keep, groups, name) | |
| def preset(cls, name): | |
| if name not in PRESETS: | |
| raise ValueError(f"unknown layout preset {name!r}; choices {list(PRESETS)}") | |
| return cls.full() if name == "full" else cls.from_drop(PRESETS[name], name) | |
| # ------------------------------------------------------------------- i/o | |
| def save(self, data_dir): | |
| with open(os.path.join(data_dir, "layout.json"), "w") as f: | |
| json.dump({"name": self.name, "keep": self.keep, | |
| "groups": {k: list(v) for k, v in self.groups.items()}, | |
| "n_kpts": self.n_kpts, "dim": self.dim}, f, indent=2) | |
| def load(cls, data_dir): | |
| p = os.path.join(data_dir, "layout.json") | |
| if not os.path.exists(p): | |
| return cls.full() # datasets packed before layouts existed | |
| with open(p) as f: | |
| d = json.load(f) | |
| return cls(d["keep"], d["groups"], d.get("name", "custom")) | |
| # ---------------------------------------------------------------- helpers | |
| def metric_groups(self): | |
| """Group ranges for reporting, with 'hands' merging both hands.""" | |
| g = dict(self.groups) | |
| out = {"all": (0, self.n_kpts), "body": g["body"], "face": g["face"], | |
| "hands": (g["lhand"][0], g["rhand"][1])} | |
| return out | |
| def __repr__(self): | |
| return (f"Layout({self.name}, {self.n_kpts} kpts, dim {self.dim}, " | |
| f"groups {self.groups})") | |