def cb(_):
            debug = np.array(viz_rn.r)

            for j in f.J_proj.r:
                cv2.circle(debug, tuple(j.astype(np.int)), 3, (0, 0, 0.8), -1)
            for j in f.keypoints[:, :2]:
                cv2.circle(debug, tuple(j.astype(np.int)), 3, (0, 0.8, 0), -1)

            im.show(debug, id='pose', waittime=1)
 def cb(_):
     silh_diff = (rn.r - viz_mask + 1) / 2.
     im.show(silh_diff, waittime=1)
Exemplo n.º 3
0
def main(consensus_file, camera_file, video_file, pose_file, masks_file, out,
         model_file, resolution, num, first_frame, last_frame, display):
    # load data
    with open(model_file, 'rb') as fp:
        model_data = pkl.load(fp)

    with open(camera_file, 'rb') as fp:
        camera_data = pkl.load(fp)

    with open(consensus_file, 'rb') as fp:
        consensus_data = pkl.load(fp)

    pose_data = h5py.File(pose_file, 'r')
    poses = pose_data['pose'][first_frame:last_frame]
    trans = pose_data['trans'][first_frame:last_frame]
    masks = h5py.File(masks_file, 'r')['masks'][first_frame:last_frame]
    num_frames = masks.shape[0]
    indices_texture = np.ceil(np.arange(num) * num_frames * 1. / num).astype(
        np.int)

    vt = np.load('assets/basicModel_vt.npy')
    ft = np.load('assets/basicModel_ft.npy')

    # init
    base_smpl = Smpl(model_data)
    base_smpl.betas[:] = consensus_data['betas']
    base_smpl.v_personal[:] = consensus_data['v_personal']

    bgcolor = np.array([1., 0.2, 1.])
    iso = Isomapper(vt, ft, base_smpl.f, resolution, bgcolor=bgcolor)
    iso_vis = IsoColoredRenderer(vt, ft, base_smpl.f, resolution)
    camera = ProjectPoints(t=camera_data['camera_t'],
                           rt=camera_data['camera_rt'],
                           c=camera_data['camera_c'],
                           f=camera_data['camera_f'],
                           k=camera_data['camera_k'],
                           v=base_smpl)
    frustum = {
        'near': 0.1,
        'far': 1000.,
        'width': int(camera_data['width']),
        'height': int(camera_data['height'])
    }
    rn_vis = ColoredRenderer(f=base_smpl.f,
                             frustum=frustum,
                             camera=camera,
                             num_channels=1)

    cap = cv2.VideoCapture(video_file)
    for _ in range(first_frame):
        cap.grab()

    # get part-textures
    i = first_frame

    tex_agg = np.zeros((resolution, resolution, 25, 3))
    tex_agg[:] = np.nan
    normal_agg = np.ones((resolution, resolution, 25)) * 0.2

    vn = VertNormals(f=base_smpl.f, v=base_smpl)
    static_indices = np.indices((resolution, resolution))

    while cap.isOpened() and i < indices_texture[-1]:
        if i in indices_texture:
            log.info('Getting part texture from frame {}...'.format(i))
            _, frame = cap.read()

            mask = np.array(masks[i], dtype=np.uint8)
            pose_i = np.array(poses[i], dtype=np.float32)
            trans_i = np.array(trans[i], dtype=np.float32)

            base_smpl.pose[:] = pose_i
            base_smpl.trans[:] = trans_i

            # which faces have been seen and are projected into the silhouette?
            visibility = rn_vis.visibility_image.ravel()
            visible = np.nonzero(visibility != 4294967295)[0]

            proj = camera.r
            in_viewport = np.logical_and(
                np.logical_and(
                    np.round(camera.r[:, 0]) >= 0,
                    np.round(camera.r[:, 0]) < frustum['width']),
                np.logical_and(
                    np.round(camera.r[:, 1]) >= 0,
                    np.round(camera.r[:, 1]) < frustum['height']),
            )
            in_mask = np.zeros(camera.shape[0], dtype=np.bool)
            idx = np.round(proj[in_viewport][:, [1, 0]].T).astype(
                np.int).tolist()
            in_mask[in_viewport] = mask[idx]

            faces_in_mask = np.where(np.min(in_mask[base_smpl.f], axis=1))[0]
            visible_faces = np.intersect1d(faces_in_mask, visibility[visible])

            # get the current unwrap
            part_tex = iso.render(frame / 255., camera, visible_faces)

            # angle under which the texels have been seen
            points = np.hstack((proj, np.ones((proj.shape[0], 1))))
            points3d = camera.unproject_points(points)
            points3d /= np.linalg.norm(points3d, axis=1).reshape(-1, 1)
            alpha = np.sum(points3d * -vn.r, axis=1).reshape(-1, 1)
            alpha[alpha < 0] = 0
            iso_normals = iso_vis.render(alpha)[:, :, 0]
            iso_normals[np.all(part_tex == bgcolor, axis=2)] = 0

            # texels to consider
            part_mask = np.zeros((resolution, resolution))
            min_normal = np.min(normal_agg, axis=2)
            part_mask[iso_normals > min_normal] = 1.

            # update best seen texels
            where = np.argmax(np.atleast_3d(iso_normals) - normal_agg, axis=2)

            idx = np.dstack(
                (static_indices[0], static_indices[1], where))[part_mask == 1]
            tex_agg[list(idx[:, 0]),
                    list(idx[:, 1]),
                    list(idx[:, 2])] = part_tex[part_mask == 1]
            normal_agg[list(idx[:, 0]),
                       list(idx[:, 1]),
                       list(idx[:, 2])] = iso_normals[part_mask == 1]

            if display:
                im.show(part_tex, id='part_tex', waittime=1)

        else:
            cap.grab()

        i += 1

    # merge textures
    log.info('Computing median texture...')
    tex_median = np.nanmedian(tex_agg, axis=2)

    log.info('Inpainting unseen areas...')
    where = np.max(normal_agg, axis=2) > 0.2

    tex_mask = iso.iso_mask
    mask_final = np.float32(where)

    kernel_size = np.int(resolution * 0.02)
    kernel = np.ones((kernel_size, kernel_size), np.uint8)
    inpaint_area = cv2.dilate(tex_mask, kernel) - mask_final

    tex_final = cv2.inpaint(np.uint8(tex_median * 255),
                            np.uint8(inpaint_area * 255), 3, cv2.INPAINT_TELEA)

    cv2.imwrite(out, tex_final)
    log.info('Done.')