Beispiel #1
0
 def _get_batch(self, N):
     beta = 4 * torch.randn(
         (N, 10)).float().cuda()  #torch.zeros((N, 10)).float().cuda()
     theta = np.ones((N, 72)) * np.expand_dims(self._sample_random_theta(),
                                               0)  #np.zeros((N, 72)) #
     theta = torch.from_numpy(theta).float().cuda()
     # Without pose but with shape for measuring
     verts, joints3d, Rs = self.smpl.forward(beta, theta, True)
     heights = measure.compute_height(verts)
     volumes = measure.compute_volume(verts, self.smpl.f)
     joints2d, camera_parameters = self.camera.forward(joints3d)
     return joints2d, verts, joints3d, camera_parameters, beta, theta, heights, volumes
Beispiel #2
0
def main(img_path, json_path=None):
    sess = tf.Session()
    model = RunModel(config, sess=sess)

    input_img, proc_param, img = preprocess_image(img_path, json_path)
    # Add batch dimension: 1 x D x D x 3
    input_img = np.expand_dims(input_img, 0)

    joints, verts, cams, joints3d, theta = model.predict(input_img,
                                                         get_theta=True)

    cams = theta[:, :model.num_cam]
    poses = theta[:, model.num_cam:(model.num_cam + model.num_theta)]
    shapes = theta[:, (model.num_cam + model.num_theta):]

    visualize(img, proc_param, joints[0], verts[0], cams[0])
    '''
    Start adjusting the shape
    '''
    shape_adjuster = torch.load("./trained/model_save1.57873062595")
    smpl = SMPL("./models/neutral_smpl_with_cocoplus_reg.pkl")

    beta = torch.from_numpy(shapes).float().cuda()
    theta = torch.zeros((1, 72)).float().cuda()
    heights = torch.from_numpy(np.asarray([1.9]))
    volume = torch.from_numpy(np.asarray([90 / 1000.]))

    verts, joints3d, Rs = smpl.forward(beta, theta, True)
    flatten_joints3d = joints3d.view(1, -1)
    heights = torch.unsqueeze(heights, -1).float().cuda()
    volumes = torch.unsqueeze(volume, -1).float().cuda()
    input_to_net = torch.cat((flatten_joints3d, heights, volumes), 1)

    adjusted_betas = shape_adjuster.forward(input_to_net)

    adjusted_verts, adjusted_joints3d, Rs = smpl.forward(
        adjusted_betas, theta, True)
    adjusted_heights = measure.compute_height(adjusted_verts)
    adjusted_volumes = measure.compute_volume(adjusted_verts, smpl.f)

    print(adjusted_heights, adjusted_volumes)

    debug_display_cloud(verts[0], joints3d[0], adjusted_verts[0],
                        adjusted_joints3d[0])
    def _get_batch(self):
        beta = 3 * torch.randn((self.batch_size, 10)).float().cuda()
        theta = torch.zeros((self.batch_size, 72)).float().cuda()

        # Without pose but with shape for measuring
        verts, joints3d, Rs = self.smpl.forward(beta, theta, True)
        heights = measure.compute_height(verts)
        volumes = measure.compute_volume(verts, self.smpl.f)

        # Must add artificial noise to the joints since joints detection algorithms are not perfect
        # -+ 2 cm
        noise = torch.normal(torch.zeros_like(joints3d), 0.04).float().cuda()
        noisy_joints3d = joints3d + noise

        # Visualize noisy joints
        #debug_display_joints(noisy_joints3d[0], joints3d[0])

        scale = torch.rand((self.batch_size, 1, 1)) * 3.75 + 0.25
        noisy_joints3d /= scale.float().cuda()

        # Must add artificial noise to the height and volume.
        # Volume must represent a weight of a person, so -+ 3 kg
        # Height is -+ 2 cm
        noise = torch.normal(torch.zeros_like(heights), 0.03).float().cuda()
        heights += noise

        noise = torch.normal(torch.zeros_like(volumes),
                             volumes / 100.0).float().cuda()
        volumes += noise

        noisy_joints3d = noisy_joints3d.view(self.batch_size, -1)
        heights = torch.unsqueeze(heights, -1)
        volumes = torch.unsqueeze(volumes, -1)

        input_to_net = torch.cat((noisy_joints3d, heights, volumes), 1)
        return input_to_net.detach(), torch.squeeze(beta).detach()
