Ejemplo n.º 1
0
def generate_pose_data():
    # Load FLAME model (here we load the female model)
    # Make sure path is correct
    model_path = './models/female_model.pkl'
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    # Assign random pose and shape parameters
    model.pose[:] = np.random.randn(model.pose.size) * 0.0
    model.betas[:] = np.random.randn(model.betas.size) * 1.0
    # model.trans[:] = np.random.randn( model.trans.size ) * 0.01   # you may also manipulate the translation of mesh

    outmesh_dir = './output'
    safe_mkdir(outmesh_dir)

    # Save zero pose
    outmesh_path = join(outmesh_dir, 'pose_0.obj')
    write_simple_obj(mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path)

    # Write to an .obj file
    model.pose[3:6] = np.random.randn(3) * 0.3
    outmesh_path = join(outmesh_dir, 'pose_t.obj')
    write_simple_obj(mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path)
    np.savetxt('./output/pose_t.txt', model.pose.r)

    # Print message
    print 'output mesh saved to: ', outmesh_path
Ejemplo n.º 2
0
def run_fitting_demo():

    # input landmarks
    lmk_path = './data/landmark_3d.pkl'
    lmk_3d = load_binary_pickle(lmk_path)
    print "loaded 3d landmark from:", lmk_path

    # model
    model_path = './models/male_model.pkl'  # change to 'female_model.pkl' or 'generic_model.pkl', if needed
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    # landmark embedding
    lmk_emb_path = './data/lmk_embedding_intraface_to_flame.pkl'
    lmk_face_idx, lmk_b_coords = load_embedding(lmk_emb_path)
    print "loaded lmk embedding"

    # output
    output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    weights['lmk'] = 1.0
    weights['shape'] = 0.001
    weights['expr'] = 0.001
    weights['pose'] = 0.1

    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp'] = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3'] = 1e-4
    opt_options['maxiter'] = 100
    sparse_solver = lambda A, x: sp.linalg.cg(
        A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver

    # run fitting
    mesh_v, mesh_f, parms = fit_lmk3d(
        lmk_3d=lmk_3d,  # input landmark 3d
        model=model,  # model
        lmk_face_idx=lmk_face_idx,
        lmk_b_coords=lmk_b_coords,  # landmark embedding
        weights=weights,  # weights for the objectives
        shape_num=300,
        expr_num=100,
        opt_options=opt_options)  # options

    # write result
    output_path = join(output_dir, 'fit_lmk3d_result.obj')
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)
Ejemplo n.º 3
0
def run_fitting():
    # input landmarks
    lmk_path = './data/scan_lmks.npy'
    # measurement unit of landmarks ['m', 'cm', 'mm']
    unit = 'mm' 

    scale_factor = get_unit_factor('m') / get_unit_factor(unit)
    lmk_3d = scale_factor*np.load(lmk_path)
    print("loaded 3d landmark from:", lmk_path)

    # model
    model_path = './models/generic_model.pkl' # change to 'female_model.pkl' or 'male_model.pkl', if gender is known
    model = load_model(model_path)       # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print("loaded model from:", model_path)

    # landmark embedding
    lmk_emb_path = './models/flame_static_embedding.pkl' 
    lmk_face_idx, lmk_b_coords = load_embedding(lmk_emb_path)
    print("loaded lmk embedding")

    # output
    output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    # landmark term
    weights['lmk']   = 1.0   
    # shape regularizer (weight higher to regularize face shape more towards the mean)
    weights['shape'] = 0.001
    # expression regularizer (weight higher to regularize facial expression more towards the mean)
    weights['expr']  = 0.001
    # regularization of head rotation around the neck and jaw opening (weight higher for more regularization)
    weights['pose']  = 0.1
    
    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp']    = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3']     = 1e-4
    opt_options['maxiter'] = 100
    sparse_solver = lambda A, x: sp.linalg.cg(A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver

    # run fitting
    mesh_v, mesh_f, parms = fit_lmk3d( lmk_3d=lmk_3d,                                         # input landmark 3d
                                       model=model,                                           # model
                                       lmk_face_idx=lmk_face_idx, lmk_b_coords=lmk_b_coords,  # landmark embedding
                                       weights=weights,                                       # weights for the objectives
                                       shape_num=300, expr_num=100, opt_options=opt_options ) # options

    # write result
    output_path = join( output_dir, 'fit_lmk3d_result.obj' )
    write_simple_obj( mesh_v=mesh_v, mesh_f=mesh_f, filepath=output_path, verbose=False )
Ejemplo n.º 4
0
def hello_world():
    # Load FLAME model (here we load the female model)
    # Make sure path is correct
    model_path = './models/female_model.pkl'
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    # Show component number
    print "\nFLAME coefficients:"
    print "shape (identity) coefficient shape =", model.betas[
        0:300].shape  # valid shape component range in "betas": 0-299
    print "expression coefficient shape       =", model.betas[
        300:].shape  # valid expression component range in "betas": 300-399
    print "pose coefficient shape             =", model.pose.shape

    print "\nFLAME model components:"
    print "shape (identity) component shape =", model.shapedirs[:, :,
                                                                0:300].shape
    print "expression component shape       =", model.shapedirs[:, :,
                                                                300:].shape
    print "pose corrective blendshape shape =", model.posedirs.shape
    print ""

    # -----------------------------------------------------------------------------

    # Assign random pose and shape parameters
    model.pose[:] = np.random.randn(model.pose.size) * 0.05
    model.pose[3:6] = np.random.randn(3) * 0.5
    model.betas[:] = np.random.randn(model.betas.size) * 1.0
    # model.trans[:] = np.random.randn( model.trans.size ) * 0.01   # you may also manipulate the translation of mesh

    # Write to an .obj file
    outmesh_dir = './output'
    safe_mkdir(outmesh_dir)
    outmesh_path = join(outmesh_dir, 'hello_flame.obj')
    write_simple_obj(mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path)

    # Print message
    print 'output mesh saved to: ', outmesh_path
Ejemplo n.º 5
0
def generate_exp_sequence(output_dir):
    # Load FLAME model (here we load the female model)
    # Make sure path is correct
    model_path = './models/generic_model.pkl'
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    safe_mkdir(output_dir)
    safe_mkdir(output_dir + '/gtcoeff')
    safe_mkdir(output_dir + '/gtcoeff/pose_coeff')
    safe_mkdir(output_dir + '/gtcoeff/exp_coeff')

    # Assign random pose and shape parameters
    model.pose[:] = np.random.randn(model.pose.size) * 0.0
    model.betas[:] = np.random.randn(model.betas.size) * 0.0

    save_model_joints_info(model, output_dir)
    save_model_pose_bs(model, output_dir + "/pose_bs.txt")

    model.betas[0:300] = np.random.randn(300) * 0.5
    save_model_joints_info(model, output_dir + "/gtcoeff")

    # model.trans[:] = np.random.randn( model.trans.size ) * 0.01   # you may also manipulate the translation of mesh

    # Save zero pose
    outmesh_path = join(output_dir, '0000.obj')
    write_simple_obj(mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path)
    np.savetxt(output_dir + '/gtcoeff/beta.txt', model.betas.r, fmt='%.8f')
    save_model_pose_info(model, output_dir + "/gtcoeff/pose_coeff/0000.txt")
    save_model_exp_info(model, output_dir + '/gtcoeff/exp_coeff/0000.txt')

    # Write to an .obj file
    for idx in range(1, 10):
        model.pose[0:5] = np.random.randn(5) * 0.01
        model.pose[6] = abs(np.random.randn(1)) * 0.3
        model.pose[7:9] = np.random.randn(2) * 0.01
        model.trans[:] = np.random.randn(model.trans.size) * 0.01
        model.betas[300:] = np.random.randn(100) * 1
        outmesh_path = join(output_dir, '{:04d}.obj'.format(idx))
        write_simple_obj(mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path)
        save_model_pose_info(
            model, output_dir + "/gtcoeff/pose_coeff/{:04d}.txt".format(idx))
        save_model_exp_info(
            model, output_dir + "/gtcoeff/exp_coeff/{:04d}.txt".format(idx))

        # Print message
        print 'output mesh saved to: ', outmesh_path
Ejemplo n.º 6
0
def run_fitting():

    # input landmarks
    lmk_path = './data/landmark_3d.pkl'
    lmk_3d = load_binary_pickle(lmk_path)

    q1 = quaternion.from_rotation_vector([0, 0, 0])
    #   quaternion.from_euler_angles(20,0,0)
    g_r = quaternion.as_rotation_matrix(q1)
    lmk_3d = np.asmatrix((lmk_3d + [0, 0.01, -0.01])) * np.asmatrix(g_r)
    lmk_3d = np.asarray(lmk_3d)
    print "loaded 3d landmark from:", lmk_path
    fig = plt.figure(figsize=plt.figaspect(1))
    ax = plt.subplot(111, projection='3d')
    ax.scatter(lmk_3d[:, 0], lmk_3d[:, 1], lmk_3d[:, 2], c='r')
    ax.set_zlabel('Z')
    ax.set_ylabel('Y')
    ax.set_xlabel('X')
    ax.set_xlim(ax.get_xlim()[::-1])
    #    plt.show()

    # model
    model_path = './models/male_model.pkl'  # change to 'female_model.pkl' or 'generic_model.pkl', if needed
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    # landmark embedding
    lmk_emb_path = './data/lmk_embedding_intraface_to_flame.pkl'
    lmk_face_idx, lmk_b_coords = load_embedding(lmk_emb_path)

    mat_save({'lmk_face_idx': lmk_face_idx}, 'lmk_face_idx.mat')
    mat_save({'lmk_b_coord': lmk_b_coords}, 'lmk_b_coords.mat')
    print "loaded lmk embedding"

    # output
    output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    weights['lmk'] = 1.0
    weights['shape'] = 0.001
    weights['expr'] = 0.001
    weights['pose'] = 0.1

    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp'] = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3'] = 1e-4
    opt_options['maxiter'] = 100
    sparse_solver = lambda A, x: sp.linalg.cg(
        A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver

    # run fitting
    mesh_v, mesh_f, parms = fit_lmk3d(
        lmk_3d=lmk_3d,  # input landmark 3d
        model=model,  # model
        lmk_face_idx=lmk_face_idx,
        lmk_b_coords=lmk_b_coords,  # landmark embedding
        weights=weights,  # weights for the objectives
        shape_num=300,
        expr_num=100,
        opt_options=opt_options)  # options
    #    vp.trisurf(align_v, align_f, rendertype='wireframe')
    #    vp.scatter(pts=lmk_3d,alpha=1,mode='sphere',scale=0.001)
    # vp.trisurf(v_final, f_final, rendertype='wireframe', color3f=(0,0,0), alpha=0.3)
    #    vp.show()
    # write result
    output_path = join(output_dir, 'fit_lmk3d_result.obj')

    vp.trisurf(mesh_v, mesh_f, rendertype='wireframe')
    vp.scatter(pts=lmk_3d, alpha=1, mode='sphere', scale=0.001)
    # vp.trisurf(v_final, f_final, rendertype='wireframe', color3f=(0,0,0), alpha=0.3)
    vp.show()
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)
Ejemplo n.º 7
0
def run_fitting():
    # input scan
    scan_path = './data/scan.obj'
    # landmarks of the scan
    scan_lmk_path = './data/scan_lmks.npy'
    # measurement unit of landmarks ['m', 'cm', 'mm']
    scan_unit = 'm'

    scale_factor = get_unit_factor('m') / get_unit_factor(scan_unit)
    scan = Mesh(filename=scan_path)
    scan.v[:] *= scale_factor
    print("loaded scan from:", scan_path)

    lmk_3d = scale_factor * np.load(scan_lmk_path)
    print("loaded scan landmark from:", scan_lmk_path)

    # model
    model_path = './models/generic_model.pkl'  # change to 'female_model.pkl' or 'male_model.pkl', if gender is known
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print("loaded model from:", model_path)

    # landmark embedding
    lmk_emb_path = './models/flame_static_embedding.pkl'
    lmk_face_idx, lmk_b_coords = load_embedding(lmk_emb_path)
    print("loaded lmk embedding")

    # output
    output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    # scan vertex to model surface distance term
    weights['s2m'] = 2.0
    # landmark term
    weights['lmk'] = 1e-2
    # shape regularizer (weight higher to regularize face shape more towards the mean)
    weights['shape'] = 1e-4
    # expression regularizer (weight higher to regularize facial expression more towards the mean)
    weights['expr'] = 1e-4
    # regularization of head rotation around the neck and jaw opening (weight higher for more regularization)
    weights['pose'] = 1e-3
    # Parameter of the Geman-McClure robustifier (higher weight for a larger bassin of attraction which makes it less robust to outliers)
    gmo_sigma = 1e-4

    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp'] = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3'] = 1e-4
    opt_options['maxiter'] = 2000
    sparse_solver = lambda A, x: sp.linalg.cg(
        A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver

    # run fitting
    mesh_v, mesh_f, parms = fit_scan(
        scan=scan,  # input scan
        lmk_3d=lmk_3d,  # input landmark 3d
        model=model,  # model
        lmk_face_idx=lmk_face_idx,
        lmk_b_coords=lmk_b_coords,  # landmark embedding
        weights=weights,  # weights for the objectives
        gmo_sigma=gmo_sigma,  # parameter of the regularizer
        shape_num=300,
        expr_num=100,
        opt_options=opt_options)  # options

    # write result
    output_path = join(output_dir, 'fit_scan_result.obj')
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)

    print('output mesh saved to: ', output_path)
