SCAIL-2 / SCAIL-Pose /pose_draw /draw_pose_utils.py
fffiloni's picture
Migrated files batch 1
09462dc verified
Raw
History Blame Contribute Delete
6.67 kB
import cv2
import numpy as np
from PIL import Image
import torch
import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import pose_draw.draw_utils as util
from pose_draw.draw_3d_utils import *
from pose_draw.reshape_utils import *
from DWPoseProcess.AAUtils import read_frames_and_fps_as_np, save_videos_from_pil
from DWPoseProcess.checkUtils import *
import random
import shutil
import argparse
import yaml # Add this import
import os
from tqdm import tqdm
from multiprocessing import Pool, cpu_count
from decord import VideoReader
import copy
def draw_pose(pose, H, W, show_feet=False, show_body=True, show_hand=True, show_face=True, show_cheek=False, dw_bgr=False, dw_hand=False, aug_body_draw=False, optimized_face=False):
final_canvas = np.zeros(shape=(H, W, 3), dtype=np.uint8)
for i in range(len(pose["bodies"]["candidate"])):
canvas = np.zeros(shape=(H, W, 3), dtype=np.uint8)
bodies = pose["bodies"]
faces = pose["faces"][i:i+1]
hands = pose["hands"][2*i:2*i+2]
candidate = bodies["candidate"][i]
subset = bodies["subset"][i:i+1] # subset是认为的有效点
if show_body:
if len(subset[0]) <= 18 or show_feet == False:
if aug_body_draw:
raise NotImplementedError("aug_body_draw is not implemented yet")
else:
canvas = util.draw_bodypose(canvas, candidate, subset)
else:
canvas = util.draw_bodypose_with_feet(canvas, candidate, subset)
if dw_bgr:
canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB)
if show_cheek:
assert show_body == False, "show_cheek and show_body cannot be True at the same time"
canvas = util.draw_bodypose_augmentation(canvas, candidate, subset, drop_aug=True, shift_aug=False, all_cheek_aug=True)
if show_hand:
if not dw_hand:
canvas = util.draw_handpose_lr(canvas, hands)
else:
canvas = util.draw_handpose(canvas, hands)
if show_face:
canvas = util.draw_facepose(canvas, faces, optimized_face=optimized_face)
final_canvas = final_canvas + canvas
return final_canvas
def scale_image_hw_keep_size(img, scale_h, scale_w):
"""分别按 scale_h, scale_w 缩放图像,保持输出尺寸不变。"""
H, W = img.shape[:2]
new_H, new_W = int(H * scale_h), int(W * scale_w)
scaled = cv2.resize(img, (new_W, new_H), interpolation=cv2.INTER_LINEAR)
result = np.zeros_like(img)
# 计算在目标图上的放置范围
# --- Y方向 ---
if new_H >= H:
y_start_src = (new_H - H) // 2
y_end_src = y_start_src + H
y_start_dst = 0
y_end_dst = H
else:
y_start_src = 0
y_end_src = new_H
y_start_dst = (H - new_H) // 2
y_end_dst = y_start_dst + new_H
# --- X方向 ---
if new_W >= W:
x_start_src = (new_W - W) // 2
x_end_src = x_start_src + W
x_start_dst = 0
x_end_dst = W
else:
x_start_src = 0
x_end_src = new_W
x_start_dst = (W - new_W) // 2
x_end_dst = x_start_dst + new_W
# 将 scaled 映射到 result
result[y_start_dst:y_end_dst, x_start_dst:x_end_dst] = scaled[y_start_src:y_end_src, x_start_src:x_end_src]
return result
def draw_pose_to_canvas_np(poses, pool, H, W, reshape_scale, show_feet_flag=False, show_body_flag=True, show_hand_flag=True, show_face_flag=True, show_cheek_flag=False, dw_bgr=False, dw_hand=False, aug_body_draw=False):
canvas_np_lst = []
for pose in poses:
if reshape_scale > 0:
pool.apply_random_reshapes(pose)
canvas = draw_pose(pose, H, W, show_feet_flag, show_body_flag, show_hand_flag, show_face_flag, show_cheek_flag, dw_bgr, dw_hand, aug_body_draw, optimized_face=True)
canvas_np_lst.append(canvas)
return canvas_np_lst
def draw_pose_to_canvas(poses, pool, H, W, reshape_scale, points_only_flag, show_feet_flag, show_body_flag=True, show_hand_flag=True, show_face_flag=True, show_cheek_flag=False, dw_bgr=False, dw_hand=False, aug_body_draw=False):
canvas_lst = []
for pose in poses:
if reshape_scale > 0:
pool.apply_random_reshapes(pose)
canvas = draw_pose(pose, H, W, show_feet_flag, show_body_flag, show_hand_flag, show_face_flag, show_cheek_flag, dw_bgr, dw_hand, aug_body_draw, optimized_face=False)
canvas_img = Image.fromarray(canvas)
canvas_lst.append(canvas_img)
return canvas_lst
def get_mp4_filenames_from_directory(dwpose_keypoints_dir):
mp4_filenames_dwpose = []
# 通过keypoints和mp4的交集取所有可用的mp4
if dwpose_keypoints_dir:
for root, dirs, files in os.walk(dwpose_keypoints_dir):
for file in files:
if file.lower().endswith('.pt'): # 只查找 .mp4 文件
mp4_filenames_dwpose.append(file.replace(".pt", ".mp4")) # 获取绝对路径
return mp4_filenames_dwpose
def project_dwpose_to_3d(dwpose_keypoint, original_threed_keypoint, focal, princpt, H, W):
# 相机内参
# fx, fy = focal, focal
fx, fy = focal
cx, cy = princpt
# 2D 关键点坐标
x_2d, y_2d = dwpose_keypoint[0] * W, dwpose_keypoint[1] * H
# 原始 3D 点(相机坐标系下)
ori_x, ori_y, ori_z = original_threed_keypoint
# 使用新的 2D 点和原始深度反投影计算新的 3D 点
# 公式: x = (u - cx) * z / fx
new_x = (x_2d - cx) * ori_z / fx
new_y = (y_2d - cy) * ori_z / fy
new_z = ori_z # 保持深度不变
return [new_x, new_y, new_z]
def process_video(mp4_path, dwpose_keypoint_path, threed_keypoint_pair, reshape_scale, points_only_flag, show_feet_flag, wanted_fps=None, output_dirname=None, pose_type="dwpose"):
frames, fps = read_frames_and_fps_as_np(mp4_path)
initial_frame = frames[0]
output_path = os.path.join(output_dirname, os.path.basename(mp4_path))
os.makedirs(output_dirname, exist_ok=True)
if "3dpose" in pose_type:
raise NotImplementedError("3dpose is not implemented")
else:
poses = torch.load(dwpose_keypoint_path)
pool = reshapePool(alpha=reshape_scale)
canvas_lst = draw_pose_to_canvas(poses, pool, initial_frame.shape[0], initial_frame.shape[1], reshape_scale, points_only_flag, show_feet_flag, show_body_flag=True)
save_videos_from_pil(canvas_lst, output_path, wanted_fps)
def load_config(config_path):
with open(config_path, 'r') as f:
config = yaml.safe_load(f)
return config