2121
2222#include " eos/core/Landmark.hpp"
2323#include " eos/core/LandmarkMapper.hpp"
24+ #include " eos/core/Mesh.hpp"
2425#include " eos/fitting/fitting.hpp"
25- #include " eos/fitting/orthographic_camera_estimation_linear.hpp"
2626#include " eos/fitting/contour_correspondence.hpp"
2727#include " eos/fitting/closest_edge_fitting.hpp"
2828#include " eos/fitting/RenderingParameters.hpp"
2929#include " eos/render/utils.hpp"
3030#include " eos/render/render.hpp"
3131#include " eos/render/texture_extraction.hpp"
32+ #include " eos/render/draw_utils.hpp"
33+ #include " eos/core/Image_opencv_interop.hpp"
3234
3335#include " rcr/model.hpp"
3436#include " cereal/cereal.hpp"
@@ -82,9 +84,9 @@ int main(int argc, char *argv[])
8284 " full path to OpenCV's face detector (haarcascade_frontalface_alt2.xml)" )
8385 (" landmarkdetector,l" , po::value<fs::path>(&landmarkdetector)->required ()->default_value (" ../share/face_landmarks_model_rcr_68.bin" ),
8486 " learned landmark detection model" )
85- (" mapping,p" , po::value<fs::path>(&mappingsfile)->required ()->default_value (" ../share/ibug2did .txt" ),
87+ (" mapping,p" , po::value<fs::path>(&mappingsfile)->required ()->default_value (" ../share/ibug_to_sfm .txt" ),
8688 " landmark identifier to model vertex number mapping" )
87- (" model-contour,c" , po::value<fs::path>(&contourfile)->required ()->default_value (" ../share/model_contours .json" ),
89+ (" model-contour,c" , po::value<fs::path>(&contourfile)->required ()->default_value (" ../share/sfm_model_contours .json" ),
8890 " file with model contour indices" )
8991 (" edge-topology,e" , po::value<fs::path>(&edgetopologyfile)->required ()->default_value (" ../share/sfm_3448_edge_topology.json" ),
9092 " file with model's precomputed edge topology" )
@@ -109,11 +111,11 @@ int main(int argc, char *argv[])
109111 }
110112
111113 // Load the Morphable Model and the LandmarkMapper:
112- morphablemodel::MorphableModel morphable_model = morphablemodel::load_model (modelfile.string ());
113- core::LandmarkMapper landmark_mapper = mappingsfile.empty () ? core::LandmarkMapper () : core::LandmarkMapper (mappingsfile);
114+ const morphablemodel::MorphableModel morphable_model = morphablemodel::load_model (modelfile.string ());
115+ const core::LandmarkMapper landmark_mapper = mappingsfile.empty () ? core::LandmarkMapper () : core::LandmarkMapper (mappingsfile. string () );
114116
115- fitting::ModelContour model_contour = contourfile.empty () ? fitting::ModelContour () : fitting::ModelContour::load (contourfile.string ());
116- fitting::ContourLandmarks ibug_contour = fitting::ContourLandmarks::load (mappingsfile.string ());
117+ const fitting::ModelContour model_contour = contourfile.empty () ? fitting::ModelContour () : fitting::ModelContour::load (contourfile.string ());
118+ const fitting::ContourLandmarks ibug_contour = fitting::ContourLandmarks::load (mappingsfile.string ());
117119
118120 rcr::detection_model rcr_model;
119121 // Load the landmark detection model:
@@ -145,9 +147,9 @@ int main(int argc, char *argv[])
145147 return EXIT_FAILURE;
146148 }
147149
148- vector< morphablemodel::Blendshape> blendshapes = morphablemodel::load_blendshapes (blendshapesfile.string ());
150+ const morphablemodel::Blendshapes blendshapes = morphablemodel::load_blendshapes (blendshapesfile.string ());
149151
150- morphablemodel::EdgeTopology edge_topology = morphablemodel::load_edge_topology (edgetopologyfile.string ());
152+ const morphablemodel::EdgeTopology edge_topology = morphablemodel::load_edge_topology (edgetopologyfile.string ());
151153
152154 cv::namedWindow (" video" , 1 );
153155 cv::namedWindow (" render" , 1 );
@@ -206,34 +208,37 @@ int main(int argc, char *argv[])
206208 // Fit the 3DMM:
207209 fitting::RenderingParameters rendering_params;
208210 vector<float > shape_coefficients, blendshape_coefficients;
209- vector<Vec2f > image_points;
210- render ::Mesh mesh;
211- std::tie (mesh, rendering_params) = fitting::fit_shape_and_pose (morphable_model, blendshapes, rcr_to_eos_landmark_collection (current_landmarks), landmark_mapper, unmodified_frame.cols , unmodified_frame.rows , edge_topology, ibug_contour, model_contour, 3 , 5 , 15 .0f , boost::none , shape_coefficients, blendshape_coefficients, image_points);
211+ vector<Eigen::Vector2f > image_points;
212+ core ::Mesh mesh;
213+ std::tie (mesh, rendering_params) = fitting::fit_shape_and_pose (morphable_model, blendshapes, rcr_to_eos_landmark_collection (current_landmarks), landmark_mapper, unmodified_frame.cols , unmodified_frame.rows , edge_topology, ibug_contour, model_contour, 3 , 5 , 15 .0f , cpp17:: nullopt , shape_coefficients, blendshape_coefficients, image_points);
212214
213215 // Draw the 3D pose of the face:
214216 draw_axes_topright (glm::eulerAngles (rendering_params.get_rotation ())[0 ], glm::eulerAngles (rendering_params.get_rotation ())[1 ], glm::eulerAngles (rendering_params.get_rotation ())[2 ], frame);
215217
216218 // Wireframe rendering of mesh of this frame (non-averaged):
217- draw_wireframe (frame, mesh, rendering_params.get_modelview (), rendering_params.get_projection (), fitting::get_opencv_viewport (frame.cols , frame.rows ));
219+ render:: draw_wireframe (frame, mesh, rendering_params.get_modelview (), rendering_params.get_projection (), fitting::get_opencv_viewport (frame.cols , frame.rows ));
218220
219221 // Extract the texture using the fitted mesh from this frame:
220- Mat affine_cam = fitting::get_3x4_affine_camera_matrix (rendering_params, frame.cols , frame.rows );
221- Mat isomap = render::extract_texture (mesh, affine_cam, unmodified_frame, true , render::TextureInterpolation::NearestNeighbour, 512 );
222+ const Eigen::Matrix< float , 3 , 4 > affine_cam = fitting::get_3x4_affine_camera_matrix (rendering_params, frame.cols , frame.rows );
223+ const Mat isomap = core::to_mat ( render::extract_texture (mesh, affine_cam, core::from_mat ( unmodified_frame) , true , render::TextureInterpolation::NearestNeighbour, 512 ) );
222224
223225 // Merge the isomaps - add the current one to the already merged ones:
224- Mat merged_isomap = isomap_averaging.add_and_merge (isomap);
226+ const Mat merged_isomap = isomap_averaging.add_and_merge (isomap);
225227 // Same for the shape:
226228 shape_coefficients = pca_shape_merging.add_and_merge (shape_coefficients);
227- auto merged_shape = morphable_model.get_shape_model ().draw_sample (shape_coefficients) + morphablemodel::to_matrix (blendshapes) * Mat (blendshape_coefficients);
228- render::Mesh merged_mesh = morphablemodel::sample_to_mesh (merged_shape, morphable_model.get_color_model ().get_mean (), morphable_model.get_shape_model ().get_triangle_list (), morphable_model.get_color_model ().get_triangle_list (), morphable_model.get_texture_coordinates ());
229+ const Eigen::VectorXf merged_shape =
230+ morphable_model.get_shape_model ().draw_sample (shape_coefficients) +
231+ to_matrix (blendshapes) *
232+ Eigen::Map<const Eigen::VectorXf>(blendshape_coefficients.data (), blendshape_coefficients.size ());
233+ const core::Mesh merged_mesh = morphablemodel::sample_to_mesh (merged_shape, morphable_model.get_color_model ().get_mean (), morphable_model.get_shape_model ().get_triangle_list (), morphable_model.get_color_model ().get_triangle_list (), morphable_model.get_texture_coordinates ());
229234
230235 // Render the model in a separate window using the estimated pose, shape and merged texture:
231- Mat rendering;
236+ core::Image4u rendering;
232237 auto modelview_no_translation = rendering_params.get_modelview ();
233238 modelview_no_translation[3 ][0 ] = 0 ;
234239 modelview_no_translation[3 ][1 ] = 0 ;
235240 std::tie (rendering, std::ignore) = render::render (merged_mesh, modelview_no_translation, glm::ortho (-130 .0f , 130 .0f , -130 .0f , 130 .0f ), 256 , 256 , render::create_mipmapped_texture (merged_isomap), true , false , false );
236- cv::imshow (" render" , rendering);
241+ cv::imshow (" render" , core::to_mat ( rendering) );
237242
238243 cv::imshow (" video" , frame);
239244 auto key = cv::waitKey (30 );
@@ -244,8 +249,8 @@ int main(int argc, char *argv[])
244249 }
245250 if (key == ' s' ) {
246251 // save an obj + current merged isomap to the disk:
247- render ::Mesh neutral_expression = morphablemodel::sample_to_mesh (morphable_model.get_shape_model ().draw_sample (shape_coefficients), morphable_model.get_color_model ().get_mean (), morphable_model.get_shape_model ().get_triangle_list (), morphable_model.get_color_model ().get_triangle_list (), morphable_model.get_texture_coordinates ());
248- render ::write_textured_obj (neutral_expression, " current_merged.obj" );
252+ const core ::Mesh neutral_expression = morphablemodel::sample_to_mesh (morphable_model.get_shape_model ().draw_sample (shape_coefficients), morphable_model.get_color_model ().get_mean (), morphable_model.get_shape_model ().get_triangle_list (), morphable_model.get_color_model ().get_triangle_list (), morphable_model.get_texture_coordinates ());
253+ core ::write_textured_obj (neutral_expression, " current_merged.obj" );
249254 cv::imwrite (" current_merged.isomap.png" , merged_isomap);
250255 }
251256 }
0 commit comments