Spaces:
Runtime error
Runtime error
import cv2 | |
import math | |
import numpy as np | |
from PIL import Image | |
def intrinsic_matrix_from_field_of_view(imshape, fov_degrees:float =55 ): # nlf default fov_degrees 55 | |
imshape = np.array(imshape) | |
fov_radians = fov_degrees * np.array(np.pi / 180) | |
larger_side = np.max(imshape) | |
focal_length = larger_side / (np.tan(fov_radians / 2) * 2) | |
# intrinsic_matrix 3*3 | |
return np.array([ | |
[focal_length, 0, imshape[1] / 2], | |
[0, focal_length, imshape[0] / 2], | |
[0, 0, 1], | |
]) | |
def p3d_to_p2d(point_3d, height, width): # point3d n*1024*3 | |
camera_matrix = intrinsic_matrix_from_field_of_view((height,width)) | |
camera_matrix = np.expand_dims(camera_matrix, axis=0) | |
camera_matrix = np.expand_dims(camera_matrix, axis=0) # 1*1*3*3 | |
point_3d = np.expand_dims(point_3d,axis=-1) # n*1024*3*1 | |
point_2d = (camera_matrix@point_3d).squeeze(-1) | |
point_2d[:,:,:2] = point_2d[:,:,:2]/point_2d[:,:,2:3] | |
return point_2d[:,:,:] # n*1024*2 | |
def get_pose_images(smpl_data, offset): | |
pose_images = [] | |
for data in smpl_data: | |
if isinstance(data, np.ndarray): | |
joints3d = data | |
else: | |
joints3d = data.numpy() | |
canvas = np.zeros(shape=(offset[0], offset[1], 3), dtype=np.uint8) | |
joints3d = p3d_to_p2d(joints3d, offset[0], offset[1]) | |
canvas = draw_3d_points(canvas, joints3d[0], stickwidth=int(offset[1]/350)) | |
pose_images.append(Image.fromarray(canvas)) | |
return pose_images | |
def draw_3d_points(canvas, points, stickwidth=2, r=2, draw_line=True): | |
colors = [ | |
[255, 0, 0], # 0 | |
[0, 255, 0], # 1 | |
[0, 0, 255], # 2 | |
[255, 0, 255], # 3 | |
[255, 255, 0], # 4 | |
[85, 255, 0], # 5 | |
[0, 75, 255], # 6 | |
[0, 255, 85], # 7 | |
[0, 255, 170], # 8 | |
[170, 0, 255], # 9 | |
[85, 0, 255], # 10 | |
[0, 85, 255], # 11 | |
[0, 255, 255], # 12 | |
[85, 0, 255], # 13 | |
[170, 0, 255], # 14 | |
[255, 0, 255], # 15 | |
[255, 0, 170], # 16 | |
[255, 0, 85], # 17 | |
] | |
connetions = [ | |
[15,12],[12, 16],[16, 18],[18, 20],[20, 22], | |
[12,17],[17,19],[19,21], | |
[21,23],[12,9],[9,6], | |
[6,3],[3,0],[0,1], | |
[1,4],[4,7],[7,10],[0,2],[2,5],[5,8],[8,11] | |
] | |
connection_colors = [ | |
[255, 0, 0], # 0 | |
[0, 255, 0], # 1 | |
[0, 0, 255], # 2 | |
[255, 255, 0], # 3 | |
[255, 0, 255], # 4 | |
[0, 255, 0], # 5 | |
[0, 85, 255], # 6 | |
[255, 175, 0], # 7 | |
[0, 0, 255], # 8 | |
[255, 85, 0], # 9 | |
[0, 255, 85], # 10 | |
[255, 0, 255], # 11 | |
[255, 0, 0], # 12 | |
[0, 175, 255], # 13 | |
[255, 255, 0], # 14 | |
[0, 0, 255], # 15 | |
[0, 255, 0], # 16 | |
] | |
# draw point | |
for i in range(len(points)): | |
x,y = points[i][0:2] | |
x,y = int(x),int(y) | |
if i==13 or i == 14: | |
continue | |
cv2.circle(canvas, (x, y), r, colors[i%17], thickness=-1) | |
# draw line | |
if draw_line: | |
for i in range(len(connetions)): | |
point1_idx,point2_idx = connetions[i][0:2] | |
point1 = points[point1_idx] | |
point2 = points[point2_idx] | |
Y = [point2[0],point1[0]] | |
X = [point2[1],point1[1]] | |
mX = int(np.mean(X)) | |
mY = int(np.mean(Y)) | |
length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
polygon = cv2.ellipse2Poly((mY, mX), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
cv2.fillConvexPoly(canvas, polygon, connection_colors[i%17]) | |
return canvas | |