Ejemplo n.º 8
0
    print("loaded model from:", model_path)

    # Show component number
    print("\nFLAME coefficients:")
    print("shape (identity) coefficient shape =", model.betas[0:300].shape) # valid shape component range in "betas": 0-299
    print("expression coefficient shape       =", model.betas[300:].shape)  # valid expression component range in "betas": 300-399
    print("pose coefficient shape             =", model.pose.shape)

    print("\nFLAME model components:")
    print("shape (identity) component shape =", model.shapedirs[:,:,0:300].shape)
    print("expression component shape       =", model.shapedirs[:,:,300:].shape)
    print("pose corrective blendshape shape =", model.posedirs.shape)
    print("")

    # -----------------------------------------------------------------------------

    # Assign random pose and shape parameters
    model.pose[:]  = np.random.randn( model.pose.size ) * 0.05
    model.betas[:] = np.random.randn( model.betas.size ) * 1.0
    # model.trans[:] = np.random.randn( model.trans.size ) * 0.01   # you may also manipulate the translation of mesh

    # Write to an .obj file
    outmesh_dir = './output'
    safe_mkdir( outmesh_dir )
    outmesh_path = join( outmesh_dir, 'hello_flame.obj' )
    write_simple_obj( mesh_v=model.r, mesh_f=model.f, filepath=outmesh_path )

    # Print(message
    print('output mesh saved to: ', outmesh_path )

