CoolFace
Apppublic

iti/HandMesh

sourceHugging Faceupdated 5y agoView on Hugging Face
0likes
draw3d.py270 linesDownload Raw Back to utils
1from __future__ import absolute_import2from __future__ import division3from __future__ import print_function4from __future__ import unicode_literals5 6import cv27import numpy as np8 9import matplotlib10 11matplotlib.use('Agg')12import matplotlib.pyplot as plt13from mpl_toolkits.mplot3d import Axes3D14import matplotlib.tri as mtri15 16color_hand_joints = [[1.0, 0.0, 0.0],17                     [0.0, 0.4, 0.0], [0.0, 0.6, 0.0], [0.0, 0.8, 0.0], [0.0, 1.0, 0.0],  # thumb18                     [0.0, 0.0, 0.6], [0.0, 0.0, 1.0], [0.2, 0.2, 1.0], [0.4, 0.4, 1.0],  # index19                     [0.0, 0.4, 0.4], [0.0, 0.6, 0.6], [0.0, 0.8, 0.8], [0.0, 1.0, 1.0],  # middle20                     [0.4, 0.4, 0.0], [0.6, 0.6, 0.0], [0.8, 0.8, 0.0], [1.0, 1.0, 0.0],  # ring21                     [0.4, 0.0, 0.4], [0.6, 0.0, 0.6], [0.8, 0.0, 0.8], [1.0, 0.0, 1.0]]  # little22 23camera_shape = [[[-0.05, 0.05, 0.05, -0.05, -0.05], [-0.05, -0.05, 0.05, 0.05, -0.05], [0, 0, 0, 0, 0]],24                [[0.05, 0], [0.05, 0], [0, -0.1]],25                [[0.05, 0], [-0.05, 0], [0, -0.1]],26                [[-0.05, 0], [-0.05, 0], [0, -0.1]],27                [[-0.05, 0], [0.05, 0], [0, -0.1]]28                ]29 30camera_color = (0, 0, 200/255)31 32 33def fig2data(fig):34    """35    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it36    @param fig a matplotlib figure37    @return a numpy 3D array of RGBA values38    """39    # draw the renderer40    fig.canvas.draw()41 42    # Get the RGBA buffer from the figure43    w, h = fig.canvas.get_width_height()44    buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)45    buf.shape = (w, h, 4)46 47    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode48    buf = np.roll(buf, 3, axis=2)49    return buf50 51 52def draw_silhouette(image, mask=None, poly=None):53    """54    :param image: H x W x 355    :param mask: H x W56    :param poly: 1 x N x 2 (np.array)57    :return:58    """59    img_mask = image.copy()60    if mask is not None:61        mask = np.concatenate([np.zeros(list(mask.shape) + [2]), mask[:, :, None]], 2).astype(np.uint8) * 25562        img_mask = cv2.addWeighted(img_mask, 1, mask, 0.5, 0)63    if poly is not None:64        cv2.polylines(img_mask, poly, isClosed=True, thickness=2, color=(0, 0, 255))65 66    return img_mask67 68 69def draw_mesh(image, cam_param, mesh_xyz, face):70    """71    :param image: H x W x 372    :param cam_param: 1 x 3 x 373    :param mesh_xyz: 778 x 374    :param face: 1538 x 3 x 275    :return:76    """77    vertex2uv = np.matmul(cam_param, mesh_xyz.T).T78    vertex2uv = (vertex2uv / vertex2uv[:, 2:3])[:, :2].astype(np.int)79 80    fig = plt.figure()81    fig.set_size_inches(float(image.shape[0]) / fig.dpi, float(image.shape[1]) / fig.dpi, forward=True)82    plt.imshow(image)83    plt.axis('off')84    if face is None:85        plt.plot(vertex2uv[:, 0], vertex2uv[:, 1], 'o', color='green', markersize=1)86    else:87        plt.triplot(vertex2uv[:, 0], vertex2uv[:, 1], face, lw=0.5, color='orange')88 89    plt.subplots_adjust(left=0., right=1., top=1., bottom=0, wspace=0, hspace=0)90 91    ret = fig2data(fig)92    plt.close(fig)93 94    return ret95 96def draw_2d_skeleton(image, pose_uv):97    """98    :param image: H x W x 399    :param pose_uv: 21 x 2100    wrist,101    thumb_mcp, thumb_pip, thumb_dip, thumb_tip102    index_mcp, index_pip, index_dip, index_tip,103    middle_mcp, middle_pip, middle_dip, middle_tip,104    ring_mcp, ring_pip, ring_dip, ring_tip,105    little_mcp, little_pip, little_dip, little_tip106    :return:107    """108    assert pose_uv.shape[0] == 21109    skeleton_overlay = image.copy()110    marker_sz = 6111    line_wd = 3112    root_ind = 0113 114    for joint_ind in range(pose_uv.shape[0]):115        joint = pose_uv[joint_ind, 0].astype('int32'), pose_uv[joint_ind, 1].astype('int32')116        cv2.circle(117            skeleton_overlay, joint,118            radius=marker_sz, color=color_hand_joints[joint_ind] * np.array(255), thickness=-1,119            lineType=cv2.CV_AA if cv2.__version__.startswith('2') else cv2.LINE_AA)120        if joint_ind == 0:121            continue122        elif joint_ind % 4 == 1:123            root_joint = pose_uv[root_ind, 0].astype('int32'), pose_uv[root_ind, 1].astype('int32')124            cv2.line(125                skeleton_overlay, root_joint, joint,126                color=color_hand_joints[joint_ind] * np.array(255), thickness=int(line_wd),127                lineType=cv2.CV_AA if cv2.__version__.startswith('2') else cv2.LINE_AA)128        else:129            joint_2 = pose_uv[joint_ind - 1, 0].astype('int32'), pose_uv[joint_ind - 1, 1].astype('int32')130            cv2.line(131                skeleton_overlay, joint_2, joint,132                color=color_hand_joints[joint_ind] * np.array(255), thickness=int(line_wd),133                lineType=cv2.CV_AA if cv2.__version__.startswith('2') else cv2.LINE_AA)134 135 136    return skeleton_overlay137 138 139def draw_3d_skeleton(pose_cam_xyz, image_size):140    """141    :param pose_cam_xyz: 21 x 3142    :param image_size: H, W143    :return:144    """145    assert pose_cam_xyz.shape[0] == 21146    fig = plt.figure()147    fig.set_size_inches(float(image_size[0]) / fig.dpi, float(image_size[1]) / fig.dpi, forward=True)148 149    ax = plt.subplot(111, projection='3d')150    marker_sz = 10151    line_wd = 2152 153    for i, shape in enumerate(camera_shape):154        ax.plot(shape[0], shape[1], shape[2], color=camera_color, linestyle=(':', '-')[i==0])155 156    for joint_ind in range(pose_cam_xyz.shape[0]):157        ax.plot(pose_cam_xyz[joint_ind:joint_ind + 1, 0], pose_cam_xyz[joint_ind:joint_ind + 1, 1],158                pose_cam_xyz[joint_ind:joint_ind + 1, 2], '.', c=color_hand_joints[joint_ind], markersize=marker_sz)159        if joint_ind == 0:160            continue161        elif joint_ind % 4 == 1:162            ax.plot(pose_cam_xyz[[0, joint_ind], 0], pose_cam_xyz[[0, joint_ind], 1], pose_cam_xyz[[0, joint_ind], 2],163                    color=color_hand_joints[joint_ind], linewidth=line_wd)164        else:165            ax.plot(pose_cam_xyz[[joint_ind - 1, joint_ind], 0], pose_cam_xyz[[joint_ind - 1, joint_ind], 1],166                    pose_cam_xyz[[joint_ind - 1, joint_ind], 2], color=color_hand_joints[joint_ind],167                    linewidth=line_wd)168 169    ax.axis('auto')170    x_lim = [-0.1, 0.1, 0.02]171    y_lim = [-0.1, 0.12, 0.02]172    z_lim = [0.0, 0.8, 0.1]173    x_ticks = np.arange(x_lim[0], x_lim[1], step=x_lim[2])174    y_ticks = np.arange(y_lim[0], y_lim[1], step=y_lim[2])175    z_ticks = np.arange(z_lim[0], z_lim[1], step=z_lim[2])176    plt.xticks(x_ticks, [x_lim[0], '', '', '', '', 0, '', '', '', x_lim[1]], fontsize=14)177    plt.yticks(y_ticks, [y_lim[0], '', '', '', '', 0, '', '', '', -y_lim[0], ''], fontsize=14)178    ax.set_zticks(z_ticks)179    z_ticks = [''] * (z_ticks.shape[0])180    z_ticks[4] = 0.4181    ax.set_zticklabels(z_ticks, fontsize=14)182    ax.view_init(elev=140, azim=80)183    plt.subplots_adjust(left=-0.06, right=0.98, top=0.93, bottom=-0.07, wspace=0, hspace=0)184 185    ret = fig2data(fig)186    plt.close(fig)187    return ret188 189def draw_3d_mesh(mesh_xyz, image_size, face):190    """191    :param mesh_xyz: 778 x 3192    :param image_size: H, W193    :param face: 1538 x 3194    :return:195    """196    fig = plt.figure()197    fig.set_size_inches(float(image_size[0]) / fig.dpi, float(image_size[1]) / fig.dpi, forward=True)198 199    ax = plt.subplot(111, projection='3d')200 201    for i, shape in enumerate(camera_shape):202        ax.plot(shape[0], shape[1], shape[2], color=camera_color, linestyle=(':', '-')[i==0])203 204    triang = mtri.Triangulation(mesh_xyz[:, 0], mesh_xyz[:, 1], triangles=face)205    ax.plot_trisurf(triang, mesh_xyz[:, 2], color=(145/255, 181/255, 255/255))206 207    ax.axis('auto')208    x_lim = [-0.1, 0.1, 0.02]209    y_lim = [-0.1, 0.12, 0.02]210    z_lim = [0.0, 0.8, 0.1]211    x_ticks = np.arange(x_lim[0], x_lim[1], step=x_lim[2])212    y_ticks = np.arange(y_lim[0], y_lim[1], step=y_lim[2])213    z_ticks = np.arange(z_lim[0], z_lim[1], step=z_lim[2])214    plt.xticks(x_ticks, [x_lim[0], '', '', '', '', 0, '', '', '', x_lim[1]], fontsize=14)215    plt.yticks(y_ticks, [y_lim[0], '', '', '', '', 0, '', '', '', -y_lim[0], ''], fontsize=14)216    ax.set_zticks(z_ticks)217    z_ticks = ['']*(z_ticks.shape[0])218    z_ticks[4] = 0.4219    ax.set_zticklabels(z_ticks, fontsize=14)220    ax.view_init(elev=140, azim=80)221    plt.subplots_adjust(left=-0.06, right=1, top=0.95, bottom=-0.06, wspace=0, hspace=0)222    plt.subplots_adjust(left=-0.06, right=0.98, top=0.93, bottom=-0.07, wspace=0, hspace=0)223 224 225    ret = fig2data(fig)226    plt.close(fig)227    return ret228 229def save_a_image_with_mesh_joints(image, mask, poly, cam_param, mesh_xyz, face, pose_uv, pose_xyz, file_name, padding=0, ret=False):230    """231    :param mesh_plot:232    :param image: H x W x 3 (np.array)233    :param mask: H x W (np.array)234    :param poly: 1 x N x 2 (np.array)235    :param cam_params: 3 x 3 (np.array)236    :param mesh_xyz: 778 x 3 (np.array)237    :param face: 1538 x 3 (np.array)238    :param pose_uv: 21 x 2 (np.array)239    :param pose_xyz: 21 x 3 (np.array)240    :param file_name:241    :param padding:242    :return:243    """244    if poly is not None:245        img_mask = draw_silhouette(image, mask, poly)246    else:247        img_mask = image.copy()248    rend_img_overlay = draw_mesh(image, cam_param, mesh_xyz, face)249    skeleton_overlay = draw_2d_skeleton(image, pose_uv)250    skeleton_3d = draw_3d_skeleton(pose_xyz, image.shape[:2])251    mesh_3d = draw_3d_mesh(mesh_xyz, image.shape[:2], face)252 253    img_list = [img_mask, skeleton_overlay, rend_img_overlay, mesh_3d, skeleton_3d]254    image_height = image.shape[0]255    image_width = image.shape[1]256    num_column = len(img_list)257 258    grid_image = np.zeros(((image_height + padding), num_column * (image_width + padding), 3), dtype=np.uint8)259 260    width_begin = 0261    width_end = image_width262    for show_img in img_list:263        grid_image[:, width_begin:width_end, :] = show_img[..., :3]264        width_begin += (image_width + padding)265        width_end = width_begin + image_width266    if ret:267        return grid_image268 269    cv2.imwrite(file_name, grid_image)270