Spaces:
Sleeping
Sleeping
Download models/preprocess.py from BaMiaAndJason/VSL_Recognition: direct link, hf CLI and curl.
- Browser
- Download file 2.25 kB
-
https://huggingface.co/spaces/BaMiaAndJason/VSL_Recognition/resolve/main/models/preprocess.py
- Command line
-
hf download hf://spaces/BaMiaAndJason/VSL_Recognition/models/preprocess.py
-
curl -L -o preprocess.py https://huggingface.co/spaces/BaMiaAndJason/VSL_Recognition/resolve/main/models/preprocess.py
2.25 kB
| """ | |
| Chuẩn hoá theo người ký (signer-relative normalization) — làm keypoint bất biến | |
| với khung hình / khoảng cách / vị trí trong khung. | |
| Dùng CHUNG cho cả huấn luyện (scripts/train_clean.py --signer) lẫn suy luận | |
| (app/inference/pipeline.py). Chỉ có MỘT bản duy nhất để train và inference không | |
| bao giờ lệch nhau. | |
| Ý tưởng: căn mọi điểm về GIỮA HAI VAI và chia cho ĐỘ RỘNG VAI. Sau phép này, | |
| người đứng gần/xa, lệch trái/phải, khung rộng/hẹp đều cho cùng toạ độ — model chỉ | |
| còn thấy hình dạng + chuyển động của tay so với cơ thể. | |
| Bố cục 75 keypoint: bàn tay trái 0–20, tay phải 21–41, pose 42–74. | |
| Vai trong pose: landmark 11 (trái) → 42+11=53, landmark 12 (phải) → 42+12=54. | |
| """ | |
| from __future__ import annotations | |
| import numpy as np | |
| _LS = 53 # vai trái (pose landmark 11) | |
| _RS = 54 # vai phải (pose landmark 12) | |
| def signer_normalize(kp: np.ndarray) -> np.ndarray: | |
| """ | |
| kp: (T, 75, 3) — toạ độ thô (đã chuẩn hoá theo khung hình, điểm thiếu = 0). | |
| Trả về (T, 75, 3) đã căn giữa vai + chia độ rộng vai. Điểm thiếu giữ nguyên 0. | |
| Nếu không đủ dữ liệu vai để ước lượng (cả clip không thấy vai), trả về nguyên | |
| bản — thà không chuẩn hoá còn hơn chuẩn hoá sai. | |
| """ | |
| kp = np.asarray(kp, dtype=np.float32) | |
| ls = kp[:, _LS, :] # (T, 3) | |
| rs = kp[:, _RS, :] # (T, 3) | |
| detected = (np.any(ls != 0.0, axis=-1)) & (np.any(rs != 0.0, axis=-1)) # (T,) | |
| if detected.sum() == 0: | |
| return kp.copy() | |
| # Tâm = trung điểm hai vai, lấy trung bình qua các frame thấy đủ vai | |
| mid = ((ls[detected] + rs[detected]) / 2.0).mean(axis=0) # (3,) | |
| # Thang = độ rộng vai (khoảng cách x-y), trung bình qua các frame đó | |
| width = np.linalg.norm((ls[detected] - rs[detected])[:, :2], axis=1).mean() | |
| if width < 1e-6: | |
| return kp.copy() | |
| mask = np.any(kp != 0.0, axis=-1, keepdims=True) # (T, 75, 1) — điểm đã phát hiện | |
| normed = (kp - mid) / width | |
| return np.where(mask, normed, 0.0).astype(np.float32) | |