Ejemplo n.º 9
0
def run_fitting():
    # input landmarks
    '''
    lmk_path = './data/landmark_3d.pkl'
    lmk_3d = load_binary_pickle(lmk_path)

    q1 = quaternion.from_rotation_vector([0, 0, 0])
    #   quaternion.from_euler_angles(20,0,0)
    g_r = quaternion.as_rotation_matrix(q1)
    lmk_3d = np.asmatrix((lmk_3d + [0, 0.01, -0.01])) * np.asmatrix(g_r)
    lmk_3d = np.asarray(lmk_3d)
    print "loaded 3d landmark from:", lmk_path
    fig = plt.figure(figsize=plt.figaspect(1))
    ax = plt.subplot(111, projection='3d')
    ax.scatter(lmk_3d[:, 0], lmk_3d[:, 1], lmk_3d[:, 2], c='r')
    ax.set_zlabel('Z')
    ax.set_ylabel('Y')
    ax.set_xlabel('X')
    ax.set_xlim(ax.get_xlim()[::-1])
    plt.show()
    '''
    # model
    model_path = './models/generic_model.pkl'  # change to 'female_model.pkl' or 'generic_model.pkl', if needed
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path

    # landmark embedding
    lmk_emb_path = './data/lmk_embedding_intraface_to_flame.pkl'
    lmk_face_idx, lmk_b_coords = load_embedding(lmk_emb_path)
    lmk_v = igl.eigen.MatrixXd()
    lmk_f = igl.eigen.MatrixXi()
    igl.readOBJ('C:/Users/hehua2015/Pictures/niutou/seg/maya_6.obj', lmk_v,
                lmk_f)
    lmk_v = IglMatrixTonpArray(lmk_v)
    #    mat_save({'lmk_face_idx': lmk_face_idx}, 'lmk_face_idx.mat')
    #    mat_save({'lmk_b_coord': lmk_b_coords}, 'lmk_b_coords.mat')
    #    print "loaded lmk embedding"
    face_select_lmk = np.array([
        2210, 1963, 3486, 3382, 3385, 3389, 3392, 3396, 3400, 3599, 3594, 3587,
        3581, 3578, 3757, 568, 728, 3764, 3158, 335, 3705, 2178, 673, 3863, 16,
        2139, 3893, 3553, 3561, 3501, 3564, 2747, 2749, 3552, 1617, 1611, 2428,
        2383, 2493, 2488, 2292, 2335, 1337, 1342, 1034, 1154, 959, 880, 2712,
        2850, 2811, 3543, 1694, 1735, 1576, 1770, 1801, 3511, 2904, 2878, 2715,
        2852, 3531, 1737, 1579, 1793, 3504, 2896
    ])
    #逆时针 ,前到后
    body_select_lmk = np.array([3277, 3240, 3222, 3341])
    target_face_lmk_v = lmk_v[face_select_lmk, 0:2]
    target_body_lmk_v = lmk_v[body_select_lmk, 0:2]
    # output
    output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    weights['lmk'] = 1.0
    weights['shape'] = 0.001
    weights['expr'] = 0.001
    weights['pose'] = 0.1

    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp'] = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3'] = 1e-4
    opt_options['maxiter'] = 10
    sparse_solver = lambda A, x: sp.linalg.cg(
        A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver
    target_lmk_v = np.concatenate((target_face_lmk_v, target_body_lmk_v))

    landmark_v = igl.eigen.MatrixXd()
    landmark_f = igl.eigen.MatrixXi()
    igl.readOBJ(
        'L:/yuanqing/imgs/imgs/vrn_result/niutou/01' +
        '/01_corr_landmark_cast_sym' + '.obj', landmark_v, landmark_f)
    landmark_v = np.array(landmark_v)
    landmark_body = np.array([[586, 336, 130], [562, 369, 150],
                              [709, 295, 160], [727, 262, 150]])
    landmark_body[:, 1] = 683 - landmark_body[:, 1]
    #    landmark_body_f = np.array([[0,1,2],[0,2,3]])
    #    igl.writeOBJ('L:/yuanqing/imgs/imgs/vrn_result/niutou/01' + '/01_landmark_body_plane' + '.obj', igl.eigen.MatrixXd(landmark_body.astype('float64')),
    #                igl.eigen.MatrixXi(landmark_body_f.astype('intc')))

    target_lmk_v = np.concatenate((landmark_v[:, :], landmark_body[:, :]))

    # run fitting
    mesh_v, mesh_f, parms = fit_lmk3d(
        lmk_3d=target_lmk_v,  # input landmark 3d
        model=model,  # model
        mesh_faces=model.f,
        lmk_face_idx=lmk_face_idx,
        lmk_b_coords=lmk_b_coords,
        lmk_facevtx_idx=face_select_lmk,
        lmk_bodyvtx_idx=body_select_lmk,  # landmark embedding
        weights=weights,  # weights for the objectives
        shape_num=300,
        expr_num=100,
        opt_options=opt_options)  # options
    #    vp.trisurf(align_v, align_f, rendertype='wireframe')
    #    vp.scatter(pts=lmk_3d,alpha=1,mode='sphere',scale=0.001)
    # vp.trisurf(v_final, f_final, rendertype='wireframe', color3f=(0,0,0), alpha=0.3)
    #    vp.show()
    # write result
    output_dir = 'L:/yuanqing/imgs/imgs/vrn_result/niutou/01/'
    output_path = join(output_dir, 'fit_lmk3d_result_01.obj')
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)
    return
    vp.trisurf(mesh_v, mesh_f, rendertype='wireframe')
    vp.scatter(pts=target_lmk_v, alpha=1, mode='sphere', scale=0.001)
    # vp.trisurf(v_final, f_final, rendertype='wireframe', color3f=(0,0,0), alpha=0.3)
    vp.show()
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)
Ejemplo n.º 10
0
def run_fitting(lmk_fid_file, lmk_bary_file, lmk_3d_file, output_dir, fix_exp):
    # input landmarks#
    lmk_3d = []
    fin = open(lmk_3d_file, 'r')
    data = fin.read()
    rows = data.split('\n')
    for row in rows:
        split_row = row.split(' ')
        if len(split_row) != 3:
            continue
        for i in range(3):
            split_row[i] = float(split_row[i])
        lmk_3d.append(split_row[0:3])
    fin.close()
    #print lmk_3d
    lmk_3d = np.array(lmk_3d)

    # model
    model_path = './models/male_model.pkl'  # change to 'female_model.pkl' or 'generic_model.pkl', if needed
    model = load_model(
        model_path
    )  # the loaded model object is a 'chumpy' object, check https://github.com/mattloper/chumpy for details
    print "loaded model from:", model_path
    #print model.J
    #print model.weights

    # landmark embedding
    lmk_face_idx = []
    fin = open(lmk_fid_file, 'r')
    data = fin.read()
    rows = data.split('\n')
    for row in rows:
        if row == '':
            continue
        lmk_face_idx.append(int(row))
    fin.close()
    lmk_face_idx = np.array(lmk_face_idx)

    lmk_b_coords = []
    fin = open(lmk_bary_file, 'r')
    data = fin.read()
    rows = data.split('\n')
    for row in rows:
        split_row = row.split(' ')
        if len(split_row) != 3:
            continue
        for i in range(3):
            split_row[i] = float(split_row[i])
        lmk_b_coords.append(split_row[0:3])
    fin.close()
    lmk_b_coords = np.array(lmk_b_coords)

    # output
    #output_dir = './output'
    safe_mkdir(output_dir)

    # weights
    weights = {}
    weights['lmk'] = 1.0
    weights['shape'] = 0.001
    weights['expr'] = 0.001
    weights['pose'] = 0.1

    # optimization options
    import scipy.sparse as sp
    opt_options = {}
    opt_options['disp'] = 1
    opt_options['delta_0'] = 0.1
    opt_options['e_3'] = 1e-4
    opt_options['maxiter'] = 100
    sparse_solver = lambda A, x: sp.linalg.cg(
        A, x, maxiter=opt_options['maxiter'])[0]
    opt_options['sparse_solver'] = sparse_solver

    # run fitting
    mesh_v, mesh_f, parms = fit_lmk3d(
        lmk_3d=lmk_3d,  # input landmark 3d
        model=model,  # model
        lmk_face_idx=lmk_face_idx,
        lmk_b_coords=lmk_b_coords,  # landmark embedding
        weights=weights,  # weights for the objectives
        shape_num=300,
        expr_num=100,
        opt_options=opt_options,
        fix_exp=fix_exp)  # options

    # write result
    output_path = join(output_dir, 'fit_lmk3d_result.obj')
    write_simple_obj(mesh_v=mesh_v,
                     mesh_f=mesh_f,
                     filepath=output_path,
                     verbose=False)

    print model.J
    j_num = len(model.J)
    fout = open(output_dir + '/vector_joints.txt', 'w')
    fout.write(str(j_num) + '\n')
    for i in range(j_num):
        for p in range(0, len(model.J[i])):
            string = str(model.J[i][p])
            string = string.replace('[', '')
            string = string.replace(']', '') + ' '
            fout.write(string)
        fout.write('\n')
    fout.close()

    #print model.weights
    v_num = len(model.weights)
    fout = open(output_dir + '/vector_weights.txt', 'w')
    fout.write(str(v_num) + '\n')
    for i in range(v_num):
        fout.write(str(len(model.weights[i])) + '\n')
        for p in range(0, len(model.weights[i])):
            string = str(model.weights[i][p])
            string = string.replace('[', '')
            string = string.replace(']', '') + '\n'
            fout.write(string)
        fout.write('\n')
    fout.close()

    #save model params
    np.savetxt(output_dir + '/beta.txt', model.betas.r, fmt='%.6f')
    np.savetxt(output_dir + '/pose.txt', model.pose.r, fmt='%.6f')