add keypoint prediction model
This commit is contained in:
parent
0b98303582
commit
5268543b7a
6
app.py
6
app.py
|
@ -17,6 +17,8 @@ import openpose_gen as opg
|
|||
from comfy_socket import get_images
|
||||
from postprocessing import expo_shuffle_image_steps, expo_add_to_background_image, expo_postprocess_main
|
||||
import skeleton_lib as skel
|
||||
import predict as pred
|
||||
|
||||
sys.path.append('./')
|
||||
app = Flask(__name__)
|
||||
|
||||
|
@ -79,6 +81,10 @@ def get_predicted_coordinates(coordinates: list, width: int, height: int) -> lis
|
|||
|
||||
# when testing, can visualize with the method expo_save_bodypose in openpose_gen.py
|
||||
|
||||
predicted = pred.predict_pose_keypoints(np.array(coordinates).reshape(1, 18, 3))
|
||||
predicted[:, :, 3] = 1
|
||||
return predicted.flatten().tolist()
|
||||
|
||||
# for now, just mirror the coordinates and add some random deviation
|
||||
predicted_coordinates = mirror_coordinates(coordinates, width)
|
||||
for i in range(0, len(predicted_coordinates), 3):
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,140 @@
|
|||
# import cv2
|
||||
from glob import glob
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import os
|
||||
import torch
|
||||
|
||||
device = 'cuda' if torch.cuda.is_available() else 'cpu'
|
||||
use_amp = True
|
||||
model_path = './models/loss8.517782751325285.pt'
|
||||
|
||||
# define helper functions
|
||||
|
||||
def load_dataset_from_npy(dir_path):
|
||||
npy_files = glob(os.path.join(os.path.realpath(dir_path), '*.npy'))
|
||||
return npy_files
|
||||
|
||||
def find_bbox(keypoints):
|
||||
keypoints_copy = keypoints
|
||||
to_delete = []
|
||||
cnt = 0
|
||||
for kp in keypoints_copy:
|
||||
# print(kp.shape)x
|
||||
pos = (kp[0], kp[1])
|
||||
if (pos == (0, 0)) or (pos == (1, 0)):
|
||||
to_delete.append(cnt)
|
||||
cnt += 1
|
||||
keypoints_copy = np.delete(keypoints_copy, to_delete, 0)
|
||||
return [min(keypoints_copy[:, 0]), max(keypoints_copy[:, 0]), min(keypoints_copy[:, 1]), max(keypoints_copy[:, 1])]
|
||||
|
||||
def get_dist_grid(dist_ref, grid_dim=[30, 1], offsets=[0, 0]):
|
||||
dist_grid = torch.zeros([grid_dim[0], grid_dim[1], 2]).to(device)
|
||||
offsetX = torch.tensor([offsets[0], 0.0]).float().to(device)
|
||||
offsetY = torch.tensor([0.0, offsets[1]]).float().to(device)
|
||||
for i in range(grid_dim[0]):
|
||||
for j in range(grid_dim[1]):
|
||||
dist_grid[i, j, :] = dist_ref + \
|
||||
offsetX * (i - int((grid_dim[0]) / 2)) + \
|
||||
offsetY * (j - int((grid_dim[1]) / 2))
|
||||
|
||||
return dist_grid
|
||||
|
||||
def bbox_center(bbox):
|
||||
return ((bbox[0] + bbox[1])/2, (bbox[2] + bbox[3])/2)
|
||||
|
||||
def bbox_dists(bbox1, bbox2):
|
||||
return (np.array(bbox_center(bbox1)) - np.array(bbox_center(bbox2)))
|
||||
|
||||
def openpose17_colors():
|
||||
return ['#ff0000', '#ff5500', '#ffaa00', '#ffff00', '#aaff00', '#55ff00', '#00ff00', '#00ff55', '#00ffaa', '#00ffff', '#00aaff', '#0055ff', '#0000ff', '#5500ff', '#aa00ff', '#ff00ff', '#ff00aa', '#ff0055']
|
||||
|
||||
def keypoints25to18(keypoints):
|
||||
return np.delete(keypoints, [8, 19, 20, 21, 22, 23, 24], 0)
|
||||
|
||||
def get_keypoints_linkage():
|
||||
return np.array([[0, 1], [1, 2], [2, 3], [3, 4], [1, 5], [5, 6], [6, 7], [1, 8], [8, 9], [9, 10], [1, 11], [11, 12], [12, 13], [0, 14], [14, 16], [0, 15], [15, 17]])
|
||||
|
||||
@torch.compile
|
||||
def batch_pose_confidence_mat(batch_pose_keypoints_with_confidence):
|
||||
keypoints_conf = batch_pose_keypoints_with_confidence[:, :, 2]
|
||||
confidence_mat = torch.zeros([keypoints_conf.shape[0], get_keypoints_linkage().shape[0]]).to(device)
|
||||
|
||||
for i in range(get_keypoints_linkage().shape[0]):
|
||||
for j in range(keypoints_conf.shape[0]):
|
||||
if keypoints_conf[j, get_keypoints_linkage()[i, 0]] == 0 or keypoints_conf[j, get_keypoints_linkage()[i, 1]] == 0:
|
||||
confidence_mat[j, i] = 0
|
||||
else:
|
||||
confidence_mat[j, i] = (keypoints_conf[j, get_keypoints_linkage()[i, 0]] + keypoints_conf[j, get_keypoints_linkage()[i, 1]]) / 2
|
||||
|
||||
return confidence_mat
|
||||
|
||||
@torch.compile
|
||||
def pose_diff(output_pose_keypoints, target_pose_keypoints, confidence_mat):
|
||||
link_open = get_keypoints_linkage()[:, 0]
|
||||
link_end = get_keypoints_linkage()[:, 1]
|
||||
|
||||
p1 = (output_pose_keypoints[:, link_open, :2] - target_pose_keypoints[:, link_open, :2]).reshape(output_pose_keypoints.shape[0], get_keypoints_linkage().shape[0], 2)
|
||||
p2 = (output_pose_keypoints[:, link_end, :2] - target_pose_keypoints[:, link_end, :2]).reshape(output_pose_keypoints.shape[0], get_keypoints_linkage().shape[0], 2)
|
||||
|
||||
return torch.sum(torch.sum(torch.pow(p1, 2) + torch.pow(p2, 2), axis=2) * confidence_mat) / get_keypoints_linkage().shape[0] / output_pose_keypoints.shape[0]
|
||||
|
||||
@torch.compile
|
||||
def pose_loss(outputs, batch_target_pose_keypoints_with_confidence):
|
||||
err = pose_diff(outputs, batch_target_pose_keypoints_with_confidence, batch_pose_confidence_mat(batch_target_pose_keypoints_with_confidence))
|
||||
return torch.abs(torch.sum(err))
|
||||
|
||||
@torch.compile
|
||||
def zscore_normalization(data):
|
||||
return torch.std(data), torch.mean(data), (data - torch.mean(data)) / torch.std(data)
|
||||
|
||||
model = torch.nn.Sequential(
|
||||
torch.nn.Linear(36, 256),
|
||||
torch.nn.Tanh(),
|
||||
torch.nn.Dropout(0.1),
|
||||
torch.nn.Linear(256, 512),
|
||||
torch.nn.Tanh(),
|
||||
torch.nn.Dropout(0.1),
|
||||
torch.nn.Linear(512, 256),
|
||||
torch.nn.Tanh(),
|
||||
torch.nn.Dropout(0.1),
|
||||
torch.nn.Linear(256, 36)
|
||||
).to(device)
|
||||
|
||||
loss_fn = pose_loss #torch.nn.MSELoss()
|
||||
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
|
||||
scaler = torch.cuda.amp.GradScaler(enabled=use_amp)
|
||||
|
||||
checkpoint = torch.load(model_path)
|
||||
model.load_state_dict(checkpoint['model'])
|
||||
optimizer.load_state_dict(checkpoint['optimizer'])
|
||||
scaler.load_state_dict(checkpoint['scaler'])
|
||||
|
||||
sample_data = torch.Tensor([[[-0.9695, -1.6531, 2.2570],
|
||||
[-0.9758, -1.5557, 2.5996],
|
||||
[-1.0910, -1.5669, 2.2916],
|
||||
[-1.1820, -1.3080, 2.4095],
|
||||
[-1.0606, -1.2970, 2.6237],
|
||||
[-0.8728, -1.5446, 2.4116],
|
||||
[-0.7996, -1.2856, 2.2992],
|
||||
[-0.6417, -1.3074, 2.2848],
|
||||
[-1.1578, -1.0483, 2.3292],
|
||||
[-1.2732, -0.6165, 2.3635],
|
||||
[-1.3583, -0.2720, 2.3981],
|
||||
[-1.0120, -1.0378, 2.3269],
|
||||
[-0.8237, -0.7680, 2.5688],
|
||||
[-0.7751, -0.3148, 2.4276],
|
||||
[-0.9878, -1.7177, 2.1040],
|
||||
[-0.9453, -1.7068, 1.8512],
|
||||
[-1.0184, -1.7280, 1.7790],
|
||||
[-0.9146, -1.6959, 0.9578]]]).to(device)
|
||||
model.eval()
|
||||
|
||||
|
||||
def predict_pose_keypoints(data):
|
||||
std, mean, data = zscore_normalization(data)
|
||||
data = data[:,:,:2].reshape(1, 36).to(device)
|
||||
with torch.cuda.amp.autocast(enabled=use_amp):
|
||||
outputs = model(data)
|
||||
outputs = (outputs * std + mean).reshape(18, 2).cpu().detach().numpy()
|
||||
return outputs
|
Loading…
Reference in New Issue