Spaces:
Running
Running
HARSHIT-hash-07 commited on
Commit ·
805922c
1
Parent(s): 8e81ebe
fix(renderer): use exact plot_videos.py scaling pipeline (* 3 * 240 + offset)
Browse files- backend/video_renderer.py +31 -43
backend/video_renderer.py
CHANGED
|
@@ -34,61 +34,49 @@ def draw_frame_2D(frame, joints):
|
|
| 34 |
|
| 35 |
def render_skeleton_to_video(skeletons, output_path: str, fps: int = 25, mode: str = "standard"):
|
| 36 |
"""
|
| 37 |
-
Renders
|
| 38 |
-
|
| 39 |
-
"""
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
| 42 |
out = cv2.VideoWriter(output_path, fourcc, fps, (650, 650), True)
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
|
| 60 |
-
|
| 61 |
-
frame
|
| 62 |
-
|
| 63 |
-
# 2. Apply Auto-Scale and Center
|
| 64 |
-
joints_2d = (np.array(skel)[:, :2] - center) * scale
|
| 65 |
-
joints_2d = joints_2d + np.array([325, 325]) # Move to center of canvas
|
| 66 |
-
|
| 67 |
-
# Draw the frame (we pass the pre-scaled joints)
|
| 68 |
-
draw_frame_2D_v2(frame, joints_2d)
|
| 69 |
-
|
| 70 |
-
label = "Generated Sign: SignBridge HQ" if mode == "hq" else "Generated Sign: Live AI Bridge"
|
| 71 |
-
cv2.putText(frame, label, (130, 620), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (80, 80, 80), 2)
|
| 72 |
out.write(frame)
|
| 73 |
|
| 74 |
out.release()
|
| 75 |
-
|
| 76 |
-
# Convert to web-compatible
|
| 77 |
tmp_path = output_path.replace(".mp4", "_tmp.mp4")
|
| 78 |
if os.path.exists(output_path):
|
| 79 |
os.rename(output_path, tmp_path)
|
| 80 |
os.system(f"ffmpeg -y -i {tmp_path} -vcodec libx264 -pix_fmt yuv420p -preset fast -crf 22 {output_path} -loglevel quiet")
|
| 81 |
if os.path.exists(tmp_path):
|
| 82 |
os.remove(tmp_path)
|
| 83 |
-
|
| 84 |
-
return output_path
|
| 85 |
|
| 86 |
-
|
| 87 |
-
"""Specific version that takes ALREADY scaled joints to avoid double scaling."""
|
| 88 |
-
from SignIDD_CodeFiles.helpers import getSkeletalModelStructure
|
| 89 |
-
skeleton = np.array(getSkeletalModelStructure())
|
| 90 |
-
|
| 91 |
-
for j in range(skeleton.shape[0]):
|
| 92 |
-
joint1 = joints_scaled[skeleton[j, 0]]
|
| 93 |
-
joint2 = joints_scaled[skeleton[j, 1]]
|
| 94 |
-
draw_line(frame, joint1, joint2, c=(40, 40, 40), t=1, width=2)
|
|
|
|
| 34 |
|
| 35 |
def render_skeleton_to_video(skeletons, output_path: str, fps: int = 25, mode: str = "standard"):
|
| 36 |
"""
|
| 37 |
+
Renders skeleton frames to an MP4, using the SAME scaling as the original
|
| 38 |
+
plot_videos.py: joints * 3 * 240 + offset [350, 250].
|
|
|
|
| 39 |
|
| 40 |
+
skeletons: list of shape (frames, 50, 3)
|
| 41 |
+
"""
|
| 42 |
+
import sys as _sys
|
| 43 |
+
_parent = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
| 44 |
+
if _parent not in _sys.path:
|
| 45 |
+
_sys.path.insert(0, _parent)
|
| 46 |
+
from SignIDD_CodeFiles.helpers import getSkeletalModelStructure
|
| 47 |
+
|
| 48 |
+
skeleton = np.array(getSkeletalModelStructure())
|
| 49 |
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
| 50 |
out = cv2.VideoWriter(output_path, fourcc, fps, (650, 650), True)
|
| 51 |
|
| 52 |
+
for skel in skeletons:
|
| 53 |
+
frame = np.ones((650, 650, 3), np.uint8) * 255
|
| 54 |
+
|
| 55 |
+
# Exact same pipeline as plot_videos.py draw_frame_2D:
|
| 56 |
+
# joints * 3 (undo the /3 normalization from data prep)
|
| 57 |
+
# then * 240 (= 10 * 12 * 2, the display scale)
|
| 58 |
+
# then + [350, 250] (center offset)
|
| 59 |
+
joints_2d = np.array(skel)[:, :2] * 3 # (50, 2)
|
| 60 |
+
joints_scaled = joints_2d * 240
|
| 61 |
+
joints_offset = joints_scaled + np.array([350, 250])
|
| 62 |
+
|
| 63 |
+
for j in range(skeleton.shape[0]):
|
| 64 |
+
j1 = joints_offset[skeleton[j, 0]]
|
| 65 |
+
j2 = joints_offset[skeleton[j, 1]]
|
| 66 |
+
draw_line(frame, j1, j2, c=(0, 0, 0), t=1, width=2)
|
| 67 |
|
| 68 |
+
label = "SignBridge HQ" if mode == "hq" else "Live AI Bridge"
|
| 69 |
+
cv2.putText(frame, label, (230, 630), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (80, 80, 80), 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
out.write(frame)
|
| 71 |
|
| 72 |
out.release()
|
| 73 |
+
|
| 74 |
+
# Convert to web-compatible H.264
|
| 75 |
tmp_path = output_path.replace(".mp4", "_tmp.mp4")
|
| 76 |
if os.path.exists(output_path):
|
| 77 |
os.rename(output_path, tmp_path)
|
| 78 |
os.system(f"ffmpeg -y -i {tmp_path} -vcodec libx264 -pix_fmt yuv420p -preset fast -crf 22 {output_path} -loglevel quiet")
|
| 79 |
if os.path.exists(tmp_path):
|
| 80 |
os.remove(tmp_path)
|
|
|
|
|
|
|
| 81 |
|
| 82 |
+
return output_path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|