Beispiel #4
0
def predict(image, weight, height):
    global config, renderer

    config = flags.FLAGS
    config(sys.argv)
    # Using pre-trained model, change this to use your own.
    config.load_path = src.config.PRETRAINED_MODEL
    config.batch_size = 1
    renderer = vis_util.SMPLRenderer(face_path=config.smpl_face_path)

    tf.reset_default_graph()
    sess = tf.Session()
    model = RunModel(config, sess=sess)

    input_img, proc_param, img = preprocess_image_V2(image)
    # Add batch dimension: 1 x D x D x 3
    input_img = np.expand_dims(input_img, 0)

    joints, verts, cams, joints3d, theta = model.predict(input_img,
                                                         get_theta=True)
    sess.close()

    cams = theta[:, :model.num_cam]
    poses = theta[:, model.num_cam:(model.num_cam + model.num_theta)]
    shapes = theta[:, (model.num_cam + model.num_theta):]

    viz_result = visualize(img, proc_param, joints[0], verts[0], cams[0])
    '''
    Start adjusting the shape
    '''
    shape_adjuster = torch.load("./trained/model_release_1.5961363467")
    smpl = SMPL("./models/neutral_smpl_with_cocoplus_reg.pkl")

    beta = torch.from_numpy(shapes).float().cuda()
    theta = torch.zeros((1, 72)).float().cuda()
    heights = torch.from_numpy(np.asarray([height]))
    volume = torch.from_numpy(np.asarray([weight]))

    verts, joints3d, Rs = smpl.forward(beta, theta, True)
    flatten_joints3d = joints3d.view(1, -1)
    heights = torch.unsqueeze(heights, -1).float().cuda()
    volumes = torch.unsqueeze(volume, -1).float().cuda()
    input_to_net = torch.cat((flatten_joints3d, heights, volumes), 1)

    adjusted_betas = shape_adjuster.forward(input_to_net)

    adjusted_verts, adjusted_joints3d, Rs = smpl.forward(
        adjusted_betas, theta, True)
    adjusted_heights = measure.compute_height(adjusted_verts)
    adjusted_volumes = measure.compute_volume(adjusted_verts, smpl.f)

    print(adjusted_heights, adjusted_volumes)

    #  debug_display_cloud(verts[0], joints3d[0], adjusted_verts[0], adjusted_joints3d[0])

    # Change the posture for measurement
    from measurement import POSE1
    theta = torch.from_numpy(np.expand_dims(POSE1, 0)).float().cuda()
    m_adjusted_verts, adjusted_joints3d, Rs = smpl.forward(
        adjusted_betas, theta, True)
    return viz_result, \
           torch.squeeze(verts).detach().cpu().numpy(), \
           torch.squeeze(adjusted_verts).detach().cpu().numpy(), \
           torch.squeeze(m_adjusted_verts).detach().cpu().numpy(), \
           torch.squeeze(adjusted_volumes).detach().cpu().numpy(),\
           torch.squeeze(adjusted_heights).detach().cpu().numpy(),
Beispiel #5
0
    def _train(self):
        # 2) After the initialization has been done, we can start training the model
        # The training loop

        # Get the training samples
        joints2d, verts, joints3d, camera_parameters, beta, theta, heights, volumes = self._get_batch(
            self.batch_size)
        joints2d = joints2d.view((self.batch_size, -1))
        heights = torch.unsqueeze(heights, -1)
        volumes = torch.unsqueeze(volumes, -1)
        input_to_net = torch.cat((joints2d, heights, volumes), 1)
        input_to_net = torch.unsqueeze(input_to_net, -1)

        eval_loss = inf
        while eval_loss > (1.3 / 32.):
            self.net.train()

            # clean the gradients
            self.net.zero_grad()
            self.camera.zero_grad()
            self.smpl.zero_grad()

            # Prediction ===============================================================================================
            # predicted_theta, predicted_beta, predicted_camera_parameters = net.forward(joints2d)
            predicted_theta, predicted_beta = self.net.forward(input_to_net)
            verts, predicted_joints3d, Rs = self.smpl.forward(
                predicted_beta, predicted_theta, True)
            predicted_joints2d, _ = self.camera.forward(
                predicted_joints3d, camera_parameters)
            # make sure they are references to the same object
            assert (_ is camera_parameters)

            verts, _, Rs = self.smpl.forward(predicted_beta,
                                             torch.zeros_like(predicted_theta),
                                             True)
            predicted_volumes = measure.compute_height(verts)
            predicted_heights = measure.compute_volume(verts, self.smpl.f)

            beta_loss = F.mse_loss(torch.squeeze(predicted_beta),
                                   torch.squeeze(beta))
            theta_loss = F.mse_loss(torch.squeeze(predicted_theta),
                                    torch.squeeze(theta))

            total_loss = theta_loss + beta_loss
            total_loss.backward()
            self.optimizer.step()

            # Evaluation ===============================================================================================
            self.net.eval()
            predicted_theta, predicted_beta = self.net.forward(input_to_net)
            verts, predicted_joints3d, Rs = self.smpl.forward(
                predicted_beta, predicted_theta, True)
            predicted_joints2d, _ = self.camera.forward(
                predicted_joints3d, camera_parameters)

            beta_loss = F.mse_loss(torch.squeeze(predicted_beta),
                                   torch.squeeze(beta))
            theta_loss = F.mse_loss(torch.squeeze(predicted_theta),
                                    torch.squeeze(theta))
            eval_loss = (theta_loss + beta_loss) / self.batch_size

            if float(np.random.random_sample()) > 0.99:
                true_verts, true_joints3d, Rs = self.smpl.forward(
                    beta, theta, True)
                debug_display_cloud(verts[0], joints3d[0], true_verts[0],
                                    true_joints3d[0])
                debug_display_joints(predicted_joints2d[0], joints2d[0])
                print eval_loss

        return TrainingResult(timesteps_this_iter=1, mean_loss=eval_loss)