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
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)
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 )
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
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
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)
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)
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 )
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)
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')